parser: reimplement [flag] enum support. Add p.vcodegen too
parent
5825e467b8
commit
b0cfd3fa67
|
@ -6,7 +6,6 @@ import v.pref
|
|||
|
||||
const (
|
||||
skip_test_files = [
|
||||
'vlib/v/tests/enum_bitfield_test.v',
|
||||
'vlib/net/http/http_httpbin_test.v',
|
||||
]
|
||||
skip_on_musl = [
|
||||
|
|
|
@ -577,6 +577,7 @@ pub struct EnumDecl {
|
|||
pub:
|
||||
name string
|
||||
is_pub bool
|
||||
is_flag bool // true when the enum has [flag] tag
|
||||
fields []EnumField
|
||||
pos token.Position
|
||||
}
|
||||
|
|
|
@ -1401,7 +1401,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
|
|||
// scope := c.file.scope.innermost(array_init.pos.pos)
|
||||
// eprintln('scope: ${scope.str()}')
|
||||
// scope.find(it.name) or {
|
||||
// c.error('undefined: `$it.name`', array_init.pos)
|
||||
// c.error('undefined ident: `$it.name`', array_init.pos)
|
||||
// }
|
||||
mut full_const_name := if it.mod == 'main' { it.name } else { it.mod + '.' +
|
||||
it.name }
|
||||
|
@ -1951,7 +1951,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
|||
return table.int_type
|
||||
}
|
||||
if ident.name != '_' {
|
||||
c.error('undefined: `$ident.name`', ident.pos)
|
||||
c.error('undefined ident: `$ident.name`', ident.pos)
|
||||
}
|
||||
if c.table.known_type(ident.name) {
|
||||
// e.g. `User` in `json.decode(User, '...')`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vlib/v/checker/tests/assign_expr_undefined_err_a.v:2:7: error: undefined: `a`
|
||||
vlib/v/checker/tests/assign_expr_undefined_err_a.v:2:7: error: undefined variable: `a`
|
||||
1 | fn main() {
|
||||
2 | a := a
|
||||
| ^
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vlib/v/checker/tests/assign_expr_undefined_err_b.v:2:10: error: undefined: `a`
|
||||
vlib/v/checker/tests/assign_expr_undefined_err_b.v:2:10: error: undefined variable: `a`
|
||||
1 | fn main() {
|
||||
2 | a, b := a, b
|
||||
| ^
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vlib/v/checker/tests/assign_expr_undefined_err_c.v:2:10: error: undefined: `a`
|
||||
vlib/v/checker/tests/assign_expr_undefined_err_c.v:2:10: error: undefined variable: `a`
|
||||
1 | fn main() {
|
||||
2 | a, b := a + 1, b * 3
|
||||
| ^
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vlib/v/checker/tests/assign_expr_undefined_err_d.v:2:9: error: undefined: `s`
|
||||
vlib/v/checker/tests/assign_expr_undefined_err_d.v:2:9: error: undefined variable: `s`
|
||||
1 | fn main() {
|
||||
2 | s := '$s'
|
||||
| ^
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vlib/v/checker/tests/match_undefined_cond.v:4:15: error: undefined: `Asd`
|
||||
vlib/v/checker/tests/match_undefined_cond.v:4:15: error: undefined ident: `Asd`
|
||||
2 |
|
||||
3 | fn main() {
|
||||
4 | res := match Asd {
|
||||
|
|
|
@ -14,7 +14,7 @@ fn (mut p Parser) check_undefined_variables(idents []ast.Ident, expr ast.Expr) {
|
|||
ast.Ident {
|
||||
for ident in idents {
|
||||
if ident.name == it.name {
|
||||
p.error_with_pos('undefined: `$it.name`', it.pos)
|
||||
p.error_with_pos('undefined variable: `$it.name`', it.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme
|
|||
global_scope: global_scope
|
||||
}
|
||||
// comments_mode: comments_mode
|
||||
p.init_parse_fns()
|
||||
p.read_first_token()
|
||||
for p.tok.kind == .comment {
|
||||
stmts << p.comment()
|
||||
|
@ -126,6 +127,7 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme
|
|||
// println('nr stmts = $stmts.len')
|
||||
// println(stmts[0])
|
||||
p.scope.end_pos = p.tok.pos
|
||||
//
|
||||
return ast.File{
|
||||
path: path
|
||||
mod: module_decl
|
||||
|
@ -210,7 +212,6 @@ pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, g
|
|||
pub fn (p &Parser) init_parse_fns() {
|
||||
// p.prefix_parse_fns = make(100, 100, sizeof(PrefixParseFn))
|
||||
// p.prefix_parse_fns[token.Kind.name] = parse_name
|
||||
println('')
|
||||
}
|
||||
|
||||
pub fn (mut p Parser) read_first_token() {
|
||||
|
@ -1371,17 +1372,35 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
|
|||
}
|
||||
}
|
||||
p.check(.rcbr)
|
||||
attr := p.attr
|
||||
is_flag := attr == 'flag'
|
||||
if is_flag {
|
||||
if fields.len > 32 {
|
||||
p.error('when an enum is used as bit field, it must have a max of 32 fields')
|
||||
}
|
||||
pubfn := if p.mod == 'main' { 'fn' } else { 'pub fn' }
|
||||
p.scanner.codegen('
|
||||
//
|
||||
$pubfn ( e &$name) has(flag $name) bool { return (int(*e) & (1 << int(flag))) != 0 }
|
||||
$pubfn (mut e $name) set(flag $name) { unsafe{ *e = int(*e) | (1 << int(flag)) } }
|
||||
$pubfn (mut e $name) clear(flag $name) { unsafe{ *e = int(*e) & ~(1 << int(flag)) } }
|
||||
$pubfn (mut e $name) toggle(flag $name) { unsafe{ *e = int(*e) ^ (1 << int(flag)) } }
|
||||
//
|
||||
')
|
||||
}
|
||||
p.table.register_type_symbol(table.TypeSymbol{
|
||||
kind: .enum_
|
||||
name: name
|
||||
mod: p.mod
|
||||
info: table.Enum{
|
||||
vals: vals
|
||||
is_flag: is_flag
|
||||
}
|
||||
})
|
||||
return ast.EnumDecl{
|
||||
name: name
|
||||
is_pub: is_pub
|
||||
is_flag: is_flag
|
||||
fields: fields
|
||||
pos: start_pos.extend(end_pos)
|
||||
}
|
||||
|
|
|
@ -1121,3 +1121,15 @@ pub fn (s &Scanner) error(msg string) {
|
|||
pub fn verror(s string) {
|
||||
util.verror('scanner error', s)
|
||||
}
|
||||
|
||||
pub fn (mut s Scanner) codegen(newtext string) {
|
||||
// codegen makes sense only during normal compilation
|
||||
// feeding code generated V code to vfmt or vdoc will
|
||||
// cause them to output/document ephemeral stuff.
|
||||
if s.comments_mode == .skip_comments {
|
||||
s.text += newtext
|
||||
$if debug_codegen ? {
|
||||
eprintln('scanner.codegen:\n $newtext')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -611,6 +611,7 @@ pub mut:
|
|||
pub struct Enum {
|
||||
pub:
|
||||
vals []string
|
||||
is_flag bool
|
||||
}
|
||||
|
||||
pub struct Alias {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
println(a)
|
||||
===output===
|
||||
.vrepl.v:2:9: error: undefined: `a`
|
||||
.vrepl.v:2:9: error: undefined ident: `a`
|
||||
1 |
|
||||
2 | println(a)
|
||||
| ^
|
||||
|
|
Loading…
Reference in New Issue