diff --git a/cmd/tools/gen_vc.v b/cmd/tools/gen_vc.v index f924dbd828..e76aac76ce 100644 --- a/cmd/tools/gen_vc.v +++ b/cmd/tools/gen_vc.v @@ -1,5 +1,12 @@ module main +import os +import log +import flag +import time +import vweb +import net.urllib + // This tool regenerates V's bootstrap .c files // every time the V master branch is updated. // if run with the --serve flag it will run in webhook @@ -13,12 +20,6 @@ module main // --log-file path to log file used when --log-to is 'file' // --dry-run dont push anything to remote repo // --force force update even if already up to date -import os -import log -import flag -import time -import vweb -import net.urllib // git credentials const ( diff --git a/cmd/tools/vdoc/html.v b/cmd/tools/vdoc/html.v index 47d2e1b892..2f4fd4e914 100644 --- a/cmd/tools/vdoc/html.v +++ b/cmd/tools/vdoc/html.v @@ -5,7 +5,7 @@ import net.urllib import strings import markdown import v.scanner -import v.table +import v.ast import v.token import v.doc import v.pref @@ -344,7 +344,7 @@ fn get_src_link(repo_url string, file_name string, line_nr int) string { return url.str() } -fn html_highlight(code string, tb &table.Table) string { +fn html_highlight(code string, tb &ast.Table) string { builtin := ['bool', 'string', 'i8', 'i16', 'int', 'i64', 'i128', 'byte', 'u16', 'u32', 'u64', 'u128', 'rune', 'f32', 'f64', 'int_literal', 'float_literal', 'byteptr', 'voidptr', 'any'] highlight_code := fn (tok token.Token, typ HighlightTokenTyp) string { @@ -425,7 +425,7 @@ fn html_highlight(code string, tb &table.Table) string { return buf.str() } -fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool, tb &table.Table) string { +fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool, tb &ast.Table) string { mut dnw := strings.new_builder(200) head_tag := if head { 'h1' } else { 'h2' } comments := dn.merge_comments_without_examples() diff --git a/cmd/tools/vdoc/utils.v b/cmd/tools/vdoc/utils.v index 09b87a8a07..e459ffb11e 100644 --- a/cmd/tools/vdoc/utils.v +++ b/cmd/tools/vdoc/utils.v @@ -3,7 +3,7 @@ module main import os import v.doc import term -import v.table +import v.ast import v.scanner import v.token import strings @@ -137,7 +137,7 @@ fn gen_footer_text(d &doc.Doc, include_timestamp bool) string { return '$footer_text Generated on: $time_str' } -fn color_highlight(code string, tb &table.Table) string { +fn color_highlight(code string, tb &ast.Table) string { builtin := ['bool', 'string', 'i8', 'i16', 'int', 'i64', 'i128', 'byte', 'u16', 'u32', 'u64', 'u128', 'rune', 'f32', 'f64', 'int_literal', 'float_literal', 'byteptr', 'voidptr', 'any'] highlight_code := fn (tok token.Token, typ HighlightTokenTyp) string { diff --git a/cmd/tools/vfmt.v b/cmd/tools/vfmt.v index 1403e0294c..ee05828a63 100644 --- a/cmd/tools/vfmt.v +++ b/cmd/tools/vfmt.v @@ -12,7 +12,6 @@ import v.pref import v.fmt import v.util import v.parser -import v.table import vhelp struct FormatOptions { @@ -156,7 +155,7 @@ fn (foptions &FormatOptions) format_file(file string) { if foptions.is_verbose { eprintln('vfmt2 running fmt.fmt over file: $file') } - table := table.new_table() + table := ast.new_table() // checker := checker.new_checker(table, prefs) file_ast := parser.parse_file(file, table, .parse_comments, prefs, &ast.Scope{ parent: 0 @@ -180,7 +179,7 @@ fn (foptions &FormatOptions) format_pipe() { eprintln('vfmt2 running fmt.fmt over stdin') } input_text := os.get_raw_lines_joined() - table := table.new_table() + table := ast.new_table() // checker := checker.new_checker(table, prefs) file_ast := parser.parse_text(input_text, '', table, .parse_comments, prefs, &ast.Scope{ parent: 0 diff --git a/cmd/tools/vtest-cleancode.v b/cmd/tools/vtest-cleancode.v index 4bd58eac34..49ff869e08 100644 --- a/cmd/tools/vtest-cleancode.v +++ b/cmd/tools/vtest-cleancode.v @@ -28,6 +28,7 @@ const ( 'vlib/v/tests/generics_return_generics_struct_test.v', /* generic fn param removed */ 'vlib/v/tests/interop_test.v', /* bad comment formatting */ 'vlib/v/tests/generics_test.v', /* some silent error */ + 'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */ ] vfmt_verify_list = [ 'cmd/', @@ -55,7 +56,7 @@ const ( 'vlib/v/eval/', 'vlib/v/fmt/', 'vlib/v/gen/c/', - //'vlib/v/gen/js/', + 'vlib/v/gen/js/', 'vlib/v/gen/x64/', 'vlib/v/live/', 'vlib/v/markused/', @@ -64,7 +65,6 @@ const ( 'vlib/v/pref/', 'vlib/v/preludes', 'vlib/v/scanner/', - 'vlib/v/table/', 'vlib/v/tests/', 'vlib/v/token/', 'vlib/v/util/', diff --git a/cmd/tools/vtest-parser.v b/cmd/tools/vtest-parser.v index c6c7b2b556..a85e5d2c31 100644 --- a/cmd/tools/vtest-parser.v +++ b/cmd/tools/vtest-parser.v @@ -3,7 +3,6 @@ import flag import term import time import v.parser -import v.table import v.ast import v.pref @@ -34,7 +33,7 @@ mut: cut_index int // the cut position in the source from context.path max_index int // the maximum index (equivalent to the file content length) // parser context in the worker processes: - table table.Table + table ast.Table scope ast.Scope pref &pref.Preferences period_ms int // print periodic progress @@ -48,7 +47,7 @@ fn main() { context.log('> worker ${pid:5} starts parsing at cut_index: ${context.cut_index:5} | $context.path') // A worker's process job is to try to parse a single given file in context.path. // It can crash/panic freely. - context.table = table.new_table() + context.table = ast.new_table() context.scope = &ast.Scope{ parent: 0 } diff --git a/cmd/tools/vvet/vvet.v b/cmd/tools/vvet/vvet.v index 5068e474df..7470f0bc97 100644 --- a/cmd/tools/vvet/vvet.v +++ b/cmd/tools/vvet/vvet.v @@ -7,8 +7,8 @@ import os.cmdline import v.vet import v.pref import v.parser -import v.table import v.token +import v.ast import term struct Vet { @@ -94,7 +94,7 @@ fn (mut vt Vet) vet_file(path string) { vt.file = path mut prefs := pref.new_preferences() prefs.is_vet = true - table := table.new_table() + table := ast.new_table() vt.vprintln("vetting file '$path'...") _, errors := parser.parse_vet_file(path, table, prefs) // Transfer errors from scanner and parser diff --git a/vlib/v/README.md b/vlib/v/README.md index 2787388c8f..c5360f9228 100644 --- a/vlib/v/README.md +++ b/vlib/v/README.md @@ -25,9 +25,9 @@ or `Preferences.compile_defines_all` **if any file is defined**. ## Parsing files To parse something a new template is created as the first step: ```v -import v.table +import v.ast -table := table.new_table() +table := ast.new_table() ``` a new preference is created: diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 0deba3a374..6c38c4adfc 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -4,7 +4,6 @@ module ast import v.token -import v.table import v.errors import v.pref @@ -16,7 +15,7 @@ pub type Expr = AnonFn | ArrayDecompose | ArrayInit | AsCast | Assoc | AtExpr | Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr | MapInit | MatchExpr | NodeError | None | OffsetOf | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectExpr | SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | - StringLiteral | StructInit | Type | TypeOf | UnsafeExpr + StringLiteral | StructInit | TypeNode | TypeOf | UnsafeExpr pub type Stmt = AsmStmt | AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDecl | DeferStmt | EmptyStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | @@ -27,14 +26,14 @@ pub type Stmt = AsmStmt | AssertStmt | AssignStmt | Block | BranchStmt | CompFor // the .position() token.Position methods too. pub type ScopeObject = AsmRegister | ConstField | GlobalField | Var -// TODO: replace table.Param -pub type Node = CallArg | ConstField | EnumField | Expr | Field | File | GlobalField | - IfBranch | MatchBranch | NodeError | ScopeObject | SelectBranch | Stmt | StructField | - StructInitField | table.Param +// TODO: replace Param +pub type Node = CallArg | ConstField | EmptyNode | EnumField | Expr | File | GlobalField | + IfBranch | MatchBranch | NodeError | Param | ScopeObject | SelectBranch | Stmt | StructField | + StructInitField -pub struct Type { +pub struct TypeNode { pub: - typ table.Type + typ Type pos token.Position } @@ -55,6 +54,14 @@ pub fn empty_stmt() Stmt { return EmptyStmt{} } +pub struct EmptyNode { + x int +} + +pub fn empty_node() Node { + return EmptyNode{} +} + // `{stmts}` or `unsafe {stmts}` pub struct Block { pub: @@ -72,7 +79,7 @@ pub: comments []Comment is_expr bool pub mut: - typ table.Type + typ Type } pub struct IntegerLiteral { @@ -91,7 +98,7 @@ pub struct StringLiteral { pub: val string is_raw bool - language table.Language + language Language pos token.Position } @@ -107,7 +114,7 @@ pub: fmt_poss []token.Position pos token.Position pub mut: - expr_types []table.Type + expr_types []Type fmts []byte need_fmts []bool // an explicit non-default fmt required, e.g. `x` } @@ -133,12 +140,12 @@ pub: mut_pos token.Position next_token token.Kind pub mut: - expr Expr // expr.field_name - expr_type table.Type // type of `Foo` in `Foo.bar` - typ table.Type // type of the entire thing (`Foo.bar`) - name_type table.Type // T in `T.name` or typeof in `typeof(expr).name` + expr Expr // expr.field_name + expr_type Type // type of `Foo` in `Foo.bar` + typ Type // type of the entire thing (`Foo.bar`) + name_type Type // T in `T.name` or typeof in `typeof(expr).name` scope &Scope - from_embed_type table.Type // holds the type of the embed that the method is called from + from_embed_type Type // holds the type of the embed that the method is called from } // root_ident returns the origin ident where the selector started. @@ -157,7 +164,7 @@ pub struct Module { pub: name string // encoding.base64 short_name string // base64 - attrs []table.Attr + attrs []Attr pos token.Position name_pos token.Position // `name` in import name is_skipped bool // module main can be skipped in single file programs @@ -170,20 +177,26 @@ pub: comments []Comment default_expr Expr has_default_expr bool - attrs []table.Attr - is_public bool + attrs []Attr + is_pub bool + default_val string + is_mut bool + is_global bool pub mut: - name string - typ table.Type + default_expr_typ Type + name string + typ Type } +/* pub struct Field { pub: name string pos token.Position pub mut: - typ table.Type + typ Type } +*/ // const field in const declaration group pub struct ConstField { @@ -194,8 +207,8 @@ pub: is_pub bool pos token.Position pub mut: - typ table.Type // the type of the const field, it can be any type in V - comments []Comment // comments before current const field + typ Type // the type of the const field, it can be any type in V + comments []Comment // comments before current const field } // const declaration @@ -213,7 +226,7 @@ pub struct StructDecl { pub: pos token.Position name string - gen_types []table.Type + gen_types []Type is_pub bool // _pos fields for vfmt mut_pos int // mut: @@ -221,9 +234,9 @@ pub: pub_mut_pos int // pub mut: global_pos int // __global: module_pos int // module: - language table.Language + language Language is_union bool - attrs []table.Attr + attrs []Attr end_comments []Comment embeds []Embed pub mut: @@ -232,14 +245,14 @@ pub mut: pub struct Embed { pub: - typ table.Type + typ Type pos token.Position } pub struct StructEmbedding { pub: name string - typ table.Type + typ Type pos token.Position } @@ -264,8 +277,8 @@ pub: next_comments []Comment pub mut: name string - typ table.Type - expected_type table.Type + typ Type + expected_type Type } pub struct StructInitEmbed { @@ -276,8 +289,8 @@ pub: next_comments []Comment pub mut: name string - typ table.Type - expected_type table.Type + typ Type + expected_type Type } pub struct StructInit { @@ -288,9 +301,9 @@ pub: pub mut: unresolved bool pre_comments []Comment - typ table.Type + typ Type update_expr Expr - update_expr_type table.Type + update_expr_type Type update_expr_comments []Comment has_update_expr bool fields []StructInitField @@ -323,8 +336,8 @@ pub: pub struct AnonFn { pub mut: decl FnDecl - typ table.Type // the type of anonymous fn. Both .typ and .decl.name are auto generated - has_gen bool // has been generated + typ Type // the type of anonymous fn. Both .typ and .decl.name are auto generated + has_gen bool // has been generated } // function or method declaration @@ -332,23 +345,23 @@ pub struct FnDecl { pub: name string mod string - params []table.Param + params []Param is_deprecated bool is_pub bool is_variadic bool is_anon bool - is_manualfree bool // true, when [manualfree] is used on a fn - is_main bool // true for `fn main()` - is_test bool // true for `fn test_abcde` - is_conditional bool // true for `[if abc] fn abc(){}` - receiver Field + is_manualfree bool // true, when [manualfree] is used on a fn + is_main bool // true for `fn main()` + is_test bool // true for `fn test_abcde` + is_conditional bool // true for `[if abc] fn abc(){}` + receiver StructField // TODO this is not a struct field receiver_pos token.Position // `(u User)` in `fn (u User) name()` position is_method bool method_type_pos token.Position // `User` in ` fn (u User)` position method_idx int rec_mut bool // is receiver mutable - rec_share table.ShareType - language table.Language + rec_share ShareType + language Language no_body bool // just a definition `fn C.malloc()` is_builtin bool // this function is defined in builtin/strconv pos token.Position // function declaration position @@ -356,12 +369,12 @@ pub: file string generic_params []GenericParam is_direct_arr bool // direct array access - attrs []table.Attr + attrs []Attr skip_gen bool // this function doesn't need to be generated (for example [if foo]) pub mut: stmts []Stmt defer_stmts []DeferStmt - return_type table.Type + return_type Type has_return bool comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl @@ -394,19 +407,19 @@ pub mut: is_method bool is_field bool // temp hack, remove ASAP when re-impl CallExpr / Selector (joe) args []CallArg - expected_arg_types []table.Type - language table.Language + expected_arg_types []Type + language Language or_block OrExpr - left Expr // `user` in `user.register()` - left_type table.Type // type of `user` - receiver_type table.Type // User - return_type table.Type + left Expr // `user` in `user.register()` + left_type Type // type of `user` + receiver_type Type // User + return_type Type should_be_skipped bool - generic_types []table.Type + generic_types []Type generic_list_pos token.Position free_receiver bool // true if the receiver expression needs to be freed scope &Scope - from_embed_type table.Type // holds the type of the embed that the method is called from + from_embed_type Type // holds the type of the embed that the method is called from comments []Comment } @@ -420,11 +433,11 @@ pub struct AutofreeArgVar { pub struct CallArg { pub: is_mut bool - share table.ShareType + share ShareType expr Expr comments []Comment pub mut: - typ table.Type + typ Type is_tmp_autofree bool // this tells cgen that a tmp variable has to be used for the arg expression in order to free it after the call pos token.Position // tmp_name string // for autofree @@ -437,7 +450,7 @@ pub: exprs []Expr comments []Comment pub mut: - types []table.Type + types []Type } /* @@ -457,15 +470,15 @@ pub struct Var { pub: name string expr Expr - share table.ShareType + share ShareType is_mut bool is_autofree_tmp bool is_arg bool // fn args should not be autofreed is_auto_deref bool pub mut: - typ table.Type - orig_type table.Type // original sumtype type; 0 if it's not a sumtype - sum_type_casts []table.Type // nested sum types require nested smart casting, for that a list of types is needed + typ Type + orig_type Type // original sumtype type; 0 if it's not a sumtype + sum_type_casts []Type // nested sum types require nested smart casting, for that a list of types is needed // TODO: move this to a real docs site later // 10 <- original type (orig_type) // [11, 12, 13] <- cast order (sum_type_casts) @@ -483,12 +496,12 @@ pub mut: // struct fields change type in scopes pub struct ScopeStructField { pub: - struct_type table.Type // type of struct + struct_type Type // type of struct name string pos token.Position - typ table.Type - sum_type_casts []table.Type // nested sum types require nested smart casting, for that a list of types is needed - orig_type table.Type // original sumtype type; 0 if it's not a sumtype + typ Type + sum_type_casts []Type // nested sum types require nested smart casting, for that a list of types is needed + orig_type Type // original sumtype type; 0 if it's not a sumtype // TODO: move this to a real docs site later // 10 <- original type (orig_type) // [11, 12, 13] <- cast order (sum_type_casts) @@ -502,7 +515,7 @@ pub: has_expr bool pos token.Position pub mut: - typ table.Type + typ Type comments []Comment } @@ -520,8 +533,8 @@ pub: apath string // absolute path during compilation to the resource } -// Each V source file is represented by one ast.File structure. -// When the V compiler runs, the parser will fill an []ast.File. +// Each V source file is represented by one File structure. +// When the V compiler runs, the parser will fill an []File. // That array is then passed to V's checker. pub struct File { pub: @@ -545,18 +558,18 @@ pub mut: pub struct IdentFn { pub mut: - typ table.Type + typ Type } // TODO: (joe) remove completely, use ident.obj // instead which points to the scope object pub struct IdentVar { pub mut: - typ table.Type + typ Type is_mut bool is_static bool is_optional bool - share table.ShareType + share ShareType } pub type IdentInfo = IdentFn | IdentVar @@ -573,7 +586,7 @@ pub enum IdentKind { // A single identifier pub struct Ident { pub: - language table.Language + language Language tok_kind token.Kind pos token.Position mut_pos token.Position @@ -609,8 +622,8 @@ pub: pub mut: left Expr right Expr - left_type table.Type - right_type table.Type + left_type Type + right_type Type auto_locked string or_block OrExpr } @@ -631,7 +644,7 @@ pub: op token.Kind pos token.Position pub mut: - right_type table.Type + right_type Type right Expr or_block OrExpr is_option bool // IfGuard @@ -644,7 +657,7 @@ pub: or_expr OrExpr pub mut: left Expr - left_type table.Type // array, map, fixed array + left_type Type // array, map, fixed array is_setter bool is_map bool is_array bool @@ -662,7 +675,7 @@ pub: pub mut: branches []IfBranch // includes all `else if` branches is_expr bool - typ table.Type + typ Type has_else bool } @@ -692,7 +705,7 @@ pub: pub mut: lockeds []Ident // `x`, `y` in `lock x, y {` is_expr bool - typ table.Type + typ Type } pub struct MatchExpr { @@ -704,9 +717,9 @@ pub: comments []Comment // comments before the first branch pub mut: is_expr bool // returns a value - return_type table.Type - cond_type table.Type // type of `x` in `match x {` - expected_type table.Type // for debugging only + return_type Type + cond_type Type // type of `x` in `match x {` + expected_type Type // for debugging only is_sum_type bool } @@ -728,8 +741,8 @@ pub: pos token.Position has_exception bool pub mut: - is_expr bool // returns a value - expected_type table.Type // for debugging only + is_expr bool // returns a value + expected_type Type // for debugging only } pub struct SelectBranch { @@ -757,7 +770,7 @@ pub: typ_pos token.Position pub mut: // expr Expr - typ table.Type + typ Type } pub struct ForStmt { @@ -783,11 +796,11 @@ pub: val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array // and the array cannot be indexed inside the loop pub mut: - key_type table.Type - val_type table.Type - cond_type table.Type - kind table.Kind // array/map/string - label string // `label: for {` + key_type Type + val_type Type + cond_type Type + kind Kind // array/map/string + label string // `label: for {` scope &Scope } @@ -837,8 +850,8 @@ pub: pub mut: right []Expr left []Expr - left_types []table.Type - right_types []table.Type + left_types []Type + right_types []Type is_static bool // for translated code only is_simple bool // `x+=2` in `for x:=1; ; x+=2` has_cross_var bool @@ -847,10 +860,10 @@ pub mut: pub struct AsCast { pub: expr Expr - typ table.Type + typ Type pos token.Position pub mut: - expr_type table.Type + expr_type Type } // an enum value, like OS.macos or .macos @@ -861,7 +874,7 @@ pub: mod string // for full path `mod_Enum_val` pos token.Position pub mut: - typ table.Type + typ Type } // enum field in enum declaration @@ -880,11 +893,11 @@ pub struct EnumDecl { pub: name string is_pub bool - is_flag bool // true when the enum has [flag] tag,for bit field enum - is_multi_allowed bool // true when the enum has [_allow_multiple_values] tag - comments []Comment // comments before the first EnumField - fields []EnumField // all the enum fields - attrs []table.Attr // attributes of enum declaration + is_flag bool // true when the enum has [flag] tag,for bit field enum + is_multi_allowed bool // true when the enum has [_allow_multiple_values] tag + comments []Comment // comments before the first EnumField + fields []EnumField // all the enum fields + attrs []Attr // attributes of enum declaration pos token.Position } @@ -892,7 +905,7 @@ pub struct AliasTypeDecl { pub: name string is_pub bool - parent_type table.Type + parent_type Type pos token.Position comments []Comment } @@ -904,14 +917,14 @@ pub: is_pub bool pos token.Position comments []Comment - typ table.Type + typ Type pub mut: variants []SumTypeVariant } pub struct SumTypeVariant { pub: - typ table.Type + typ Type pos token.Position } @@ -919,7 +932,7 @@ pub struct FnTypeDecl { pub: name string is_pub bool - typ table.Type + typ Type pos token.Position comments []Comment } @@ -956,7 +969,7 @@ pub: pub mut: go_stmt GoStmt mut: - return_type table.Type + return_type Type } pub struct GotoLabel { @@ -988,9 +1001,9 @@ pub: has_cap bool has_default bool pub mut: - expr_types []table.Type // [Dog, Cat] // also used for interface_types - elem_type table.Type // element type - typ table.Type // array type + expr_types []Type // [Dog, Cat] // also used for interface_types + elem_type Type // element type + typ Type // array type } pub struct ArrayDecompose { @@ -998,8 +1011,8 @@ pub: expr Expr pos token.Position pub mut: - expr_type table.Type - arg_type table.Type + expr_type Type + arg_type Type } pub struct ChanInit { @@ -1008,8 +1021,8 @@ pub: cap_expr Expr has_cap bool pub mut: - typ table.Type - elem_type table.Type + typ Type + elem_type Type } pub struct MapInit { @@ -1020,9 +1033,9 @@ pub: comments [][]Comment // comments after key-value pairs pre_cmnts []Comment // comments before the first key-value pair pub mut: - typ table.Type - key_type table.Type - value_type table.Type + typ Type + key_type Type + value_type Type } // s[10..20] @@ -1035,9 +1048,9 @@ pub: pos token.Position } -// NB: &string(x) gets parsed as ast.PrefixExpr{ right: ast.CastExpr{...} } +// NB: &string(x) gets parsed as PrefixExpr{ right: CastExpr{...} } // TODO: that is very likely a parsing bug. It should get parsed as just -// ast.CastExpr{...}, where .typname is '&string' instead. +// CastExpr{...}, where .typname is '&string' instead. // The current situation leads to special cases in vfmt and cgen // (see prefix_expr_cast_expr in fmt.v, and .is_amp in cgen.v) // .in_prexpr is also needed because of that, because the checker needs to @@ -1045,15 +1058,15 @@ pub: // `string(x,y)`, while skipping the real pointer casts like `&string(x)`. pub struct CastExpr { pub: - expr Expr // `buf` in `string(buf, n)` - arg Expr // `n` in `string(buf, n)` - typ table.Type // `string` TODO rename to `type_to_cast_to` + expr Expr // `buf` in `string(buf, n)` + arg Expr // `n` in `string(buf, n)` + typ Type // `string` TODO rename to `type_to_cast_to` pos token.Position pub mut: - typname string // TypeSymbol.name - expr_type table.Type // `byteptr` + typname string // TypeSymbol.name + expr_type Type // `byteptr` has_arg bool - in_prexpr bool // is the parent node an ast.PrefixExpr + in_prexpr bool // is the parent node an PrefixExpr } pub struct AsmStmt { @@ -1091,7 +1104,7 @@ pub struct AsmRegister { pub: name string // eax or r12d mut: - typ table.Type + typ Type size int } @@ -1143,7 +1156,7 @@ pub: constraint string // '=r' expr Expr // (a) comments []Comment // // this is a comment - typ table.Type + typ Type pos token.Position } @@ -1243,7 +1256,7 @@ pub: pos token.Position pub mut: expr Expr - expr_type table.Type + expr_type Type } pub enum OrKind { @@ -1279,7 +1292,7 @@ pub: exprs []Expr pos token.Position pub mut: - typ table.Type + typ Type scope &Scope } @@ -1289,12 +1302,12 @@ pub: expr Expr // checker uses this to set typ pos token.Position pub mut: - typ table.Type + typ Type } pub struct OffsetOf { pub: - struct_type table.Type + struct_type Type field string pos token.Position } @@ -1311,7 +1324,7 @@ pub: expr Expr pos token.Position pub mut: - expr_type table.Type + expr_type Type } pub struct DumpExpr { @@ -1319,7 +1332,7 @@ pub: expr Expr pos token.Position pub mut: - expr_type table.Type + expr_type Type cname string // filled in the checker } @@ -1336,7 +1349,7 @@ pub: vals []Expr pos token.Position pub mut: - return_type table.Type + return_type Type } // @FN, @STRUCT, @MOD etc. See full list in token.valid_at_tokens @@ -1356,8 +1369,8 @@ pub: field_expr Expr pos token.Position pub mut: - left_type table.Type - typ table.Type + left_type Type + typ Type } pub struct ComptimeCall { @@ -1379,8 +1392,8 @@ pub: is_env bool env_pos token.Position pub mut: - sym table.TypeSymbol - result_type table.Type + sym TypeSymbol + result_type Type env_value string args []CallArg } @@ -1407,14 +1420,14 @@ pub: updated_columns []string // for `update set x=y` update_exprs []Expr // for `update` pub mut: - table_expr Type - fields []table.Field + table_expr TypeNode + fields []StructField sub_structs map[int]SqlStmt } pub struct SqlExpr { pub: - typ table.Type + typ Type is_count bool db_expr Expr // `db` in `sql db {` has_where bool @@ -1429,14 +1442,14 @@ pub: limit_expr Expr pub mut: where_expr Expr - table_expr Type - fields []table.Field + table_expr TypeNode + fields []StructField sub_structs map[int]SqlExpr } pub struct NodeError { pub: - idx int // index for referencing the related ast.File error + idx int // index for referencing the related File error pos token.Position } @@ -1462,8 +1475,8 @@ pub fn (expr Expr) position() token.Position { ChanInit, CharLiteral, ConcatExpr, Comment, ComptimeCall, ComptimeSelector, EnumVal, DumpExpr, FloatLiteral, GoExpr, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit, MatchExpr, None, OffsetOf, OrExpr, ParExpr, PostfixExpr, PrefixExpr, RangeExpr, SelectExpr, - SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, Type, TypeOf, - UnsafeExpr { + SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, TypeNode, + TypeOf, UnsafeExpr { return expr.pos } IfGuardExpr { @@ -1559,10 +1572,10 @@ pub fn (stmt Stmt) check_c_expr() ? { // CTempVar is used in cgen only, to hold nodes for temporary variables pub struct CTempVar { pub: - name string // the name of the C temporary variable; used by g.expr(x) - orig Expr // the original expression, which produced the C temp variable; used by x.str() - typ table.Type // the type of the original expression - is_ptr bool // whether the type is a pointer + name string // the name of the C temporary variable; used by g.expr(x) + orig Expr // the original expression, which produced the C temp variable; used by x.str() + typ Type // the type of the original expression + is_ptr bool // whether the type is a pointer } pub fn (node Node) position() token.Position { @@ -1570,6 +1583,9 @@ pub fn (node Node) position() token.Position { NodeError { return token.Position{} } + EmptyNode { + return token.Position{} + } Stmt { mut pos := node.pos if node is Import { @@ -1585,8 +1601,7 @@ pub fn (node Node) position() token.Position { StructField { return node.pos.extend(node.type_pos) } - MatchBranch, SelectBranch, Field, EnumField, ConstField, StructInitField, GlobalField, - table.Param { + MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, Param { return node.pos } IfBranch { @@ -1760,27 +1775,6 @@ pub fn (node Node) children() []Node { return children } -// TODO: remove this fugly hack :-| -// fe2ex/1 and ex2fe/1 are used to convert back and forth from -// table.FExpr to ast.Expr , which in turn is needed to break -// a dependency cycle between v.ast and v.table, for the single -// field table.Field.default_expr, which should be ast.Expr -pub fn fe2ex(x table.FExpr) Expr { - unsafe { - res := Expr{} - C.memcpy(&res, &x, sizeof(Expr)) - return res - } -} - -pub fn ex2fe(x Expr) table.FExpr { - unsafe { - res := table.FExpr{} - C.memcpy(&res, &x, sizeof(table.FExpr)) - return res - } -} - // helper for dealing with `m[k1][k2][k3][k3] = value` pub fn (mut lx IndexExpr) recursive_mapset_is_setter(val bool) { lx.is_setter = val @@ -1792,7 +1786,7 @@ pub fn (mut lx IndexExpr) recursive_mapset_is_setter(val bool) { } // return all the registers for a give architecture -pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject { +pub fn all_registers(mut t Table, arch pref.Arch) map[string]ScopeObject { mut res := map[string]ScopeObject{} match arch { .amd64, .i386 { @@ -1809,7 +1803,7 @@ pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject { for name, max_num in array { for i in 0 .. max_num { hash_index := name.index('#') or { - panic('ast.all_registers: no hashtag found') + panic('all_registers: no hashtag found') } assembled_name := '${name[..hash_index]}$i${name[hash_index + 1..]}' res[assembled_name] = AsmRegister{ @@ -1850,7 +1844,7 @@ pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject { } } else { // TODO - panic('ast.all_registers: unhandled arch') + panic('all_registers: unhandled arch') } } @@ -1858,7 +1852,7 @@ pub fn all_registers(mut t table.Table, arch pref.Arch) map[string]ScopeObject { } // only for arm and riscv because x86 has different sized registers -fn gen_all_registers(mut t table.Table, without_numbers []string, with_numbers map[string]int, bit_size int) map[string]ScopeObject { +fn gen_all_registers(mut t Table, without_numbers []string, with_numbers map[string]int, bit_size int) map[string]ScopeObject { mut res := map[string]ScopeObject{} for name in without_numbers { res[name] = AsmRegister{ @@ -1869,7 +1863,7 @@ fn gen_all_registers(mut t table.Table, without_numbers []string, with_numbers m } for name, max_num in with_numbers { for i in 0 .. max_num { - hash_index := name.index('#') or { panic('ast.all_registers: no hashtag found') } + hash_index := name.index('#') or { panic('all_registers: no hashtag found') } assembled_name := '${name[..hash_index]}$i${name[hash_index + 1..]}' res[assembled_name] = AsmRegister{ name: assembled_name diff --git a/vlib/v/table/attr.v b/vlib/v/ast/attr.v similarity index 98% rename from vlib/v/table/attr.v rename to vlib/v/ast/attr.v index 3786f80efc..20c597a4aa 100644 --- a/vlib/v/table/attr.v +++ b/vlib/v/ast/attr.v @@ -1,7 +1,7 @@ // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. -module table +module ast import v.token diff --git a/vlib/v/table/cflags.v b/vlib/v/ast/cflags.v similarity index 86% rename from vlib/v/table/cflags.v rename to vlib/v/ast/cflags.v index 1f0535f468..77b155592d 100644 --- a/vlib/v/table/cflags.v +++ b/vlib/v/ast/cflags.v @@ -1,13 +1,13 @@ // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. -module table +module ast import v.cflag // check if cflag is in table -fn (mytable &Table) has_cflag(flag cflag.CFlag) bool { - for cf in mytable.cflags { +fn (t &Table) has_cflag(flag cflag.CFlag) bool { + for cf in t.cflags { if cf.os == flag.os && cf.name == flag.name && cf.value == flag.value { return true } @@ -15,9 +15,9 @@ fn (mytable &Table) has_cflag(flag cflag.CFlag) bool { return false } -// parse the flags to (table.cflags) []CFlag +// parse the flags to (ast.cflags) []CFlag // Note: clean up big time (joe-c) -pub fn (mut mytable Table) parse_cflag(cflg string, mod string, ctimedefines []string) ?bool { +pub fn (mut t Table) parse_cflag(cflg string, mod string, ctimedefines []string) ?bool { allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L'] flag_orig := cflg.trim_space() mut flag := flag_orig @@ -78,8 +78,8 @@ pub fn (mut mytable Table) parse_cflag(cflg string, mod string, ctimedefines []s name: name value: value } - if !mytable.has_cflag(cf) { - mytable.cflags << cf + if !t.has_cflag(cf) { + t.cflags << cf } if index == -1 { break diff --git a/vlib/v/table/cflags_test.v b/vlib/v/ast/cflags_test.v similarity index 90% rename from vlib/v/table/cflags_test.v rename to vlib/v/ast/cflags_test.v index 2ae9526ccf..a64fe8c32b 100644 --- a/vlib/v/table/cflags_test.v +++ b/vlib/v/ast/cflags_test.v @@ -1,4 +1,4 @@ -import v.table +import v.ast import v.cflag const ( @@ -10,7 +10,7 @@ const ( ) fn test_parse_valid_cflags() { - mut t := table.new_table() + mut t := ast.new_table() expected_flags := [ make_flag('freebsd', '-I', '/usr/local/include/freetype2'), make_flag('linux', '-l', 'glfw'), @@ -36,7 +36,7 @@ fn test_parse_valid_cflags() { } fn test_parse_invalid_cflags() { - mut t := table.new_table() + mut t := ast.new_table() // -I, -L, -l must have values assert_parse_invalid_flag(mut t, 'windows -l') assert_parse_invalid_flag(mut t, '-I') @@ -53,11 +53,11 @@ fn test_parse_invalid_cflags() { assert t.cflags.len == 0 } -fn parse_valid_flag(mut t table.Table, flag string) { +fn parse_valid_flag(mut t ast.Table, flag string) { t.parse_cflag(flag, module_name, cdefines) or {} } -fn assert_parse_invalid_flag(mut t table.Table, flag string) { +fn assert_parse_invalid_flag(mut t ast.Table, flag string) { t.parse_cflag(flag, module_name, cdefines) or { return } assert false } diff --git a/vlib/v/ast/init.v b/vlib/v/ast/init.v index 81ad29ad8c..0ee69ea2b9 100644 --- a/vlib/v/ast/init.v +++ b/vlib/v/ast/init.v @@ -1,11 +1,11 @@ module ast -import v.table +import v.ast -pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr { +pub fn resolve_init(node StructInit, typ Type, t &Table) Expr { type_sym := t.get_type_symbol(typ) if type_sym.kind == .array { - array_info := type_sym.info as table.Array + array_info := type_sym.info as Array mut has_len := false mut has_cap := false mut has_default := false @@ -32,7 +32,7 @@ pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr { } } } - return ArrayInit{ + return ast.ArrayInit{ // TODO: mod is not being set for now, we could need this in future // mod: mod pos: node.pos @@ -47,16 +47,16 @@ pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr { exprs: exprs } } else if type_sym.kind == .map { - map_info := type_sym.info as table.Map + map_info := type_sym.info as Map mut keys := []Expr{} mut vals := []Expr{} for field in node.fields { - keys << StringLiteral{ + keys << ast.StringLiteral{ val: field.name } vals << field.expr } - return MapInit{ + return ast.MapInit{ typ: typ key_type: map_info.key_type value_type: map_info.value_type @@ -65,7 +65,7 @@ pub fn resolve_init(node StructInit, typ table.Type, t &table.Table) Expr { } } // struct / other (sumtype?) - return StructInit{ + return ast.StructInit{ ...node unresolved: false } diff --git a/vlib/v/ast/scope.v b/vlib/v/ast/scope.v index 672b3b173a..1a9b3ba114 100644 --- a/vlib/v/ast/scope.v +++ b/vlib/v/ast/scope.v @@ -3,7 +3,7 @@ // that can be found in the LICENSE file. module ast -import v.table +import v.ast pub struct Scope { pub mut: @@ -18,7 +18,7 @@ pub mut: } pub fn new_scope(parent &Scope, start_pos int) &Scope { - return &Scope{ + return &ast.Scope{ parent: parent start_pos: start_pos } @@ -54,7 +54,7 @@ pub fn (s &Scope) find(name string) ?ScopeObject { return none } -pub fn (s &Scope) find_struct_field(struct_type table.Type, field_name string) ?ScopeStructField { +pub fn (s &Scope) find_struct_field(struct_type Type, field_name string) ?ScopeStructField { for sc := s; true; sc = sc.parent { for field in sc.struct_fields { if field.struct_type == struct_type && field.name == field_name { @@ -103,7 +103,7 @@ pub fn (s &Scope) known_var(name string) bool { return false } -pub fn (mut s Scope) update_var_type(name string, typ table.Type) { +pub fn (mut s Scope) update_var_type(name string, typ Type) { s.end_pos = s.end_pos // TODO mut bug mut obj := s.objects[name] match mut obj { diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index 06f65598b7..843d1fdcdb 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -3,7 +3,7 @@ // that can be found in the LICENSE file. module ast -import v.table +import v.ast import v.util import strings @@ -19,7 +19,7 @@ pub fn (node &FnDecl) modname() string { } // These methods are used only by vfmt, vdoc, and for debugging. -pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string, m2a map[string]string) string { +pub fn (node &FnDecl) stringify(t &Table, cur_mod string, m2a map[string]string) string { mut f := strings.new_builder(30) if node.is_pub { f.write_string('pub ') @@ -117,7 +117,7 @@ pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string, m2a map[string]s } } f.write_string(')') - if node.return_type != table.void_type { + if node.return_type != ast.void_type { mut rs := util.no_cur_mod(t.type_to_str(node.return_type), cur_mod) for mod, alias in m2a { rs = rs.replace(mod, alias) @@ -351,8 +351,8 @@ pub fn (x Expr) str() string { StringLiteral { return "'$x.val'" } - Type { - return 'Type($x.typ)' + TypeNode { + return 'TypeNode($x.typ)' } TypeOf { return 'typeof($x.expr.str())' diff --git a/vlib/v/table/table.v b/vlib/v/ast/table.v similarity index 97% rename from vlib/v/table/table.v rename to vlib/v/ast/table.v index 1d831d85a1..a21ba09d41 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/ast/table.v @@ -1,7 +1,7 @@ // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. -module table +module ast import v.cflag import v.token @@ -18,7 +18,7 @@ pub mut: cflags []cflag.CFlag redefined_fns []string fn_gen_types map[string][][]Type // for generic functions - cmod_prefix string // needed for table.type_to_str(Type) while vfmt; contains `os.` + cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.` is_fmt bool used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true; used_consts map[string]bool // filled in by the checker, when pref.skip_unused = true; @@ -82,6 +82,7 @@ fn (p []Param) equals(o []Param) bool { return true } +/* pub struct Var { pub: name string @@ -89,6 +90,7 @@ pub: mut: typ Type } +*/ pub fn new_table() &Table { mut t := &Table{ @@ -240,14 +242,14 @@ pub fn (t &Table) type_find_method(s &TypeSymbol, name string) ?Fn { return none } -fn (t &Table) register_aggregate_field(mut sym TypeSymbol, name string) ?Field { +fn (t &Table) register_aggregate_field(mut sym TypeSymbol, name string) ?StructField { if sym.kind != .aggregate { panic('Unexpected type symbol: $sym.kind') } mut agg_info := sym.info as Aggregate // an aggregate always has at least 2 types mut found_once := false - mut new_field := Field{ + mut new_field := StructField{ // default_expr: ast.empty_expr() } for typ in agg_info.types { @@ -276,7 +278,7 @@ pub fn (t &Table) struct_has_field(s &TypeSymbol, name string) bool { } // search from current type up through each parent looking for field -pub fn (t &Table) find_field(s &TypeSymbol, name string) ?Field { +pub fn (t &Table) find_field(s &TypeSymbol, name string) ?StructField { // println('find_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx') mut ts := s for { @@ -316,13 +318,13 @@ pub fn (t &Table) find_field(s &TypeSymbol, name string) ?Field { } // search for a given field, looking through embedded fields -pub fn (t &Table) find_field_with_embeds(sym &TypeSymbol, field_name string) ?Field { +pub fn (t &Table) find_field_with_embeds(sym &TypeSymbol, field_name string) ?StructField { if f := t.find_field(sym, field_name) { return f } else { // look for embedded field if sym.info is Struct { - mut found_fields := []Field{} + mut found_fields := []StructField{} mut embed_of_found_fields := []Type{} for embed in sym.info.embeds { embed_sym := t.get_type_symbol(embed) @@ -347,7 +349,7 @@ pub fn (t &Table) resolve_common_sumtype_fields(sym_ &TypeSymbol) { if info.found_fields { return } - mut field_map := map[string]Field{} + mut field_map := map[string]StructField{} mut field_usages := map[string]int{} for variant in info.variants { mut v_sym := t.get_type_symbol(variant) @@ -360,7 +362,7 @@ pub fn (t &Table) resolve_common_sumtype_fields(sym_ &TypeSymbol) { v_sym.info.fields } else { - []Field{} + []StructField{} } } for field in fields { @@ -867,8 +869,8 @@ pub fn (mut t Table) register_fn_gen_type(fn_name string, types []Type) { // TODO: there is a bug when casting sumtype the other way if its pointer // so until fixed at least show v (not C) error `x(variant) = y(SumType*)` -pub fn (mytable &Table) sumtype_has_variant(parent Type, variant Type) bool { - parent_sym := mytable.get_type_symbol(parent) +pub fn (t &Table) sumtype_has_variant(parent Type, variant Type) bool { + parent_sym := t.get_type_symbol(parent) if parent_sym.kind == .sum_type { parent_info := parent_sym.info as SumType for v in parent_info.variants { @@ -894,11 +896,11 @@ pub fn (t &Table) known_type_names() []string { // has_deep_child_no_ref returns true if type is struct and has any child or nested child with the type of the given name // the given name consists of module and name (`mod.Name`) // it doesn't care about childs that are references -pub fn (mytable &Table) has_deep_child_no_ref(ts &TypeSymbol, name string) bool { +pub fn (t &Table) has_deep_child_no_ref(ts &TypeSymbol, name string) bool { if ts.info is Struct { for field in ts.info.fields { - sym := mytable.get_type_symbol(field.typ) - if !field.typ.is_ptr() && (sym.name == name || mytable.has_deep_child_no_ref(sym, name)) { + sym := t.get_type_symbol(field.typ) + if !field.typ.is_ptr() && (sym.name == name || t.has_deep_child_no_ref(sym, name)) { return true } } diff --git a/vlib/v/table/types.v b/vlib/v/ast/types.v similarity index 93% rename from vlib/v/table/types.v rename to vlib/v/ast/types.v index ef1d182e67..0b06f78f43 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/ast/types.v @@ -9,7 +9,7 @@ // flag: (int(type)>>24) & 0xff // nr_muls: (int(type)>>16) & 0xff // idx: u16(type) & 0xffff -module table +module ast import strings import v.pref @@ -109,10 +109,10 @@ pub fn (t ShareType) str() string { pub fn (t Type) atomic_typename() string { idx := t.idx() match idx { - table.u32_type_idx { return 'atomic_uint' } - table.int_type_idx { return 'atomic_int' } - table.u64_type_idx { return 'atomic_ullong' } - table.i64_type_idx { return 'atomic_llong' } + ast.u32_type_idx { return 'atomic_uint' } + ast.int_type_idx { return 'atomic_int' } + ast.u64_type_idx { return 'atomic_ullong' } + ast.i64_type_idx { return 'atomic_llong' } else { return 'unknown_atomic' } } } @@ -133,12 +133,12 @@ pub fn (t Type) idx() int { [inline] pub fn (t Type) is_void() bool { - return t == table.void_type + return t == ast.void_type } [inline] pub fn (t Type) is_full() bool { - return t != 0 && t != table.void_type + return t != 0 && t != ast.void_type } // return nr_muls for `t` @@ -273,42 +273,42 @@ pub fn new_type_ptr(idx int, nr_muls int) Type { // built in pointers (voidptr, byteptr, charptr) [inline] pub fn (typ Type) is_pointer() bool { - return typ.idx() in table.pointer_type_idxs + return typ.idx() in ast.pointer_type_idxs } [inline] pub fn (typ Type) is_float() bool { - return typ.idx() in table.float_type_idxs + return typ.idx() in ast.float_type_idxs } [inline] pub fn (typ Type) is_int() bool { - return typ.idx() in table.integer_type_idxs + return typ.idx() in ast.integer_type_idxs } [inline] pub fn (typ Type) is_signed() bool { - return typ.idx() in table.signed_integer_type_idxs + return typ.idx() in ast.signed_integer_type_idxs } [inline] pub fn (typ Type) is_unsigned() bool { - return typ.idx() in table.unsigned_integer_type_idxs + return typ.idx() in ast.unsigned_integer_type_idxs } [inline] pub fn (typ Type) is_int_literal() bool { - return typ.idx() == table.int_literal_type_idx + return typ.idx() == ast.int_literal_type_idx } [inline] pub fn (typ Type) is_number() bool { - return typ.idx() in table.number_type_idxs + return typ.idx() in ast.number_type_idxs } [inline] pub fn (typ Type) is_string() bool { - return typ.idx() in table.string_type_idxs + return typ.idx() in ast.string_type_idxs } pub const ( @@ -408,11 +408,11 @@ pub: } // returns TypeSymbol kind only if there are no type modifiers -pub fn (table &Table) type_kind(typ Type) Kind { +pub fn (t &Table) type_kind(typ Type) Kind { if typ.nr_muls() > 0 || typ.has_flag(.optional) { return Kind.placeholder } - return table.get_type_symbol(typ).kind + return t.get_type_symbol(typ).kind } pub enum Kind { @@ -585,7 +585,7 @@ pub fn (mut t Table) register_builtin_type_symbols() { cname: '__v_thread' mod: 'builtin' info: Thread{ - return_type: table.void_type + return_type: ast.void_type } ) t.register_type_symbol(kind: .interface_, name: 'IError', cname: 'IError', mod: 'builtin') @@ -688,7 +688,7 @@ pub: attrs []Attr pub mut: embeds []Type - fields []Field + fields []StructField is_typedef bool // C. [typedef] is_union bool is_heap bool @@ -705,7 +705,7 @@ pub mut: pub struct Interface { pub mut: types []Type - fields []Field + fields []StructField methods []Fn } @@ -725,22 +725,23 @@ pub: pub struct Aggregate { mut: - fields []Field // used for faster lookup inside the module + fields []StructField // used for faster lookup inside the module pub: types []Type } // NB: FExpr here is a actually an ast.Expr . // It should always be used by casting to ast.Expr, using ast.fe2ex()/ast.ex2fe() -// That hack is needed to break an import cycle between v.ast and v.table . -pub type FExpr = byteptr | voidptr +// That hack is needed to break an import cycle between v.ast and v.ast . +// pub type FExpr = byteptr | voidptr +/* pub struct Field { pub: name string pub mut: typ Type - default_expr FExpr + default_expr Expr has_default_expr bool default_expr_typ Type default_val string @@ -749,8 +750,9 @@ pub mut: is_mut bool is_global bool } +*/ -pub fn (f &Field) equals(o &Field) bool { +pub fn (f &StructField) equals(o &StructField) bool { // TODO: f.is_mut == o.is_mut was removed here to allow read only access // to (mut/not mut), but otherwise equal fields; some other new checks are needed: // - if node is declared mut, and we mutate node.stmts, all stmts fields must be mutable @@ -793,19 +795,19 @@ pub struct SumType { pub: variants []Type pub mut: - fields []Field + fields []StructField found_fields bool } // human readable type name -pub fn (table &Table) type_to_str(t Type) string { - return table.type_to_str_using_aliases(t, map[string]string{}) +pub fn (t &Table) type_to_str(typ Type) string { + return t.type_to_str_using_aliases(typ, map[string]string{}) } // type name in code (for builtin) pub fn (mytable &Table) type_to_code(t Type) string { match t { - table.int_literal_type, table.float_literal_type { return mytable.get_type_symbol(t).kind.str() } + ast.int_literal_type, ast.float_literal_type { return mytable.get_type_symbol(t).kind.str() } else { return mytable.type_to_str_using_aliases(t, map[string]string{}) } } } @@ -824,7 +826,7 @@ pub fn (mytable &Table) type_to_str_using_aliases(t Type, import_aliases map[str res = sym.kind.str() } .array { - if t == table.array_type { + if t == ast.array_type { return 'array' } if t.has_flag(.variadic) { @@ -869,7 +871,7 @@ pub fn (mytable &Table) type_to_str_using_aliases(t Type, import_aliases map[str } } .map { - if int(t) == table.map_type_idx { + if int(t) == ast.map_type_idx { return 'map' } info := sym.info as Map @@ -969,7 +971,7 @@ pub fn (t &Table) fn_signature(func &Fn, opts FnSignatureOpts) string { sb.write_string('$styp') } sb.write_string(')') - if func.return_type != table.void_type { + if func.return_type != ast.void_type { sb.write_string(' ${t.type_to_str(func.return_type)}') } return sb.str() @@ -1014,7 +1016,7 @@ pub fn (t &TypeSymbol) str_method_info() (bool, bool, int) { return has_str_method, expects_ptr, nr_args } -pub fn (t &TypeSymbol) find_field(name string) ?Field { +pub fn (t &TypeSymbol) find_field(name string) ?StructField { match t.info { Aggregate { return t.info.find_field(name) } Struct { return t.info.find_field(name) } @@ -1024,7 +1026,7 @@ pub fn (t &TypeSymbol) find_field(name string) ?Field { } } -fn (a &Aggregate) find_field(name string) ?Field { +fn (a &Aggregate) find_field(name string) ?StructField { for field in a.fields { if field.name == name { return field @@ -1033,7 +1035,7 @@ fn (a &Aggregate) find_field(name string) ?Field { return none } -pub fn (i &Interface) find_field(name string) ?Field { +pub fn (i &Interface) find_field(name string) ?StructField { for field in i.fields { if field.name == name { return field @@ -1058,7 +1060,7 @@ pub fn (i &Interface) has_method(name string) bool { return false } -pub fn (s Struct) find_field(name string) ?Field { +pub fn (s Struct) find_field(name string) ?StructField { for field in s.fields { if field.name == name { return field @@ -1067,14 +1069,14 @@ pub fn (s Struct) find_field(name string) ?Field { return none } -pub fn (s Struct) get_field(name string) Field { +pub fn (s Struct) get_field(name string) StructField { if field := s.find_field(name) { return field } panic('unknown field `$name`') } -pub fn (s &SumType) find_field(name string) ?Field { +pub fn (s &SumType) find_field(name string) ?StructField { for field in s.fields { if field.name == name { return field diff --git a/vlib/v/ast/types_test.v b/vlib/v/ast/types_test.v new file mode 100644 index 0000000000..67e1adc911 --- /dev/null +++ b/vlib/v/ast/types_test.v @@ -0,0 +1,81 @@ +import v.ast + +fn test_idx() { + mut t := ast.new_type(ast.void_type_idx) + assert t.idx() == ast.void_type_idx + t = ast.new_type(ast.i8_type_idx) + assert t.idx() == ast.i8_type_idx +} + +fn test_muls() { + mut t := ast.new_type(ast.void_type_idx) + idx := t.idx() + assert t.nr_muls() == 0 + for i in 0 .. 32 { + t = t.set_nr_muls(i) + assert t.nr_muls() == i + } + t = t.set_nr_muls(0) + assert t.nr_muls() == 0 + assert t.is_ptr() == false + t = t.to_ptr() + assert t.nr_muls() == 1 + assert t.is_ptr() == true + t = t.to_ptr() + assert t.nr_muls() == 2 + assert t.is_ptr() == true + t = t.deref() + assert t.nr_muls() == 1 + assert t.is_ptr() == true + t = t.deref() + assert t.nr_muls() == 0 + assert t.is_ptr() == false + assert t.idx() == idx +} + +fn test_flags() { + mut t := ast.new_type(ast.void_type_idx) + idx := t.idx() + nr_muls := t.nr_muls() + t = t.set_flag(ast.TypeFlag.optional) + assert t.has_flag(ast.TypeFlag.optional) == true + assert t.has_flag(ast.TypeFlag.variadic) == false + assert t.has_flag(ast.TypeFlag.generic) == false + t = t.set_flag(ast.TypeFlag.variadic) + assert t.has_flag(ast.TypeFlag.optional) == true + assert t.has_flag(ast.TypeFlag.variadic) == true + assert t.has_flag(ast.TypeFlag.generic) == false + t = t.set_flag(ast.TypeFlag.generic) + assert t.has_flag(ast.TypeFlag.optional) == true + assert t.has_flag(ast.TypeFlag.variadic) == true + assert t.has_flag(ast.TypeFlag.generic) == true + assert t.idx() == idx + assert t.nr_muls() == nr_muls + t = t.clear_flag(ast.TypeFlag.optional) + assert t.has_flag(ast.TypeFlag.optional) == false + assert t.has_flag(ast.TypeFlag.variadic) == true + assert t.has_flag(ast.TypeFlag.generic) == true + t = t.clear_flag(ast.TypeFlag.variadic) + assert t.has_flag(ast.TypeFlag.optional) == false + assert t.has_flag(ast.TypeFlag.variadic) == false + assert t.has_flag(ast.TypeFlag.generic) == true + t = t.clear_flag(ast.TypeFlag.generic) + assert t.has_flag(ast.TypeFlag.optional) == false + assert t.has_flag(ast.TypeFlag.variadic) == false + assert t.has_flag(ast.TypeFlag.generic) == false + assert t.idx() == idx + assert t.nr_muls() == nr_muls +} + +fn test_derive() { + mut t := ast.new_type(ast.i8_type_idx) + t = t.set_flag(ast.TypeFlag.generic) + t = t.set_flag(ast.TypeFlag.variadic) + t = t.set_nr_muls(10) + mut t2 := ast.new_type(ast.i16_type_idx) + t2 = t2.derive(t) + assert t2.has_flag(ast.TypeFlag.optional) == false + assert t2.has_flag(ast.TypeFlag.variadic) == true + assert t2.has_flag(ast.TypeFlag.generic) == true + assert t2.nr_muls() == 10 +} diff --git a/vlib/v/ast/walker/walker_test.v b/vlib/v/ast/walker/walker_test.v index b7a64a37a7..7418159107 100644 --- a/vlib/v/ast/walker/walker_test.v +++ b/vlib/v/ast/walker/walker_test.v @@ -1,11 +1,10 @@ import v.ast import v.ast.walker import v.parser -import v.table import v.pref fn parse_text(text string) ast.File { - tbl := table.new_table() + tbl := ast.new_table() prefs := pref.new_preferences() scope := &ast.Scope{ parent: 0 diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 9f61a69d99..cbc37270b9 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -1,11 +1,10 @@ module builder import os -import v.ast import v.token -import v.table import v.pref import v.util +import v.ast import v.vmod import v.checker import v.parser @@ -26,14 +25,14 @@ pub mut: module_search_paths []string parsed_files []ast.File cached_msvc MsvcResult - table &table.Table + table &ast.Table ccoptions CcompilerOptions } pub fn new_builder(pref &pref.Preferences) Builder { rdir := os.real_path(pref.path) compiled_dir := if os.is_dir(rdir) { rdir } else { os.dir(rdir) } - mut table := table.new_table() + mut table := ast.new_table() table.is_fmt = false if pref.use_color == .always { util.emanager.set_support_color(true) @@ -100,7 +99,7 @@ pub fn (mut b Builder) parse_imports() { continue } import_path := b.find_module_path(mod, ast_file.path) or { - // v.parsers[i].error_with_token_index('cannot import module "$mod" (not found)', v.parsers[i].import_table.get_import_tok_idx(mod)) + // v.parsers[i].error_with_token_index('cannot import module "$mod" (not found)', v.parsers[i].import_ast.get_import_tok_idx(mod)) // break error_with_pos('cannot import module "$mod" (not found)', ast_file.path, imp.pos) @@ -108,7 +107,7 @@ pub fn (mut b Builder) parse_imports() { } v_files := b.v_files_from_dir(import_path) if v_files.len == 0 { - // v.parsers[i].error_with_token_index('cannot import module "$mod" (no .v files in "$import_path")', v.parsers[i].import_table.get_import_tok_idx(mod)) + // v.parsers[i].error_with_token_index('cannot import module "$mod" (no .v files in "$import_path")', v.parsers[i].import_ast.get_import_tok_idx(mod)) error_with_pos('cannot import module "$mod" (no .v files in "$import_path")', ast_file.path, imp.pos) } diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 198f6b4854..f7b9db84a8 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -430,8 +430,8 @@ fn (mut v Builder) setup_output_name() { v.pref.cache_manager.save('.description.txt', v.pref.path, '${v.pref.path:-30} @ $v.pref.cache_manager.vopts\n') or { panic(err) } - // println('v.table.imports:') - // println(v.table.imports) + // println('v.ast.imports:') + // println(v.ast.imports) } if os.is_dir(v.pref.out_name) { verror("'$v.pref.out_name' is a directory") @@ -913,15 +913,15 @@ fn (mut c Builder) cc_windows_cross() { println(c.pref.out_name + ' has been successfully compiled') } -fn (mut v Builder) build_thirdparty_obj_files() { - v.log('build_thirdparty_obj_files: v.table.cflags: $v.table.cflags') - for flag in v.get_os_cflags() { +fn (mut b Builder) build_thirdparty_obj_files() { + b.log('build_thirdparty_obj_files: v.ast.cflags: $b.table.cflags') + for flag in b.get_os_cflags() { if flag.value.ends_with('.o') { - rest_of_module_flags := v.get_rest_of_module_cflags(flag) - if v.pref.ccompiler == 'msvc' { - v.build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags) + rest_of_module_flags := b.get_rest_of_module_cflags(flag) + if b.pref.ccompiler == 'msvc' { + b.build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags) } else { - v.build_thirdparty_obj_file(flag.value, rest_of_module_flags) + b.build_thirdparty_obj_file(flag.value, rest_of_module_flags) } } } diff --git a/vlib/v/builder/msvc.v b/vlib/v/builder/msvc.v index 3f86446fd3..e027737bf6 100644 --- a/vlib/v/builder/msvc.v +++ b/vlib/v/builder/msvc.v @@ -260,7 +260,7 @@ pub fn (mut v Builder) cc_msvc() { println('`builtin.obj` not found') exit(1) } - for imp in v.table.imports { + for imp in v.ast.imports { if imp == 'webview' { continue } diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index f8cd2a40fe..30c66e0d83 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -3,16 +3,15 @@ // that can be found in the LICENSE file. module checker -import v.table -import v.token import v.ast +import v.token -pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.Type, language table.Language) ? { +pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language) ? { mut expected := expected_ // variadic if expected.has_flag(.variadic) { exp_type_sym := c.table.get_type_symbol(expected_) - exp_info := exp_type_sym.info as table.Array + exp_info := exp_type_sym.info as ast.Array expected = exp_info.elem_type } if language == .c { @@ -21,29 +20,29 @@ pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.T return } // mode_t - currently using u32 as mode_t for C fns - // if got.idx() in [table.int_type_idx, table.u32_type_idx] && expected.idx() in [table.int_type_idx, table.u32_type_idx] { + // if got.idx() in [ast.int_type_idx, ast.u32_type_idx] && expected.idx() in [ast.int_type_idx, ast.u32_type_idx] { // return // } // allow number to be used as size_t - if got.is_number() && expected.idx() == table.size_t_type_idx { + if got.is_number() && expected.idx() == ast.size_t_type_idx { return } // allow bool & int to be used interchangeably for C functions - if (got.idx() == table.bool_type_idx - && expected.idx() in [table.int_type_idx, table.int_literal_type_idx]) - || (expected.idx() == table.bool_type_idx - && got.idx() in [table.int_type_idx, table.int_literal_type_idx]) { + if (got.idx() == ast.bool_type_idx + && expected.idx() in [ast.int_type_idx, ast.int_literal_type_idx]) + || (expected.idx() == ast.bool_type_idx + && got.idx() in [ast.int_type_idx, ast.int_literal_type_idx]) { return } - if got.idx() == table.string_type_idx - && expected in [table.byteptr_type_idx, table.charptr_type_idx] { + if got.idx() == ast.string_type_idx + && expected in [ast.byteptr_type_idx, ast.charptr_type_idx] { return } exp_sym := c.table.get_type_symbol(expected) // unknown C types are set to int, allow int to be used for types like `&C.FILE` // eg. `C.fflush(C.stderr)` - error: cannot use `int` as `&C.FILE` in argument 1 to `C.fflush` if expected.is_ptr() && exp_sym.language == .c && exp_sym.kind == .placeholder - && got == table.int_type_idx { + && got == ast.int_type_idx { return } // return @@ -54,7 +53,7 @@ pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.T return error('cannot use `${c.table.type_to_str(got.clear_flag(.variadic))}` as `${c.table.type_to_str(expected.clear_flag(.variadic))}`') } -pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool { +pub fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool { got_, exp_ := c.table.unalias_num_type(got), c.table.unalias_num_type(expected) if got_.idx() == exp_.idx() { // this is returning true even if one type is a ptr @@ -65,11 +64,11 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool { return true } // allow pointers to be initialized with 0. TODO: use none instead - if expected.is_ptr() && got_ == table.int_literal_type { + if expected.is_ptr() && got_ == ast.int_literal_type { return true } // TODO: use sym so it can be absorbed into below [.voidptr, .any] logic - if expected.idx() == table.array_type_idx || got.idx() == table.array_type_idx { + if expected.idx() == ast.array_type_idx || got.idx() == ast.array_type_idx { return true } got_sym, exp_sym := c.table.get_type_symbol(got), c.table.get_type_symbol(expected) @@ -100,15 +99,15 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool { return c.check_matching_function_symbols(got_sym, exp_sym) } // allow using Error as a string for now (avoid a breaking change) - if got == table.error_type_idx && expected == table.string_type_idx { + if got == ast.error_type_idx && expected == ast.string_type_idx { return true } return false } -pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &table.TypeSymbol, exp_type_sym &table.TypeSymbol) bool { - got_info := got_type_sym.info as table.FnType - exp_info := exp_type_sym.info as table.FnType +pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &ast.TypeSymbol, exp_type_sym &ast.TypeSymbol) bool { + got_info := got_type_sym.info as ast.FnType + exp_info := exp_type_sym.info as ast.FnType got_fn := got_info.func exp_fn := exp_info.func // we are using check() to compare return type & args as they might include @@ -137,39 +136,39 @@ pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &table.TypeS } [inline] -fn (mut c Checker) check_shift(left_type table.Type, right_type table.Type, left_pos token.Position, right_pos token.Position) table.Type { +fn (mut c Checker) check_shift(left_type ast.Type, right_type ast.Type, left_pos token.Position, right_pos token.Position) ast.Type { if !left_type.is_int() { // maybe it's an int alias? TODO move this to is_int() ? sym := c.table.get_type_symbol(left_type) - if sym.kind == .alias && (sym.info as table.Alias).parent_type.is_int() { + if sym.kind == .alias && (sym.info as ast.Alias).parent_type.is_int() { return left_type } - if c.pref.translated && left_type == table.bool_type { + if c.pref.translated && left_type == ast.bool_type { // allow `bool << 2` in translated C code - return table.int_type + return ast.int_type } c.error('invalid operation: shift on type `$sym.name`', left_pos) - return table.void_type + return ast.void_type } else if !right_type.is_int() { c.error('cannot shift non-integer type `${c.table.get_type_symbol(right_type).name}` into type `${c.table.get_type_symbol(left_type).name}`', right_pos) - return table.void_type + return ast.void_type } return left_type } -pub fn (c &Checker) promote(left_type table.Type, right_type table.Type) table.Type { +pub fn (c &Checker) promote(left_type ast.Type, right_type ast.Type) ast.Type { if left_type.is_ptr() || left_type.is_pointer() { if right_type.is_int() { return left_type } else { - return table.void_type + return ast.void_type } } else if right_type.is_ptr() || right_type.is_pointer() { if left_type.is_int() { return right_type } else { - return table.void_type + return ast.void_type } } if left_type == right_type { @@ -179,13 +178,13 @@ pub fn (c &Checker) promote(left_type table.Type, right_type table.Type) table.T return c.promote_num(left_type, right_type) } else if left_type.has_flag(.optional) != right_type.has_flag(.optional) { // incompatible - return table.void_type + return ast.void_type } else { return left_type // default to left if not automatic promotion possible } } -fn (c &Checker) promote_num(left_type table.Type, right_type table.Type) table.Type { +fn (c &Checker) promote_num(left_type ast.Type, right_type ast.Type) ast.Type { // sort the operands to save time mut type_hi := left_type mut type_lo := right_type @@ -195,38 +194,38 @@ fn (c &Checker) promote_num(left_type table.Type, right_type table.Type) table.T idx_hi := type_hi.idx() idx_lo := type_lo.idx() // the following comparisons rely on the order of the indices in table/types.v - if idx_hi == table.int_literal_type_idx { + if idx_hi == ast.int_literal_type_idx { return type_lo - } else if idx_hi == table.float_literal_type_idx { - if idx_lo in table.float_type_idxs { + } else if idx_hi == ast.float_literal_type_idx { + if idx_lo in ast.float_type_idxs { return type_lo } else { - return table.void_type + return ast.void_type } } else if type_hi.is_float() { - if idx_hi == table.f32_type_idx { - if idx_lo in [table.i64_type_idx, table.u64_type_idx] { - return table.void_type + if idx_hi == ast.f32_type_idx { + if idx_lo in [ast.i64_type_idx, ast.u64_type_idx] { + return ast.void_type } else { return type_hi } } else { // f64, float_literal return type_hi } - } else if idx_lo >= table.byte_type_idx { // both operands are unsigned + } else if idx_lo >= ast.byte_type_idx { // both operands are unsigned return type_hi - } else if idx_lo >= table.i8_type_idx - && (idx_hi <= table.i64_type_idx || idx_hi == table.rune_type_idx) { // both signed - return if idx_lo == table.i64_type_idx { type_lo } else { type_hi } - } else if idx_hi - idx_lo < (table.byte_type_idx - table.i8_type_idx) { + } else if idx_lo >= ast.i8_type_idx + && (idx_hi <= ast.i64_type_idx || idx_hi == ast.rune_type_idx) { // both signed + return if idx_lo == ast.i64_type_idx { type_lo } else { type_hi } + } else if idx_hi - idx_lo < (ast.byte_type_idx - ast.i8_type_idx) { return type_lo // conversion unsigned -> signed if signed type is larger } else { - return table.void_type // conversion signed -> unsigned not allowed + return ast.void_type // conversion signed -> unsigned not allowed } } // TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged -pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool { +pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool { if got == expected { return true } @@ -242,7 +241,7 @@ pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool { if exp_idx == got_idx { return true } - if exp_idx == table.voidptr_type_idx || exp_idx == table.byteptr_type_idx { + if exp_idx == ast.voidptr_type_idx || exp_idx == ast.byteptr_type_idx { if got.is_ptr() || got.is_pointer() { return true } @@ -250,25 +249,25 @@ pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool { // allow direct int-literal assignment for pointers for now // maybe in the future optionals should be used for that if expected.is_ptr() || expected.is_pointer() { - if got == table.int_literal_type { + if got == ast.int_literal_type { return true } } - if got_idx == table.voidptr_type_idx || got_idx == table.byteptr_type_idx { + if got_idx == ast.voidptr_type_idx || got_idx == ast.byteptr_type_idx { if expected.is_ptr() || expected.is_pointer() { return true } } - if expected == table.charptr_type && got == table.char_type.to_ptr() { + if expected == ast.charptr_type && got == ast.char_type.to_ptr() { return true } if !c.check_basic(got, expected) { // TODO: this should go away... return false } if got.is_number() && expected.is_number() { - if got == table.rune_type && expected == table.byte_type { + if got == ast.rune_type && expected == ast.byte_type { return true - } else if expected == table.rune_type && got == table.byte_type { + } else if expected == ast.rune_type && got == ast.byte_type { return true } if c.promote_num(expected, got) != expected { @@ -282,7 +281,7 @@ pub fn (mut c Checker) check_types(got table.Type, expected table.Type) bool { return true } -pub fn (mut c Checker) check_expected(got table.Type, expected table.Type) ? { +pub fn (mut c Checker) check_expected(got ast.Type, expected ast.Type) ? { if c.check_types(got, expected) { return } @@ -290,30 +289,30 @@ pub fn (mut c Checker) check_expected(got table.Type, expected table.Type) ? { } [inline] -fn (c &Checker) expected_msg(got table.Type, expected table.Type) string { +fn (c &Checker) expected_msg(got ast.Type, expected ast.Type) string { exps := c.table.type_to_str(expected) gots := c.table.type_to_str(got) return 'expected `$exps`, not `$gots`' } -pub fn (mut c Checker) symmetric_check(left table.Type, right table.Type) bool { +pub fn (mut c Checker) symmetric_check(left ast.Type, right ast.Type) bool { // allow direct int-literal assignment for pointers for now // maybe in the future optionals should be used for that if right.is_ptr() || right.is_pointer() { - if left == table.int_literal_type { + if left == ast.int_literal_type { return true } } // allow direct int-literal assignment for pointers for now if left.is_ptr() || left.is_pointer() { - if right == table.int_literal_type { + if right == ast.int_literal_type { return true } } return c.check_basic(left, right) } -pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte { +pub fn (c &Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) byte { if ftyp.has_flag(.optional) { return `s` } else if typ.is_float() { @@ -328,16 +327,16 @@ pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte { mut sym := c.table.get_type_symbol(c.unwrap_generic(ftyp)) if sym.kind == .alias { // string aliases should be printable - info := sym.info as table.Alias + info := sym.info as ast.Alias sym = c.table.get_type_symbol(info.parent_type) - if info.parent_type == table.string_type { + if info.parent_type == ast.string_type { return `s` } } if sym.kind == .function { return `s` } - if ftyp in [table.string_type, table.bool_type] + if ftyp in [ast.string_type, ast.bool_type] || sym.kind in [.enum_, .array, .array_fixed, .struct_, .map, .multi_return, .sum_type, .interface_, .none_] || ftyp.has_flag(.optional) || sym.has_method('str') { return `s` @@ -347,7 +346,7 @@ pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte { } } -pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ table.Type, what string) { +pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) { mut pos := token.Position{} match expr { ast.Ident { @@ -376,7 +375,7 @@ pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ table.Type, what st } } -pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.Type { +pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type { inside_println_arg_save := c.inside_println_arg c.inside_println_arg = true for i, expr in node.exprs { @@ -392,7 +391,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T if fmt == `_` { // set default representation for type if none has been given fmt = c.get_default_fmt(ftyp, typ) if fmt == `_` { - if typ != table.void_type { + if typ != ast.void_type { c.error('no known default format for type `${c.table.get_type_name(ftyp)}`', node.fmt_poss[i]) } @@ -413,7 +412,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T || (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) || (typ.is_pointer() && fmt !in [`p`, `x`, `X`]) || (typ.is_string() && fmt != `s`) - || (typ.idx() in [table.i64_type_idx, table.f64_type_idx] && fmt == `c`) { + || (typ.idx() in [ast.i64_type_idx, ast.f64_type_idx] && fmt == `c`) { c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`', node.fmt_poss[i]) } @@ -425,18 +424,18 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) table.T } } c.inside_println_arg = inside_println_arg_save - return table.string_type + return ast.string_type } -pub fn (mut c Checker) infer_fn_types(f table.Fn, mut call_expr ast.CallExpr) { - mut inferred_types := []table.Type{} +pub fn (mut c Checker) infer_fn_types(f ast.Fn, mut call_expr ast.CallExpr) { + mut inferred_types := []ast.Type{} for gi, gt_name in f.generic_names { // skip known types if gi < call_expr.generic_types.len { inferred_types << call_expr.generic_types[gi] continue } - mut typ := table.void_type + mut typ := ast.void_type for i, param in f.params { arg_i := if i != 0 && call_expr.is_method { i - 1 } else { i } if call_expr.args.len <= arg_i { @@ -453,16 +452,16 @@ pub fn (mut c Checker) infer_fn_types(f table.Fn, mut call_expr ast.CallExpr) { } arg_sym := c.table.get_type_symbol(arg.typ) if arg_sym.kind == .array && param_type_sym.kind == .array { - mut arg_elem_info := arg_sym.info as table.Array - mut param_elem_info := param_type_sym.info as table.Array + mut arg_elem_info := arg_sym.info as ast.Array + mut param_elem_info := param_type_sym.info as ast.Array mut arg_elem_sym := c.table.get_type_symbol(arg_elem_info.elem_type) mut param_elem_sym := c.table.get_type_symbol(param_elem_info.elem_type) for { if arg_elem_sym.kind == .array && param_elem_sym.kind == .array && c.cur_fn.generic_params.filter(it.name == param_elem_sym.name).len == 0 { - arg_elem_info = arg_elem_sym.info as table.Array + arg_elem_info = arg_elem_sym.info as ast.Array arg_elem_sym = c.table.get_type_symbol(arg_elem_info.elem_type) - param_elem_info = param_elem_sym.info as table.Array + param_elem_info = param_elem_sym.info as ast.Array param_elem_sym = c.table.get_type_symbol(param_elem_info.elem_type) } else { typ = arg_elem_info.elem_type @@ -475,7 +474,7 @@ pub fn (mut c Checker) infer_fn_types(f table.Fn, mut call_expr ast.CallExpr) { break } } - if typ == table.void_type { + if typ == ast.void_type { c.error('could not infer generic type `$gt_name` in call to `$f.name`', call_expr.pos) return } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 200bf41233..eb42ffd7c3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -7,7 +7,6 @@ import strings import time import v.ast import v.vmod -import v.table import v.token import v.pref import v.util @@ -35,7 +34,7 @@ const ( pub struct Checker { pref &pref.Preferences // Preferences shared from V struct pub mut: - table &table.Table + table &ast.Table file &ast.File = 0 nr_errors int nr_warnings int @@ -44,8 +43,8 @@ pub mut: warnings []errors.Warning notices []errors.Notice error_lines []int // to avoid printing multiple errors for the same line - expected_type table.Type - expected_or_type table.Type // fn() or { 'this type' } eg. string. expected or block type + expected_type ast.Type + expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type cur_fn &ast.FnDecl // current function const_decl string const_deps []string @@ -64,19 +63,19 @@ pub mut: inside_anon_fn bool inside_ref_lit bool skip_flags bool // should `#flag` and `#include` be skipped - cur_generic_types []table.Type + cur_generic_types []ast.Type mut: files []ast.File expr_level int // to avoid infinite recursion segfaults due to compiler bugs inside_sql bool // to handle sql table fields pseudo variables - cur_orm_ts table.TypeSymbol + cur_orm_ts ast.TypeSymbol error_details []string - vmod_file_content string // needed for @VMOD_FILE, contents of the file, *NOT its path** - vweb_gen_types []table.Type // vweb route checks - prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then - loop_label string // set when inside a labelled for loop + vmod_file_content string // needed for @VMOD_FILE, contents of the file, *NOT its path** + vweb_gen_types []ast.Type // vweb route checks + prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then + loop_label string // set when inside a labelled for loop timers &util.Timers = util.new_timers(false) - comptime_fields_type map[string]table.Type + comptime_fields_type map[string]ast.Type fn_scope &ast.Scope = voidptr(0) used_fns map[string]bool // used_fns['println'] == true main_fn_decl_node ast.FnDecl @@ -87,7 +86,7 @@ mut: inside_println_arg bool } -pub fn new_checker(table &table.Table, pref &pref.Preferences) Checker { +pub fn new_checker(table &ast.Table, pref &pref.Preferences) Checker { mut timers_should_print := false $if time_checking ? { timers_should_print = true @@ -176,7 +175,7 @@ pub fn (mut c Checker) check_files(ast_files []ast.File) { mod: 'main' is_main: true file: the_main_file.path - return_type: table.void_type + return_type: ast.void_type scope: &ast.Scope{ parent: 0 } @@ -251,7 +250,7 @@ fn (mut c Checker) file_has_main_fn(file ast.File) bool { if stmt.params.len > 0 { c.error('function `main` cannot have arguments', stmt.pos) } - if stmt.return_type != table.void_type { + if stmt.return_type != ast.void_type { c.error('function `main` cannot return values', stmt.pos) } if stmt.no_body { @@ -304,7 +303,7 @@ pub fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) { if typ_sym.kind in [.placeholder, .int_literal, .float_literal] { c.error("type `$typ_sym.name` doesn't exist", node.pos) } else if typ_sym.kind == .alias { - orig_sym := c.table.get_type_symbol((typ_sym.info as table.Alias).parent_type) + orig_sym := c.table.get_type_symbol((typ_sym.info as ast.Alias).parent_type) c.error('type `$typ_sym.str()` is an alias, use the original alias type `$orig_sym.name` instead', node.pos) } else if typ_sym.kind == .chan { @@ -315,7 +314,7 @@ pub fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) { pub fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) { c.check_valid_pascal_case(node.name, 'fn type', node.pos) typ_sym := c.table.get_type_symbol(node.typ) - fn_typ_info := typ_sym.info as table.FnType + fn_typ_info := typ_sym.info as ast.FnType fn_info := fn_typ_info.func ret_sym := c.table.get_type_symbol(fn_info.return_type) if ret_sym.kind == .placeholder { @@ -353,7 +352,7 @@ pub fn (mut c Checker) interface_decl(decl ast.InterfaceDecl) { c.check_valid_pascal_case(decl.name, 'interface name', decl.pos) for method in decl.methods { c.check_valid_snake_case(method.name, 'method name', method.pos) - if method.return_type != table.Type(0) { + if method.return_type != ast.Type(0) { c.ensure_type_exists(method.return_type, method.pos) or { return } } for param in method.params { @@ -362,7 +361,7 @@ pub fn (mut c Checker) interface_decl(decl ast.InterfaceDecl) { } for i, field in decl.fields { c.check_valid_snake_case(field.name, 'field name', field.pos) - if field.typ != table.Type(0) { + if field.typ != ast.Type(0) { c.ensure_type_exists(field.typ, field.pos) or { return } } for j in 0 .. i { @@ -377,14 +376,14 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) { if decl.language == .v && !c.is_builtin_mod { c.check_valid_pascal_case(decl.name, 'struct name', decl.pos) } - mut struct_sym := c.table.find_type(decl.name) or { table.TypeSymbol{} } - if mut struct_sym.info is table.Struct { + mut struct_sym := c.table.find_type(decl.name) or { ast.TypeSymbol{} } + if mut struct_sym.info is ast.Struct { for embed in decl.embeds { embed_sym := c.table.get_type_symbol(embed.typ) if embed_sym.kind != .struct_ { c.error('`$embed_sym.name` is not a struct', embed.pos) } else { - info := embed_sym.info as table.Struct + info := embed_sym.info as ast.Struct if info.is_heap && !embed.typ.is_ptr() { struct_sym.info.is_heap = true } @@ -407,7 +406,7 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) { } } if sym.kind == .struct_ { - info := sym.info as table.Struct + info := sym.info as ast.Struct if info.is_heap && !field.typ.is_ptr() { struct_sym.info.is_heap = true } @@ -451,16 +450,16 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) { } } -pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { +pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type { // typ := c.table.find_type(struct_init.typ.typ.name) or { // c.error('unknown struct: $struct_init.typ.typ.name', struct_init.pos) // panic('') // } - if struct_init.typ == table.void_type { + if struct_init.typ == ast.void_type { // Short syntax `({foo: bar})` - if c.expected_type == table.void_type { + if c.expected_type == ast.void_type { c.error('unexpected short struct syntax', struct_init.pos) - return table.void_type + return ast.void_type } sym := c.table.get_type_symbol(c.expected_type) if sym.kind == .array { @@ -493,10 +492,10 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { if type_sym.kind == .interface_ { c.error('cannot instantiate interface `$type_sym.name`', struct_init.pos) } - if type_sym.info is table.Alias { + if type_sym.info is ast.Alias { if type_sym.info.parent_type.is_number() { c.error('cannot instantiate number type alias `$type_sym.name`', struct_init.pos) - return table.void_type + return ast.void_type } } // allow init structs from generic if they're private except the type is from builtin module @@ -506,7 +505,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { c.error('type `$type_sym.name` is private', struct_init.pos) } if type_sym.kind == .struct_ { - info := type_sym.info as table.Struct + info := type_sym.info as ast.Struct if info.attrs.len > 0 && info.attrs[0].name == 'noinit' && type_sym.mod != c.mod { c.error('struct `$type_sym.name` is declared with a `[noinit]` attribute, so ' + 'it cannot be initialized with `$type_sym.name{}`', struct_init.pos) @@ -523,24 +522,24 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { match type_sym.kind { .placeholder { c.error('unknown struct: $type_sym.name', struct_init.pos) - return table.void_type + return ast.void_type } // string & array are also structs but .kind of string/array .struct_, .string, .array, .alias { - mut info := table.Struct{} + mut info := ast.Struct{} if type_sym.kind == .alias { - info_t := type_sym.info as table.Alias + info_t := type_sym.info as ast.Alias sym := c.table.get_type_symbol(info_t.parent_type) if sym.kind == .placeholder { // pending import symbol did not resolve c.error('unknown struct: $type_sym.name', struct_init.pos) - return table.void_type + return ast.void_type } if sym.kind != .struct_ { c.error('alias type name: $sym.name is not struct type', struct_init.pos) } - info = sym.info as table.Struct + info = sym.info as ast.Struct } else { - info = type_sym.info as table.Struct + info = type_sym.info as ast.Struct } if struct_init.is_short { exp_len := info.fields.len @@ -553,8 +552,8 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { } mut inited_fields := []string{} for i, field in struct_init.fields { - mut info_field := table.Field{} - mut embed_type := table.Type(0) + mut info_field := ast.StructField{} + mut embed_type := ast.Type(0) mut is_embed := false mut field_name := '' if struct_init.is_short { @@ -602,7 +601,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { c.expected_type = embed_type expr_type := c.expr(field.expr) expr_type_sym := c.table.get_type_symbol(expr_type) - if expr_type != table.void_type && expr_type_sym.kind != .placeholder { + if expr_type != ast.void_type && expr_type_sym.kind != .placeholder { c.check_expected(expr_type, embed_type) or { c.error('cannot assign to field `$info_field.name`: $err.msg', field.pos) @@ -621,7 +620,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { expr_type_sym := c.table.get_type_symbol(expr_type) if field_type_sym.kind == .interface_ { c.type_implements(expr_type, info_field.typ, field.pos) - } else if expr_type != table.void_type && expr_type_sym.kind != .placeholder { + } else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder { c.check_expected(expr_type, info_field.typ) or { c.error('cannot assign to field `$info_field.name`: $err.msg', field.pos) @@ -687,8 +686,8 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { } else if update_type != struct_init.typ { from_sym := c.table.get_type_symbol(update_type) to_sym := c.table.get_type_symbol(struct_init.typ) - from_info := from_sym.info as table.Struct - to_info := to_sym.info as table.Struct + from_info := from_sym.info as ast.Struct + to_info := to_sym.info as ast.Struct // TODO this check is too strict if !c.check_struct_signature(from_info, to_info) { c.error('struct `$from_sym.name` is not compatible with struct `$to_sym.name`', @@ -725,7 +724,7 @@ fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) { } } -pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { +pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type { // println('checker: infix expr(op $infix_expr.op.str())') former_expected_type := c.expected_type defer { @@ -750,7 +749,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { && !infix_expr.right.is_auto_deref_var() { c.warn('pointer arithmetic is only allowed in `unsafe` blocks', left_pos) } - if left_type == table.voidptr_type { + if left_type == ast.voidptr_type { c.error('`$infix_expr.op` cannot be used with `voidptr`', left_pos) } } @@ -810,22 +809,22 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { infix_expr.pos) } } - return table.bool_type + return ast.bool_type } .plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe { // binary operators that expect matching types - if right.info is table.Alias && (right.info as table.Alias).language != .c + if right.info is ast.Alias && (right.info as ast.Alias).language != .c && c.mod == c.table.type_to_str(right_type).split('.')[0] - && c.table.get_type_symbol((right.info as table.Alias).parent_type).is_primitive() { - right = c.table.get_type_symbol((right.info as table.Alias).parent_type) + && c.table.get_type_symbol((right.info as ast.Alias).parent_type).is_primitive() { + right = c.table.get_type_symbol((right.info as ast.Alias).parent_type) } - if left.info is table.Alias && (left.info as table.Alias).language != .c + if left.info is ast.Alias && (left.info as ast.Alias).language != .c && c.mod == c.table.type_to_str(left_type).split('.')[0] - && c.table.get_type_symbol((left.info as table.Alias).parent_type).is_primitive() { - left = c.table.get_type_symbol((left.info as table.Alias).parent_type) + && c.table.get_type_symbol((left.info as ast.Alias).parent_type).is_primitive() { + left = c.table.get_type_symbol((left.info as ast.Alias).parent_type) } // Check if the alias type is not a primitive then allow using operator overloading for aliased `arrays` and `maps` - if left.kind == .alias && left.info is table.Alias - && !(c.table.get_type_symbol((left.info as table.Alias).parent_type).is_primitive()) { + if left.kind == .alias && left.info is ast.Alias + && !(c.table.get_type_symbol((left.info as ast.Alias).parent_type).is_primitive()) { if left.has_method(infix_expr.op.str()) { if method := left.find_method(infix_expr.op.str()) { return_type = method.return_type @@ -842,8 +841,8 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { c.error('mismatched types `$left_name` and `$right_name`', left_right_pos) } } - } else if right.kind == .alias && right.info is table.Alias - && !(c.table.get_type_symbol((right.info as table.Alias).parent_type).is_primitive()) { + } else if right.kind == .alias && right.info is ast.Alias + && !(c.table.get_type_symbol((right.info as ast.Alias).parent_type).is_primitive()) { if right.has_method(infix_expr.op.str()) { if method := right.find_method(infix_expr.op.str()) { return_type = method.return_type @@ -897,7 +896,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { } } else { promoted_type := c.promote(c.table.unalias_num_type(left_type), c.table.unalias_num_type(right_type)) - if promoted_type.idx() == table.void_type_idx { + if promoted_type.idx() == ast.void_type_idx { left_name := c.table.type_to_str(left_type) right_name := c.table.type_to_str(right_type) c.error('mismatched types `$left_name` and `$right_name`', left_right_pos) @@ -967,20 +966,20 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { c.type_implements(c.table.value_type(right_type), left_value_type, right_pos) } - return table.void_type + return ast.void_type } // the expressions have different types (array_x and x) if c.check_types(right_type, left_value_type) { // , right_type) { // []T << T - return table.void_type + return ast.void_type } if right_final.kind == .array && c.check_types(left_value_type, c.table.value_type(right_type)) { // []T << []T - return table.void_type + return ast.void_type } c.error('cannot append `$right.name` to `$left.name`', right_pos) - return table.void_type + return ast.void_type } else { return c.check_shift(left_type, right_type, left_pos, right_pos) } @@ -991,15 +990,15 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { .key_is, .not_is { right_expr := infix_expr.right mut typ := match right_expr { - ast.Type { + ast.TypeNode { right_expr.typ } ast.None { - table.none_type_idx + ast.none_type_idx } else { c.error('invalid type `$right_expr`', right_expr.position()) - table.Type(0) + ast.Type(0) } } typ_sym := c.table.get_type_symbol(typ) @@ -1009,12 +1008,12 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { } if left.kind !in [.interface_, .sum_type] { c.error('`$op` can only be used with interfaces and sum types', infix_expr.pos) - } else if mut left.info is table.SumType { + } else if mut left.info is ast.SumType { if typ !in left.info.variants { c.error('`$left.name` has no variant `$right.name`', infix_expr.pos) } } - return table.bool_type + return ast.bool_type } .arrow { // `chan <- elem` if left.kind == .chan { @@ -1035,13 +1034,13 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { } else { c.error('cannot push on non-channel `$left.name`', left_pos) } - return table.void_type + return ast.void_type } .and, .logical_or { - if infix_expr.left_type != table.bool_type_idx { + if infix_expr.left_type != ast.bool_type_idx { c.error('left operand for `$infix_expr.op` is not a boolean', infix_expr.left.position()) } - if infix_expr.right_type != table.bool_type_idx { + if infix_expr.right_type != ast.bool_type_idx { c.error('right operand for `$infix_expr.op` is not a boolean', infix_expr.right.position()) } // use `()` to make the boolean expression clear error @@ -1055,17 +1054,17 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { else {} } // TODO: Absorb this block into the above single side check block to accelerate. - if left_type == table.bool_type && infix_expr.op !in [.eq, .ne, .logical_or, .and] { + if left_type == ast.bool_type && infix_expr.op !in [.eq, .ne, .logical_or, .and] { c.error('bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`', infix_expr.pos) - } else if left_type == table.string_type + } else if left_type == ast.string_type && infix_expr.op !in [.plus, .eq, .ne, .lt, .gt, .le, .ge] { // TODO broken !in c.error('string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`', infix_expr.pos) } else if left.kind == .enum_ && right.kind == .enum_ && !eq_ne { - left_enum := left.info as table.Enum - right_enum := right.info as table.Enum + left_enum := left.info as ast.Enum + right_enum := right.info as ast.Enum if left_enum.is_flag && right_enum.is_flag { // `[flag]` tagged enums are a special case that allow also `|` and `&` binary operators if infix_expr.op !in [.pipe, .amp] { @@ -1094,8 +1093,8 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { // Dual sides check (compatibility check) if !c.symmetric_check(right_type, left_type) && !c.pref.translated { // for type-unresolved consts - if left_type == table.void_type || right_type == table.void_type { - return table.void_type + if left_type == ast.void_type || right_type == ast.void_type { + return ast.void_type } c.error('infix expr: cannot use `$right.name` (right expression) as `$left.name`', left_right_pos) @@ -1107,7 +1106,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { c.warn('`++` and `--` are statements, not expressions', infix_expr.pos) } */ - return if infix_expr.op.is_relational() { table.bool_type } else { return_type } + return if infix_expr.op.is_relational() { ast.bool_type } else { return_type } } // returns name and position of variable that needs write lock @@ -1153,16 +1152,16 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) { } ast.IndexExpr { left_sym := c.table.get_type_symbol(expr.left_type) - mut elem_type := table.Type(0) + mut elem_type := ast.Type(0) mut kind := '' match left_sym.info { - table.Array { + ast.Array { elem_type, kind = left_sym.info.elem_type, 'array' } - table.ArrayFixed { + ast.ArrayFixed { elem_type, kind = left_sym.info.elem_type, 'fixed array' } - table.Map { + ast.Map { elem_type, kind = left_sym.info.value_type, 'map' } else {} @@ -1183,21 +1182,21 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) { if expr.expr_type == 0 { return '', pos } - // retrieve table.Field + // retrieve ast.Field c.ensure_type_exists(expr.expr_type, expr.pos) or { return '', pos } mut typ_sym := c.table.get_final_type_symbol(c.unwrap_generic(expr.expr_type)) match typ_sym.kind { .struct_ { - struct_info := typ_sym.info as table.Struct + struct_info := typ_sym.info as ast.Struct mut has_field := true mut field_info := struct_info.find_field(expr.field_name) or { has_field = false - table.Field{} + ast.StructField{} } if !has_field { for embed in struct_info.embeds { embed_sym := c.table.get_type_symbol(embed) - embed_struct_info := embed_sym.info as table.Struct + embed_struct_info := embed_sym.info as ast.Struct if embed_field_info := embed_struct_info.find_field(expr.field_name) { has_field = true field_info = embed_field_info @@ -1227,7 +1226,7 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) { } } .interface_ { - interface_info := typ_sym.info as table.Interface + interface_info := typ_sym.info as ast.Interface mut field_info := interface_info.find_field(expr.field_name) or { type_str := c.table.type_to_str(expr.expr_type) c.error('unknown field `${type_str}.$expr.field_name`', expr.pos) @@ -1285,7 +1284,7 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) { return to_lock, pos } -pub fn (mut c Checker) call_expr(mut call_expr ast.CallExpr) table.Type { +pub fn (mut c Checker) call_expr(mut call_expr ast.CallExpr) ast.Type { // First check everything that applies to both fns and methods // TODO merge logic from call_method and call_fn /* @@ -1315,7 +1314,7 @@ pub fn (mut c Checker) call_expr(mut call_expr ast.CallExpr) table.Type { && !call_expr.args[0].typ.has_flag(.optional) if free_tmp_arg_vars && !c.inside_const { for i, arg in call_expr.args { - if arg.typ != table.string_type { + if arg.typ != ast.string_type { continue } if arg.expr is ast.Ident || arg.expr is ast.StringLiteral @@ -1329,7 +1328,7 @@ pub fn (mut c Checker) call_expr(mut call_expr ast.CallExpr) table.Type { call_expr.args[i].is_tmp_autofree = true } // TODO copy pasta from above - if call_expr.receiver_type == table.string_type && !(call_expr.left is ast.Ident + if call_expr.receiver_type == ast.string_type && !(call_expr.left is ast.Ident || call_expr.left is ast.StringLiteral || call_expr.left is ast.SelectorExpr) { call_expr.free_receiver = true @@ -1337,7 +1336,7 @@ pub fn (mut c Checker) call_expr(mut call_expr ast.CallExpr) table.Type { } c.expected_or_type = call_expr.return_type.clear_flag(.optional) c.stmts(call_expr.or_block.stmts) - c.expected_or_type = table.void_type + c.expected_or_type = ast.void_type if call_expr.or_block.kind == .propagate && !c.cur_fn.return_type.has_flag(.optional) && !c.inside_const { if !c.cur_fn.is_main { @@ -1348,7 +1347,7 @@ pub fn (mut c Checker) call_expr(mut call_expr ast.CallExpr) table.Type { return typ } -fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_expr ast.CallExpr) { +fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, call_expr ast.CallExpr) { if call_expr.args.len != 1 { c.error('expected 1 argument, but got $call_expr.args.len', call_expr.pos) // Finish early so that it doesn't fail later @@ -1360,10 +1359,10 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e ast.AnonFn { if arg_expr.decl.params.len > 1 { c.error('function needs exactly 1 argument', arg_expr.decl.pos) - } else if is_map && (arg_expr.decl.return_type == table.void_type + } else if is_map && (arg_expr.decl.return_type == ast.void_type || arg_expr.decl.params[0].typ != elem_typ) { c.error('type mismatch, should use `fn(a $elem_sym.name) T {...}`', arg_expr.decl.pos) - } else if !is_map && (arg_expr.decl.return_type != table.bool_type + } else if !is_map && (arg_expr.decl.return_type != ast.bool_type || arg_expr.decl.params[0].typ != elem_typ) { c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`', arg_expr.decl.pos) @@ -1378,11 +1377,11 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e if func.params.len > 1 { c.error('function needs exactly 1 argument', call_expr.pos) } else if is_map - && (func.return_type == table.void_type || func.params[0].typ != elem_typ) { + && (func.return_type == ast.void_type || func.params[0].typ != elem_typ) { c.error('type mismatch, should use `fn(a $elem_sym.name) T {...}`', arg_expr.pos) } else if !is_map - && (func.return_type != table.bool_type || func.params[0].typ != elem_typ) { + && (func.return_type != ast.bool_type || func.params[0].typ != elem_typ) { c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`', arg_expr.pos) } @@ -1393,11 +1392,11 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e // copied from above if expr.decl.params.len > 1 { c.error('function needs exactly 1 argument', expr.decl.pos) - } else if is_map && (expr.decl.return_type == table.void_type + } else if is_map && (expr.decl.return_type == ast.void_type || expr.decl.params[0].typ != elem_typ) { c.error('type mismatch, should use `fn(a $elem_sym.name) T {...}`', expr.decl.pos) - } else if !is_map && (expr.decl.return_type != table.bool_type + } else if !is_map && (expr.decl.return_type != ast.bool_type || expr.decl.params[0].typ != elem_typ) { c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`', expr.decl.pos) @@ -1405,7 +1404,7 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e return } } - if !is_map && arg_expr.info.typ != table.bool_type { + if !is_map && arg_expr.info.typ != ast.bool_type { c.error('type mismatch, should be bool', arg_expr.pos) } } @@ -1414,7 +1413,7 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e } } -pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { +pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) ast.Type { left_type := c.expr(call_expr.left) c.expected_type = left_type is_generic := left_type.has_flag(.generic) @@ -1428,13 +1427,13 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { mut unknown_method_msg := 'unknown method: `${left_type_sym.name}.$method_name`' if left_type.has_flag(.optional) { c.error('optional type cannot be called directly', call_expr.left.position()) - return table.void_type + return ast.void_type } if left_type_sym.kind in [.sum_type, .interface_] && method_name == 'type_name' { - return table.string_type + return ast.string_type } mut has_generic_generic := false // x.foo() instead of x.foo() - mut generic_types := []table.Type{} + mut generic_types := []ast.Type{} for generic_type in call_expr.generic_types { if generic_type.has_flag(.generic) { has_generic_generic = true @@ -1458,7 +1457,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { } else if left_type_sym.kind == .map && method_name in ['clone', 'keys', 'move'] { return c.call_map_builtin_method(mut call_expr, left_type, left_type_sym) } else if left_type_sym.kind == .array && method_name in ['insert', 'prepend'] { - info := left_type_sym.info as table.Array + info := left_type_sym.info as ast.Array arg_expr := if method_name == 'insert' { call_expr.args[1].expr } else { @@ -1470,24 +1469,24 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { c.error('cannot $method_name `$arg_sym.name` to `$left_type_sym.name`', arg_expr.position()) } } else if left_type_sym.kind == .thread && method_name == 'wait' { - info := left_type_sym.info as table.Thread + info := left_type_sym.info as ast.Thread if call_expr.args.len > 0 { c.error('wait() does not have any arguments', call_expr.args[0].pos) } call_expr.return_type = info.return_type return info.return_type } - mut method := table.Fn{} + mut method := ast.Fn{} mut has_method := false mut is_method_from_embed := false if m := c.table.type_find_method(left_type_sym, method_name) { method = m has_method = true } else { - // can this logic be moved to table.type_find_method() so it can be used from anywhere - if left_type_sym.info is table.Struct { - mut found_methods := []table.Fn{} - mut embed_of_found_methods := []table.Type{} + // can this logic be moved to ast.type_find_method() so it can be used from anywhere + if left_type_sym.info is ast.Struct { + mut found_methods := []ast.Fn{} + mut embed_of_found_methods := []ast.Type{} for embed in left_type_sym.info.embeds { embed_sym := c.table.get_type_symbol(embed) if m := c.table.type_find_method(embed_sym, method_name) { @@ -1535,7 +1534,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { && method.no_body { c.error('cannot call a method that does not have a body', call_expr.pos) } - if method.return_type == table.void_type && method.ctdefine.len > 0 + if method.return_type == ast.void_type && method.ctdefine.len > 0 && method.ctdefine !in c.pref.compile_defines { call_expr.should_be_skipped = true } @@ -1587,7 +1586,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { // if arg_typ_sym.kind == .string && typ_sym.has_method('str') { // continue // } - if got_arg_typ != table.void_type { + if got_arg_typ != ast.void_type { c.error('$err.msg in argument ${i + 1} to `${left_type_sym.name}.$method_name`', arg.pos) } @@ -1679,12 +1678,12 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { call_expr.pos) } call_expr.receiver_type = left_type - call_expr.return_type = table.string_type + call_expr.return_type = ast.string_type if call_expr.args.len > 0 { c.error('.str() method calls should have no arguments', call_expr.pos) } c.fail_if_unreadable(call_expr.left, left_type, 'receiver') - return table.string_type + return ast.string_type } // call struct field fn type // TODO: can we use SelectorExpr for all? this dosent really belong here @@ -1693,9 +1692,9 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { if field_type_sym.kind == .function { // call_expr.is_method = false call_expr.is_field = true - info := field_type_sym.info as table.FnType + info := field_type_sym.info as ast.FnType call_expr.return_type = info.func.return_type - mut earg_types := []table.Type{} + mut earg_types := []ast.Type{} for mut arg in call_expr.args { targ := c.check_expr_opt_call(arg.expr, c.expr(arg.expr)) arg.typ = targ @@ -1705,16 +1704,16 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { return info.func.return_type } } - if left_type != table.void_type { + if left_type != ast.void_type { suggestion := util.new_suggestion(method_name, left_type_sym.methods.map(it.name)) c.error(suggestion.say(unknown_method_msg), call_expr.pos) } - return table.void_type + return ast.void_type } -fn (mut c Checker) call_map_builtin_method(mut call_expr ast.CallExpr, left_type table.Type, left_type_sym table.TypeSymbol) table.Type { +fn (mut c Checker) call_map_builtin_method(mut call_expr ast.CallExpr, left_type ast.Type, left_type_sym ast.TypeSymbol) ast.Type { method_name := call_expr.name - mut ret_type := table.void_type + mut ret_type := ast.void_type match method_name { 'clone', 'move' { if method_name[0] == `m` { @@ -1727,9 +1726,9 @@ fn (mut c Checker) call_map_builtin_method(mut call_expr ast.CallExpr, left_type } } 'keys' { - info := left_type_sym.info as table.Map + info := left_type_sym.info as ast.Map typ := c.table.find_or_register_array(info.key_type) - ret_type = table.Type(typ) + ret_type = ast.Type(typ) } else {} } @@ -1738,13 +1737,13 @@ fn (mut c Checker) call_map_builtin_method(mut call_expr ast.CallExpr, left_type return call_expr.return_type } -fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_type table.Type, left_type_sym table.TypeSymbol) table.Type { +fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_type ast.Type, left_type_sym ast.TypeSymbol) ast.Type { method_name := call_expr.name - mut elem_typ := table.void_type + mut elem_typ := ast.void_type if method_name == 'slice' && !c.is_builtin_mod { c.error('.slice() is a private method, use `x[start..end]` instead', call_expr.pos) } - array_info := left_type_sym.info as table.Array + array_info := left_type_sym.info as ast.Array elem_typ = array_info.elem_type if method_name in ['filter', 'map', 'any', 'all'] { // position of `it` doesn't matter @@ -1802,7 +1801,7 @@ fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_ty c.check_map_and_filter(true, elem_typ, call_expr) arg_sym := c.table.get_type_symbol(arg_type) ret_type := match arg_sym.info { - table.FnType { arg_sym.info.func.return_type } + ast.FnType { arg_sym.info.func.return_type } else { arg_type } } call_expr.return_type = c.table.find_or_register_array(ret_type) @@ -1811,7 +1810,7 @@ fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_ty c.check_map_and_filter(false, elem_typ, call_expr) } else if method_name in ['any', 'all'] { c.check_map_and_filter(false, elem_typ, call_expr) - call_expr.return_type = table.bool_type + call_expr.return_type = ast.bool_type } else if method_name == 'clone' { // need to return `array_xxx` instead of `array` // in ['clone', 'str'] { @@ -1822,11 +1821,11 @@ fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_ty call_expr.return_type = call_expr.receiver_type.set_nr_muls(0) } } else if method_name == 'sort' { - call_expr.return_type = table.void_type + call_expr.return_type = ast.void_type } else if method_name == 'contains' { - call_expr.return_type = table.bool_type + call_expr.return_type = ast.bool_type } else if method_name == 'index' { - call_expr.return_type = table.int_type + call_expr.return_type = ast.int_type } else if method_name in ['first', 'last', 'pop'] { call_expr.return_type = array_info.elem_type if method_name == 'pop' { @@ -1838,17 +1837,17 @@ fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_ty return call_expr.return_type } -pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { +pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) ast.Type { fn_name := call_expr.name if fn_name == 'main' { c.error('the `main` function cannot be called in the program', call_expr.pos) } if fn_name == 'typeof' { // TODO: impl typeof properly (probably not going to be a fn call) - return table.string_type + return ast.string_type } mut has_generic_generic := false // foo() instead of foo() - mut generic_types := []table.Type{} + mut generic_types := []ast.Type{} for generic_type in call_expr.generic_types { if generic_type.has_flag(.generic) { has_generic_generic = true @@ -1870,26 +1869,26 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { if call_expr.args.len != 2 { c.error("json.decode expects 2 arguments, a type and a string (e.g `json.decode(T, '')`)", call_expr.pos) - return table.void_type + return ast.void_type } expr := call_expr.args[0].expr - if expr !is ast.Type { + if expr !is ast.TypeNode { typ := expr.type_name() c.error('json.decode: first argument needs to be a type, got `$typ`', call_expr.pos) - return table.void_type + return ast.void_type } - c.expected_type = table.string_type + c.expected_type = ast.string_type call_expr.args[1].typ = c.expr(call_expr.args[1].expr) - if call_expr.args[1].typ != table.string_type { + if call_expr.args[1].typ != ast.string_type { c.error('json.decode: second argument needs to be a string', call_expr.pos) } - typ := expr as ast.Type + typ := expr as ast.TypeNode ret_type := typ.typ.set_flag(.optional) call_expr.return_type = ret_type return ret_type } // look for function in format `mod.fn` or `fn` (builtin) - mut f := table.Fn{} + mut f := ast.Fn{} mut found := false mut found_in_args := false // anon fn direct call @@ -1898,7 +1897,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { call_expr.name = '' c.expr(call_expr.left) anon_fn_sym := c.table.get_type_symbol(call_expr.left.typ) - f = (anon_fn_sym.info as table.FnType).func + f = (anon_fn_sym.info as ast.FnType).func found = true } // try prefix with current module as it would have never gotten prefixed @@ -1916,26 +1915,26 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { expr := call_expr.left as ast.IndexExpr sym := c.table.get_type_symbol(expr.left_type) if sym.kind == .array { - info := sym.info as table.Array + info := sym.info as ast.Array elem_typ := c.table.get_type_symbol(info.elem_type) - if elem_typ.info is table.FnType { + if elem_typ.info is ast.FnType { return elem_typ.info.func.return_type } } else if sym.kind == .map { - info := sym.info as table.Map + info := sym.info as ast.Map value_typ := c.table.get_type_symbol(info.value_type) - if value_typ.info is table.FnType { + if value_typ.info is ast.FnType { return value_typ.info.func.return_type } } else if sym.kind == .array_fixed { - info := sym.info as table.ArrayFixed + info := sym.info as ast.ArrayFixed elem_typ := c.table.get_type_symbol(info.elem_type) - if elem_typ.info is table.FnType { + if elem_typ.info is ast.FnType { return elem_typ.info.func.return_type } } found = true - return table.string_type + return ast.string_type } // already prefixed (mod.fn) or C/builtin/main if !found { @@ -1963,7 +1962,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { if v.typ != 0 { vts := c.table.get_type_symbol(v.typ) if vts.kind == .function { - info := vts.info as table.FnType + info := vts.info as ast.FnType f = info.func found = true found_in_args = true @@ -1973,7 +1972,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { } if !found { c.error('unknown function: $fn_name', call_expr.pos) - return table.void_type + return ast.void_type } if !found_in_args { if _ := call_expr.scope.find_var(fn_name) { @@ -2000,7 +1999,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { } if f.generic_names.len > 0 && f.return_type.has_flag(.generic) { rts := c.table.get_type_symbol(f.return_type) - if rts.info is table.Struct { + if rts.info is ast.Struct { if rts.info.generic_types.len > 0 { gts := c.table.get_type_symbol(call_expr.generic_types[0]) nrt := '$rts.name<$gts.name>' @@ -2008,7 +2007,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { idx := c.table.type_idxs[nrt] if idx != 0 { c.ensure_type_exists(idx, call_expr.pos) or {} - call_expr.return_type = table.new_type(idx).derive(f.return_type) + call_expr.return_type = ast.new_type(idx).derive(f.return_type) } else { mut fields := rts.info.fields.clone() if rts.info.generic_types.len == generic_types.len { @@ -2022,14 +2021,14 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { mut info := rts.info info.generic_types = [] info.fields = fields - stru_idx := c.table.register_type_symbol(table.TypeSymbol{ + stru_idx := c.table.register_type_symbol(ast.TypeSymbol{ kind: .struct_ name: nrt cname: util.no_dots(c_nrt) mod: c.mod info: info }) - call_expr.return_type = table.new_type(stru_idx) + call_expr.return_type = ast.new_type(stru_idx) } } } @@ -2037,8 +2036,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { } else { call_expr.return_type = f.return_type } - if f.return_type == table.void_type && f.ctdefine.len > 0 - && f.ctdefine !in c.pref.compile_defines { + if f.return_type == ast.void_type && f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines { call_expr.should_be_skipped = true } // dont check number of args for JS functions since arguments are not required @@ -2058,7 +2056,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { // println / eprintln / panic can print anything if fn_name in ['println', 'print', 'eprintln', 'eprint', 'panic'] && call_expr.args.len > 0 { c.inside_println_arg = true - c.expected_type = table.string_type + c.expected_type = ast.string_type call_expr.args[0].typ = c.expr(call_expr.args[0].expr) if call_expr.args[0].typ.is_void() { c.error('`$fn_name` can not print void expressions', call_expr.pos) @@ -2084,7 +2082,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { if fn_name == 'error' { arg := call_expr.args[0] call_expr.args[0].typ = c.expr(arg.expr) - if call_expr.args[0].typ == table.error_type { + if call_expr.args[0].typ == ast.error_type { c.warn('`error($arg)` can be shortened to just `$arg`', call_expr.pos) } } @@ -2185,7 +2183,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { // Warn about automatic (de)referencing, which will be removed soon. if f.language != .c && !c.inside_unsafe && typ.nr_muls() != param.typ.nr_muls() && !(call_arg.is_mut && param.is_mut) && !(!call_arg.is_mut && !param.is_mut) - && param.typ !in [table.byteptr_type, table.charptr_type, table.voidptr_type] { + && param.typ !in [ast.byteptr_type, ast.charptr_type, ast.voidptr_type] { // sym := c.table.get_type_symbol(typ) c.warn('automatic referencing/dereferencing is deprecated and will be removed soon (got: $typ.nr_muls() references, expected: $param.typ.nr_muls() references)', call_arg.pos) @@ -2210,7 +2208,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { return f.return_type } -fn (mut c Checker) deprecate_fnmethod(kind string, name string, the_fn table.Fn, call_expr ast.CallExpr) { +fn (mut c Checker) deprecate_fnmethod(kind string, name string, the_fn ast.Fn, call_expr ast.CallExpr) { start_message := '$kind `$name`' mut deprecation_message := '' now := time.now() @@ -2245,7 +2243,7 @@ fn semicolonize(main string, details string) string { return '$main; $details' } -fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos token.Position) bool { +fn (mut c Checker) type_implements(typ ast.Type, inter_typ ast.Type, pos token.Position) bool { $if debug_interface_type_implements ? { eprintln('> type_implements typ: $typ.debug() | inter_typ: $inter_typ.debug()') } @@ -2253,7 +2251,7 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok typ_sym := c.table.get_type_symbol(utyp) mut inter_sym := c.table.get_type_symbol(inter_typ) // do not check the same type more than once - if mut inter_sym.info is table.Interface { + if mut inter_sym.info is ast.Interface { for t in inter_sym.info.types { if t.idx() == utyp.idx() { return true @@ -2265,7 +2263,7 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok // same type -> already casted to the interface return true } - if inter_typ.idx() == table.error_type_idx && utyp.idx() == table.none_type_idx { + if inter_typ.idx() == ast.error_type_idx && utyp.idx() == ast.none_type_idx { // `none` "implements" the Error interface return true } @@ -2274,7 +2272,7 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok pos) } imethods := if inter_sym.kind == .interface_ { - (inter_sym.info as table.Interface).methods + (inter_sym.info as ast.Interface).methods } else { inter_sym.methods } @@ -2293,7 +2291,7 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok c.error("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`", pos) } - if mut inter_sym.info is table.Interface { + if mut inter_sym.info is ast.Interface { for ifield in inter_sym.info.fields { if field := c.table.find_field_with_embeds(typ_sym, ifield.name) { if ifield.typ != field.typ { @@ -2320,7 +2318,7 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok } // return the actual type of the expression, once the optional is handled -pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) table.Type { +pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Type { if expr is ast.CallExpr { if expr.return_type.has_flag(.optional) { if expr.or_block.kind == .absent { @@ -2345,7 +2343,7 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t return ret_type } -pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, expr_return_type table.Type) { +pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type ast.Type, expr_return_type ast.Type) { if or_expr.kind == .propagate { if !c.cur_fn.return_type.has_flag(.optional) && c.cur_fn.name != 'main.main' && !c.inside_const { @@ -2356,7 +2354,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex } stmts_len := or_expr.stmts.len if stmts_len == 0 { - if ret_type != table.void_type { + if ret_type != ast.void_type { // x := f() or {} c.error('assignment requires a non empty `or {}` block', or_expr.pos) return @@ -2365,13 +2363,13 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex return } last_stmt := or_expr.stmts[stmts_len - 1] - if ret_type != table.void_type { + if ret_type != ast.void_type { match last_stmt { ast.ExprStmt { c.expected_type = ret_type c.expected_or_type = ret_type.clear_flag(.optional) last_stmt_typ := c.expr(last_stmt.expr) - c.expected_or_type = table.void_type + c.expected_or_type = ast.void_type type_fits := c.check_types(last_stmt_typ, ret_type) && last_stmt_typ.nr_muls() == ret_type.nr_muls() is_panic_or_exit := is_expr_panic_or_exit(last_stmt.expr) @@ -2379,7 +2377,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex return } expected_type_name := c.table.type_to_str(ret_type.clear_flag(.optional)) - if last_stmt.typ == table.void_type { + if last_stmt.typ == ast.void_type { c.error('`or` block must provide a default value of type `$expected_type_name`, or return/exit/continue/break/panic', last_stmt.pos) } else { @@ -2407,7 +2405,7 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex } else { match last_stmt { ast.ExprStmt { - if last_stmt.typ == table.void_type { + if last_stmt.typ == ast.void_type { return } if is_expr_panic_or_exit(last_stmt.expr) { @@ -2434,7 +2432,7 @@ fn is_expr_panic_or_exit(expr ast.Expr) bool { } } -pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.Type { +pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Type { prevent_sum_type_unwrapping_once := c.prevent_sum_type_unwrapping_once c.prevent_sum_type_unwrapping_once = false @@ -2452,7 +2450,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T valid_generic := util.is_generic_type_name(name) && c.cur_fn.generic_params.filter(it.name == name).len != 0 if valid_generic { - name_type = table.Type(c.table.find_type_idx(name)).set_flag(.generic) + name_type = ast.Type(c.table.find_type_idx(name)).set_flag(.generic) } } // Note: in future typeof() should be a type known at compile-time @@ -2468,7 +2466,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T selector_expr.pos) } selector_expr.name_type = name_type - return table.string_type + return ast.string_type } // old_selector_expr := c.inside_selector_expr @@ -2477,9 +2475,9 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T c.inside_selector_expr = old_selector_expr // c.using_new_err_struct = using_new_err_struct_save - if typ == table.void_type_idx { + if typ == ast.void_type_idx { c.error('unknown selector expression', selector_expr.pos) - return table.void_type + return ast.void_type } selector_expr.expr_type = typ if selector_expr.expr_type.has_flag(.optional) && !((selector_expr.expr is ast.Ident @@ -2492,21 +2490,21 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T sym := c.table.get_type_symbol(utyp) if typ.has_flag(.variadic) || sym.kind == .array_fixed || sym.kind == .chan { if field_name == 'len' || (sym.kind == .chan && field_name == 'cap') { - selector_expr.typ = table.int_type - return table.int_type + selector_expr.typ = ast.int_type + return ast.int_type } if sym.kind == .chan && field_name == 'closed' { - selector_expr.typ = table.bool_type - return table.bool_type + selector_expr.typ = ast.bool_type + return ast.bool_type } } mut unknown_field_msg := 'type `$sym.name` has no field or method `$field_name`' mut has_field := false - mut field := table.Field{} - if field_name.len > 0 && field_name[0].is_capital() && sym.info is table.Struct + mut field := ast.StructField{} + if field_name.len > 0 && field_name[0].is_capital() && sym.info is ast.Struct && sym.language == .v { // x.Foo.y => access the embedded struct - sym_info := sym.info as table.Struct + sym_info := sym.info as ast.Struct for embed in sym_info.embeds { embed_sym := c.table.get_type_symbol(embed) if embed_sym.embed_name() == field_name { @@ -2520,9 +2518,9 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T field = f } else { // look for embedded field - if sym.info is table.Struct { - mut found_fields := []table.Field{} - mut embed_of_found_fields := []table.Type{} + if sym.info is ast.Struct { + mut found_fields := []ast.StructField{} + mut embed_of_found_fields := []ast.Type{} for embed in sym.info.embeds { embed_sym := c.table.get_type_symbol(embed) if f := c.table.find_field(embed_sym, field_name) { @@ -2543,7 +2541,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T } } if !c.inside_unsafe { - if sym.info is table.Struct { + if sym.info is ast.Struct { if sym.info.is_union && selector_expr.next_token !in token.assign_tokens { c.warn('reading a union field (or its address) requires `unsafe`', selector_expr.pos) @@ -2571,13 +2569,13 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T c.error('`$sym.name` has no property `$selector_expr.field_name`', selector_expr.pos) } } else { - if sym.info is table.Struct { + if sym.info is ast.Struct { suggestion := util.new_suggestion(field_name, sym.info.fields.map(it.name)) c.error(suggestion.say(unknown_field_msg), selector_expr.pos) } c.error(unknown_field_msg, selector_expr.pos) } - return table.void_type + return ast.void_type } // TODO: non deferred @@ -2585,10 +2583,10 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { c.expected_type = c.cur_fn.return_type expected_type := c.unwrap_generic(c.expected_type) expected_type_sym := c.table.get_type_symbol(expected_type) - if return_stmt.exprs.len > 0 && c.cur_fn.return_type == table.void_type { + if return_stmt.exprs.len > 0 && c.cur_fn.return_type == ast.void_type { c.error('unexpected argument, current function does not return anything', return_stmt.exprs[0].position()) return - } else if return_stmt.exprs.len == 0 && !(c.expected_type == table.void_type + } else if return_stmt.exprs.len == 0 && !(c.expected_type == ast.void_type || expected_type_sym.kind == .void) { stype := c.table.type_to_str(expected_type) arg := if expected_type_sym.kind == .multi_return { 'arguments' } else { 'argument' } @@ -2600,13 +2598,13 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { } exp_is_optional := expected_type.has_flag(.optional) mut expected_types := [expected_type] - if expected_type_sym.info is table.MultiReturn { + if expected_type_sym.info is ast.MultiReturn { expected_types = expected_type_sym.info.types if c.cur_generic_types.len > 0 { expected_types = expected_types.map(c.unwrap_generic(it)) } } - mut got_types := []table.Type{} + mut got_types := []ast.Type{} for expr in return_stmt.exprs { typ := c.expr(expr) // Unpack multi return types @@ -2622,7 +2620,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { return_stmt.types = got_types // allow `none` & `error` return types for function that returns optional if exp_is_optional - && got_types[0].idx() in [table.none_type_idx, table.error_type_idx, c.table.type_idxs['Option']] { + && got_types[0].idx() in [ast.none_type_idx, ast.error_type_idx, c.table.type_idxs['Option']] { return } if expected_types.len > 0 && expected_types.len != got_types.len { @@ -2662,7 +2660,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { pos) } if (exp_type.is_ptr() || exp_type.is_pointer()) - && (!got_typ.is_ptr() && !got_typ.is_pointer()) && got_typ != table.int_literal_type { + && (!got_typ.is_ptr() && !got_typ.is_pointer()) && got_typ != ast.int_literal_type { pos := return_stmt.exprs[i].position() if return_stmt.exprs[i].is_auto_deref_var() { continue @@ -2787,13 +2785,13 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) { } pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { - c.expected_type = table.none_type // TODO a hack to make `x := if ... work` + c.expected_type = ast.none_type // TODO a hack to make `x := if ... work` defer { - c.expected_type = table.void_type + c.expected_type = ast.void_type } right_first := assign_stmt.right[0] mut right_len := assign_stmt.right.len - mut right_type0 := table.void_type + mut right_type0 := ast.void_type for i, right in assign_stmt.right { if right is ast.CallExpr || right is ast.IfExpr || right is ast.LockExpr || right is ast.MatchExpr { @@ -2812,7 +2810,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } assign_stmt.right_types = right_type_sym.mr_info().types right_len = assign_stmt.right_types.len - } else if right_type == table.void_type { + } else if right_type == ast.void_type { right_len = 0 } } @@ -2835,7 +2833,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { left.pos) } is_blank_ident := left.is_blank_ident() - mut left_type := table.void_type + mut left_type := ast.void_type if !is_decl && !is_blank_ident { if left is ast.Ident || left is ast.SelectorExpr { c.prevent_sum_type_unwrapping_once = true @@ -2872,7 +2870,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } else { left_type = c.table.mktyp(right_type) } - if left_type == table.int_type { + if left_type == ast.int_type { if right is ast.IntegerLiteral { mut is_large := right.val.len > 13 if !is_large && right.val.len > 8 { @@ -3022,12 +3020,12 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { match assign_stmt.op { .assign {} // No need to do single side check for =. But here put it first for speed. .plus_assign, .minus_assign { - if left_type == table.string_type { + if left_type == ast.string_type { if assign_stmt.op != .plus_assign { c.error('operator `$assign_stmt.op` not defined on left operand type `$left_sym.name`', left.position()) } - if right_type != table.string_type { + if right_type != ast.string_type { c.error('invalid right operand: $left_sym.name $assign_stmt.op $right_sym.name', right.position()) } @@ -3158,7 +3156,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { // right_sym := c.table.get_type_symbol(right_type_unwrapped) } -fn scope_register_it(mut s ast.Scope, pos token.Position, typ table.Type) { +fn scope_register_it(mut s ast.Scope, pos token.Position, typ ast.Type) { s.register(ast.Var{ name: 'it' pos: pos @@ -3167,7 +3165,7 @@ fn scope_register_it(mut s ast.Scope, pos token.Position, typ table.Type) { }) } -fn scope_register_a_b(mut s ast.Scope, pos token.Position, typ table.Type) { +fn scope_register_a_b(mut s ast.Scope, pos token.Position, typ ast.Type) { s.register(ast.Var{ name: 'a' pos: pos @@ -3196,11 +3194,11 @@ pub fn (mut c Checker) ensure_sumtype_array_has_default_value(array_init ast.Arr } } -pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { +pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type { // println('checker: array init $array_init.pos.line_nr $c.file.path') - mut elem_type := table.void_type + mut elem_type := ast.void_type // []string - was set in parser - if array_init.typ != table.void_type { + if array_init.typ != ast.void_type { if array_init.exprs.len == 0 { if array_init.has_cap { c.check_array_init_para_type('cap', array_init.cap_expr, array_init.pos) @@ -3229,19 +3227,19 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { // a = [] if array_init.exprs.len == 0 { // a := fn_returing_opt_array() or { [] } - if c.expected_type == table.void_type && c.expected_or_type != table.void_type { + if c.expected_type == ast.void_type && c.expected_or_type != ast.void_type { c.expected_type = c.expected_or_type } mut type_sym := c.table.get_type_symbol(c.expected_type) if type_sym.kind != .array { c.error('array_init: no type specified (maybe: `[]Type{}` instead of `[]`)', array_init.pos) - return table.void_type + return ast.void_type } // TODO: seperate errors once bug is fixed with `x := if expr { ... } else { ... }` - // if c.expected_type == table.void_type { + // if c.expected_type == ast.void_type { // c.error('array_init: use `[]Type{}` instead of `[]`', array_init.pos) - // return table.void_type + // return ast.void_type // } array_info := type_sym.array_info() array_init.elem_type = array_info.elem_type @@ -3249,8 +3247,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { return c.expected_type.clear_flag(.optional) } // [1,2,3] - if array_init.exprs.len > 0 && array_init.elem_type == table.void_type { - mut expected_value_type := table.void_type + if array_init.exprs.len > 0 && array_init.elem_type == ast.void_type { + mut expected_value_type := ast.void_type mut expecting_interface_array := false if c.expected_type != 0 { expected_value_type = c.table.value_type(c.expected_type) @@ -3293,14 +3291,14 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { } if array_init.is_fixed { idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len) - array_init.typ = table.new_type(idx) + array_init.typ = ast.new_type(idx) } else { idx := c.table.find_or_register_array(elem_type) - array_init.typ = table.new_type(idx) + array_init.typ = ast.new_type(idx) } array_init.elem_type = elem_type } else if array_init.is_fixed && array_init.exprs.len == 1 - && array_init.elem_type != table.void_type { + && array_init.elem_type != ast.void_type { // [50]byte mut fixed_size := 0 init_expr := array_init.exprs[0] @@ -3331,7 +3329,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { c.error('fixed size cannot be zero or negative', init_expr.position()) } idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size) - array_type := table.new_type(idx) + array_type := ast.new_type(idx) array_init.typ = array_type if array_init.has_default { c.expr(array_init.default_expr) @@ -3399,7 +3397,7 @@ fn (mut c Checker) stmt(node ast.Stmt) { stmt_pos := node.pos eprintln('checking file: ${c.file.path:-30} | stmt pos: ${stmt_pos.str():-45} | stmt') } - // c.expected_type = table.void_type + // c.expected_type = ast.void_type match mut node { ast.EmptyStmt { print_backtrace() @@ -3446,10 +3444,10 @@ fn (mut c Checker) stmt(node ast.Stmt) { } ast.ExprStmt { node.typ = c.expr(node.expr) - c.expected_type = table.void_type - c.check_expr_opt_call(node.expr, table.void_type) + c.expected_type = ast.void_type + c.check_expr_opt_call(node.expr, ast.void_type) // TODO This should work, even if it's prolly useless .-. - // node.typ = c.check_expr_opt_call(node.expr, table.void_type) + // node.typ = c.check_expr_opt_call(node.expr, ast.void_type) } ast.FnDecl { c.fn_decl(mut node) @@ -3518,7 +3516,7 @@ fn (mut c Checker) stmt(node ast.Stmt) { fn (mut c Checker) assert_stmt(node ast.AssertStmt) { cur_exp_typ := c.expected_type assert_type := c.check_expr_opt_call(node.expr, c.expr(node.expr)) - if assert_type != table.bool_type_idx { + if assert_type != ast.bool_type_idx { atype_name := c.table.get_type_symbol(assert_type).name c.error('assert can be used only with `bool` expressions, but found `$atype_name` instead', node.pos) @@ -3578,13 +3576,13 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { if node.is_range { high_type := c.expr(node.high) high_type_idx := high_type.idx() - if typ_idx in table.integer_type_idxs && high_type_idx !in table.integer_type_idxs { + if typ_idx in ast.integer_type_idxs && high_type_idx !in ast.integer_type_idxs { c.error('range types do not match', node.cond.position()) - } else if typ_idx in table.float_type_idxs || high_type_idx in table.float_type_idxs { + } else if typ_idx in ast.float_type_idxs || high_type_idx in ast.float_type_idxs { c.error('range type can not be float', node.cond.position()) - } else if typ_idx == table.bool_type_idx || high_type_idx == table.bool_type_idx { + } else if typ_idx == ast.bool_type_idx || high_type_idx == ast.bool_type_idx { c.error('range type can not be bool', node.cond.position()) - } else if typ_idx == table.string_type_idx || high_type_idx == table.string_type_idx { + } else if typ_idx == ast.string_type_idx || high_type_idx == ast.string_type_idx { c.error('range type can not be string', node.cond.position()) } } else { @@ -3616,14 +3614,14 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { if node.key_var.len > 0 { key_type := match sym.kind { .map { sym.map_info().key_type } - else { table.int_type } + else { ast.int_type } } node.key_type = key_type node.scope.update_var_type(node.key_var, key_type) } mut value_type := c.table.value_type(typ) - if value_type == table.void_type || typ.has_flag(.optional) { - if typ != table.void_type { + if value_type == ast.void_type || typ.has_flag(.optional) { + if typ != ast.void_type { c.error('for in: cannot index `${c.table.type_to_str(typ)}`', node.cond.position()) } } @@ -3663,17 +3661,17 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { fn (mut c Checker) for_stmt(mut node ast.ForStmt) { c.in_for_count++ prev_loop_label := c.loop_label - c.expected_type = table.bool_type + c.expected_type = ast.bool_type typ := c.expr(node.cond) - if !node.is_inf && typ.idx() != table.bool_type_idx && !c.pref.translated { + if !node.is_inf && typ.idx() != ast.bool_type_idx && !c.pref.translated { c.error('non-bool used as for condition', node.pos) } if node.cond is ast.InfixExpr { infix := node.cond if infix.op == .key_is { if (infix.left is ast.Ident || infix.left is ast.SelectorExpr) - && infix.right is ast.Type { - right_expr := infix.right as ast.Type + && infix.right is ast.TypeNode { + right_expr := infix.right as ast.TypeNode is_variable := if mut infix.left is ast.Ident { infix.left.kind == .variable } else { @@ -3963,7 +3961,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) { mut unreachable := token.Position{ line_nr: -1 } - c.expected_type = table.void_type + c.expected_type = ast.void_type for stmt in stmts { if c.scope_returns { if unreachable.line_nr == -1 { @@ -3976,10 +3974,10 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) { c.error('unreachable code', unreachable) } c.scope_returns = false - c.expected_type = table.void_type + c.expected_type = ast.void_type } -pub fn (c &Checker) unwrap_generic(typ table.Type) table.Type { +pub fn (c &Checker) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) { sym := c.table.get_type_symbol(typ) for i, generic_param in c.cur_fn.generic_params { @@ -3992,14 +3990,14 @@ pub fn (c &Checker) unwrap_generic(typ table.Type) table.Type { } // TODO node must be mut -pub fn (mut c Checker) expr(node ast.Expr) table.Type { +pub fn (mut c Checker) expr(node ast.Expr) ast.Type { c.expr_level++ defer { c.expr_level-- } if c.expr_level > 200 { c.error('checker: too many expr levels: $c.expr_level ', node.position()) - return table.void_type + return ast.void_type } match mut node { ast.NodeError {} @@ -4025,9 +4023,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { type_sym := c.table.get_type_symbol(typ) if type_sym.kind != .array { c.error('decomposition can only be used on arrays', node.expr.position()) - return table.void_type + return ast.void_type } - array_info := type_sym.info as table.Array + array_info := type_sym.info as ast.Array elem_type := array_info.elem_type.set_flag(.variadic) node.expr_type = typ node.arg_type = elem_type @@ -4067,7 +4065,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { return v.typ } ast.BoolLiteral { - return table.bool_type + return ast.bool_type } ast.CastExpr { return c.cast_expr(mut node) @@ -4101,12 +4099,12 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { } ast.CharLiteral { // return int_literal, not rune, so that we can do "bytes << `A`" without a cast etc - // return table.int_literal_type - return table.rune_type - // return table.byte_type + // return ast.int_literal_type + return ast.rune_type + // return ast.byte_type } ast.Comment { - return table.void_type + return ast.void_type } ast.AtExpr { return c.at_expr(mut node) @@ -4118,7 +4116,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { node.left_type = c.unwrap_generic(c.expr(node.left)) expr_type := c.unwrap_generic(c.expr(node.field_expr)) expr_sym := c.table.get_type_symbol(expr_type) - if expr_type != table.string_type { + if expr_type != ast.string_type { c.error('expected `string` instead of `$expr_sym.name` (e.g. `field.name`)', node.field_expr.position()) } @@ -4136,16 +4134,16 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { } else { c.error('expected selector expression e.g. `$(field.name)`', node.field_expr.position()) } - return table.void_type + return ast.void_type } ast.ConcatExpr { return c.concat_expr(mut node) } ast.DumpExpr { node.expr_type = c.expr(node.expr) - if node.expr_type.idx() == table.void_type_idx { + if node.expr_type.idx() == ast.void_type_idx { c.error('dump expression can not be void', node.expr.position()) - return table.void_type + return ast.void_type } tsym := c.table.get_type_symbol(node.expr_type) c.table.dumps[int(node.expr_type)] = tsym.cname @@ -4156,7 +4154,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { return c.enum_val(mut node) } ast.FloatLiteral { - return table.float_literal_type + return ast.float_literal_type } ast.Ident { // c.checked_ident = node.name @@ -4190,7 +4188,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { c.error('expression should return an option', node.expr.position()) } } - return table.bool_type + return ast.bool_type } ast.IndexExpr { return c.index_expr(mut node) @@ -4199,7 +4197,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { return c.infix_expr(mut node) } ast.IntegerLiteral { - return table.int_literal_type + return ast.int_literal_type } ast.LockExpr { return c.lock_expr(mut node) @@ -4217,11 +4215,11 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { return c.prefix_expr(mut node) } ast.None { - return table.none_type + return ast.none_type } ast.OrExpr { // never happens - return table.void_type + return ast.void_type } // ast.OrExpr2 { // return node.typ @@ -4231,7 +4229,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { } ast.RangeExpr { // never happens - return table.void_type + return ast.void_type } ast.SelectExpr { return c.select_expr(mut node) @@ -4243,7 +4241,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { if !node.is_type { node.typ = c.expr(node.expr) } - return table.u32_type + return ast.u32_type } ast.OffsetOf { return c.offset_of(node) @@ -4253,9 +4251,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { } ast.StringLiteral { if node.language == .c { - return table.byteptr_type + return ast.byteptr_type } - return table.string_type + return ast.string_type } ast.StringInterLiteral { return c.string_inter_lit(mut node) @@ -4266,31 +4264,31 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { } return c.struct_init(mut node) } - ast.Type { + ast.TypeNode { return node.typ } ast.TypeOf { node.expr_type = c.expr(node.expr) - return table.string_type + return ast.string_type } ast.UnsafeExpr { return c.unsafe_expr(mut node) } ast.Likely { ltype := c.expr(node.expr) - if !c.check_types(ltype, table.bool_type) { + if !c.check_types(ltype, ast.bool_type) { ltype_sym := c.table.get_type_symbol(ltype) lname := if node.is_likely { '_likely_' } else { '_unlikely_' } c.error('`${lname}()` expects a boolean expression, instead it got `$ltype_sym.name`', node.pos) } - return table.bool_type + return ast.bool_type } } - return table.void_type + return ast.void_type } -// pub fn (mut c Checker) asm_reg(mut node ast.AsmRegister) table.Type { +// pub fn (mut c Checker) asm_reg(mut node ast.AsmRegister) ast.Type { // name := node.name // for bit_size, array in ast.x86_no_number_register_list { @@ -4304,17 +4302,17 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { // } // } // c.error('invalid register name: `$name`', node.pos) -// return table.void_type +// return ast.void_type // } -pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type { +pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { node.expr_type = c.expr(node.expr) // type to be casted from_type_sym := c.table.get_type_symbol(node.expr_type) to_type_sym := c.table.get_type_symbol(node.typ) // type to be used as cast if to_type_sym.language != .c { c.ensure_type_exists(node.typ, node.pos) or {} } - expr_is_ptr := node.expr_type.is_ptr() || node.expr_type.idx() in table.pointer_type_idxs + expr_is_ptr := node.expr_type.is_ptr() || node.expr_type.idx() in ast.pointer_type_idxs if expr_is_ptr && to_type_sym.kind == .string && !node.in_prexpr { if node.has_arg { c.warn('to convert a C string buffer pointer to a V string, please use x.vstring_with_len(len) instead of string(x,len)', @@ -4324,33 +4322,33 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type { node.pos) } } - if node.expr_type == table.byte_type && to_type_sym.kind == .string { + if node.expr_type == ast.byte_type && to_type_sym.kind == .string { c.error('can not cast type `byte` to string, use `${node.expr.str()}.str()` instead.', node.pos) } if to_type_sym.kind == .sum_type { - if node.expr_type in [table.int_literal_type, table.float_literal_type] { - node.expr_type = c.promote_num(node.expr_type, if node.expr_type == table.int_literal_type { - table.int_type + if node.expr_type in [ast.int_literal_type, ast.float_literal_type] { + node.expr_type = c.promote_num(node.expr_type, if node.expr_type == ast.int_literal_type { + ast.int_type } else { - table.f64_type + ast.f64_type }) } if !c.table.sumtype_has_variant(node.typ, node.expr_type) { c.error('cannot cast `$from_type_sym.name` to `$to_type_sym.name`', node.pos) } - } else if mut to_type_sym.info is table.Alias { + } else if mut to_type_sym.info is ast.Alias { if !c.check_types(node.expr_type, to_type_sym.info.parent_type) { parent_type_sym := c.table.get_type_symbol(to_type_sym.info.parent_type) c.error('cannot convert type `$from_type_sym.name` to `$to_type_sym.name` (alias to `$parent_type_sym.name`)', node.pos) } - } else if node.typ == table.string_type + } else if node.typ == ast.string_type && (from_type_sym.kind in [.int_literal, .int, .byte, .byteptr, .bool] || (from_type_sym.kind == .array && from_type_sym.name == 'array_byte')) { type_name := c.table.type_to_str(node.expr_type) c.error('cannot cast type `$type_name` to string, use `x.str()` instead', node.pos) - } else if node.expr_type == table.string_type { + } else if node.expr_type == ast.string_type { if to_type_sym.kind != .alias { mut error_msg := 'cannot cast a string' if mut node.expr is ast.StringLiteral { @@ -4360,19 +4358,19 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type { } c.error(error_msg, node.pos) } - } else if to_type_sym.kind == .byte && node.expr_type != table.voidptr_type + } else if to_type_sym.kind == .byte && node.expr_type != ast.voidptr_type && from_type_sym.kind != .enum_ && !node.expr_type.is_int() && !node.expr_type.is_float() && !node.expr_type.is_ptr() { type_name := c.table.type_to_str(node.expr_type) c.error('cannot cast type `$type_name` to `byte`', node.pos) } else if to_type_sym.kind == .struct_ && !node.typ.is_ptr() - && !(to_type_sym.info as table.Struct).is_typedef { + && !(to_type_sym.info as ast.Struct).is_typedef { // For now we ignore C typedef because of `C.Window(C.None)` in vlib/clipboard if from_type_sym.kind == .struct_ && !node.expr_type.is_ptr() { c.warn('casting to struct is deprecated, use e.g. `Struct{...expr}` instead', node.pos) - from_type_info := from_type_sym.info as table.Struct - to_type_info := to_type_sym.info as table.Struct + from_type_info := from_type_sym.info as ast.Struct + to_type_info := to_type_sym.info as ast.Struct if !c.check_struct_signature(from_type_info, to_type_info) { c.error('cannot convert struct `$from_type_sym.name` to struct `$to_type_sym.name`', node.pos) @@ -4383,9 +4381,9 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type { } } else if to_type_sym.kind == .interface_ { c.type_implements(node.expr_type, node.typ, node.pos) - } else if node.typ == table.bool_type { + } else if node.typ == ast.bool_type { c.error('cannot cast to bool - use e.g. `some_int != 0` instead', node.pos) - } else if node.expr_type == table.none_type { + } else if node.expr_type == ast.none_type { type_name := c.table.type_to_str(node.typ) c.error('cannot cast `none` to `$type_name`', node.pos) } else if from_type_sym.kind == .struct_ && !node.expr_type.is_ptr() { @@ -4411,15 +4409,15 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type { return node.typ } -fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) table.Type { +fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type { node.sym = c.table.get_type_symbol(c.unwrap_generic(c.expr(node.left))) if node.is_env { env_value := util.resolve_env_value("\$env('$node.args_var')", false) or { c.error(err.msg, node.env_pos) - return table.string_type + return ast.string_type } node.env_value = env_value - return table.string_type + return ast.string_type } if node.is_embed { c.file.embedded_files << node.embed_file @@ -4465,20 +4463,20 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) table.Type { node.args[i].typ = c.expr(arg.expr) } // assume string for now - return table.string_type + return ast.string_type } if node.is_vweb { - return table.string_type + return ast.string_type } // s.$my_str() v := node.scope.find_var(node.method_name) or { c.error('unknown identifier `$node.method_name`', node.method_pos) - return table.void_type + return ast.void_type } - if v.typ != table.string_type { - s := c.expected_msg(v.typ, table.string_type) + if v.typ != ast.string_type { + s := c.expected_msg(v.typ, ast.string_type) c.error('invalid string method call: $s', node.method_pos) - return table.void_type + return ast.void_type } // note: we should use a compile-time evaluation function rather than handle here // mut variables will not work after init @@ -4490,14 +4488,14 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) table.Type { } f := node.sym.find_method(method_name) or { c.error('could not find method `$method_name`', node.method_pos) - return table.void_type + return ast.void_type } // println(f.name + ' ' + c.table.type_to_str(f.return_type)) node.result_type = f.return_type return f.return_type } -fn (mut c Checker) at_expr(mut node ast.AtExpr) table.Type { +fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type { match node.kind { .fn_name { node.val = c.cur_fn.name.all_after_last('.') @@ -4558,10 +4556,10 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) table.Type { node.pos) } } - return table.string_type + return ast.string_type } -pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { +pub fn (mut c Checker) ident(mut ident ast.Ident) ast.Type { // TODO: move this if c.const_deps.len > 0 { mut name := ident.name @@ -4570,7 +4568,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { } if name == c.const_decl { c.error('cycle in constant `$c.const_decl`', ident.pos) - return table.void_type + return ast.void_type } c.const_deps << name } @@ -4578,7 +4576,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { if ident.tok_kind !in [.assign, .decl_assign] { c.error('undefined ident: `_` (may only be used in assignments)', ident.pos) } - return table.void_type + return ast.void_type } // second use if ident.kind in [.constant, .global, .variable] { @@ -4618,7 +4616,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { if mut obj.expr is ast.Ident { if obj.expr.kind == .unresolved { c.error('unresolved variable: `$ident.name`', ident.pos) - return table.void_type + return ast.void_type } } if mut obj.expr is ast.IfGuardExpr { @@ -4636,7 +4634,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { typ: typ is_optional: is_optional } - if typ == table.error_type && c.expected_type == table.string_type + if typ == ast.error_type && c.expected_type == ast.string_type && !c.using_new_err_struct && !c.inside_selector_expr && !c.inside_println_arg && !c.file.mod.name.contains('v.') && !c.is_builtin_mod { @@ -4644,7 +4642,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { c.warn('string errors are deprecated; use `err.msg` instead', ident.pos) } - // if typ == table.t_type { + // if typ == ast.t_type { // sym := c.table.get_type_symbol(c.cur_generic_type) // println('IDENT T unresolved $ident.name typ=$sym.name') // Got a var with type T, return current generic type @@ -4704,7 +4702,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { } // Non-anon-function object (not a call), e.g. `onclick(my_click)` if func := c.table.find_fn(name) { - fn_type := table.new_type(c.table.find_or_register_fn_type(ident.mod, func, + fn_type := ast.new_type(c.table.find_or_register_fn_type(ident.mod, func, false, true)) ident.name = name ident.kind = .function @@ -4716,9 +4714,9 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { } if ident.language == .c { if ident.name == 'C.NULL' { - return table.voidptr_type + return ast.voidptr_type } - return table.int_type + return ast.int_type } if c.inside_sql { if field := c.table.find_field(c.cur_orm_ts, ident.name) { @@ -4731,7 +4729,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { saved_mod := ident.mod ident.mod = 'builtin' builtin_type := c.ident(mut ident) - if builtin_type != table.void_type { + if builtin_type != ast.void_type { return builtin_type } ident.mod = saved_mod @@ -4745,13 +4743,13 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { } if c.table.known_type(ident.name) { // e.g. `User` in `json.decode(User, '...')` - return table.void_type + return ast.void_type } - return table.void_type + return ast.void_type } -pub fn (mut c Checker) concat_expr(mut concat_expr ast.ConcatExpr) table.Type { - mut mr_types := []table.Type{} +pub fn (mut c Checker) concat_expr(mut concat_expr ast.ConcatExpr) ast.Type { + mut mr_types := []ast.Type{} for expr in concat_expr.vals { mr_types << c.expr(expr) } @@ -4761,27 +4759,27 @@ pub fn (mut c Checker) concat_expr(mut concat_expr ast.ConcatExpr) table.Type { return typ } else { typ := c.table.find_or_register_multi_return(mr_types) - table.new_type(typ) + ast.new_type(typ) concat_expr.return_type = typ return typ } } -pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { - node.is_expr = c.expected_type != table.void_type +pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { + node.is_expr = c.expected_type != ast.void_type node.expected_type = c.expected_type cond_type := c.expr(node.cond) // we setting this here rather than at the end of the method // since it is used in c.match_exprs() it saves checking twice node.cond_type = c.table.mktyp(cond_type) - c.ensure_type_exists(node.cond_type, node.pos) or { return table.void_type } + c.ensure_type_exists(node.cond_type, node.pos) or { return ast.void_type } cond_type_sym := c.table.get_type_symbol(cond_type) if cond_type_sym.kind !in [.interface_, .sum_type] { node.is_sum_type = false } c.match_exprs(mut node, cond_type_sym) c.expected_type = cond_type - mut ret_type := table.void_type + mut ret_type := ast.void_type mut nbranches_with_return := 0 mut nbranches_without_return := 0 for branch in node.branches { @@ -4802,7 +4800,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { match mut stmt { ast.ExprStmt { expr_type := c.expr(stmt.expr) - if ret_type == table.void_type { + if ret_type == ast.void_type { ret_type = expr_type stmt.typ = ret_type } else if node.is_expr && ret_type != expr_type { @@ -4841,21 +4839,21 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { c.returns = false } } - // if ret_type != table.void_type { - // node.is_expr = c.expected_type != table.void_type + // if ret_type != ast.void_type { + // node.is_expr = c.expected_type != ast.void_type // node.expected_type = c.expected_type // } node.return_type = ret_type return ret_type } -fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeSymbol) { +fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSymbol) { // branch_exprs is a histogram of how many times // an expr was used in the match mut branch_exprs := map[string]int{} for branch_i, _ in node.branches { mut branch := node.branches[branch_i] - mut expr_types := []ast.Type{} + mut expr_types := []ast.TypeNode{} for expr in branch.exprs { mut key := '' if expr is ast.RangeExpr { @@ -4898,7 +4896,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS continue } match expr { - ast.Type { + ast.TypeNode { key = c.table.type_to_str(expr.typ) expr_types << expr } @@ -4927,7 +4925,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS // c.type_implements(expr_type, c.expected_type, expr.position()) expr_pos := expr.position() c.type_implements(expr_type, c.expected_type, expr_pos) - } else if mut cond_type_sym.info is table.SumType { + } else if mut cond_type_sym.info is ast.SumType { if expr_type !in cond_type_sym.info.variants { expr_str := c.table.type_to_str(expr_type) expect_str := c.table.type_to_str(node.cond_type) @@ -4943,7 +4941,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS // when match is sum type matching, then register smart cast for every branch if expr_types.len > 0 { if cond_type_sym.kind == .sum_type { - mut expr_type := table.Type(0) + mut expr_type := ast.Type(0) if expr_types.len > 1 { mut agg_name := strings.new_builder(20) mut agg_cname := strings.new_builder(20) @@ -4964,12 +4962,12 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS if existing_idx > 0 { expr_type = existing_idx } else { - expr_type = c.table.register_type_symbol(table.TypeSymbol{ + expr_type = c.table.register_type_symbol(ast.TypeSymbol{ name: name cname: agg_cname.str() kind: .aggregate mod: c.mod - info: table.Aggregate{ + info: ast.Aggregate{ types: expr_types.map(it.typ) } }) @@ -4987,7 +4985,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS // by listing all variants or values mut is_exhaustive := true mut unhandled := []string{} - if node.cond_type == table.bool_type { + if node.cond_type == ast.bool_type { variants := ['true', 'false'] for v in variants { if v !in branch_exprs { @@ -4997,7 +4995,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS } } else { match mut cond_type_sym.info { - table.SumType { + ast.SumType { for v in cond_type_sym.info.variants { v_str := c.table.type_to_str(v) if v_str !in branch_exprs { @@ -5007,7 +5005,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS } } // - table.Enum { + ast.Enum { for v in cond_type_sym.info.vals { if v !in branch_exprs { is_exhaustive = false @@ -5058,11 +5056,11 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym table.TypeS } // smartcast takes the expression with the current type which should be smartcasted to the target type in the given scope -fn (c &Checker) smartcast_sumtype(expr ast.Expr, cur_type table.Type, to_type table.Type, mut scope ast.Scope) { +fn (c &Checker) smartcast_sumtype(expr ast.Expr, cur_type ast.Type, to_type ast.Type, mut scope ast.Scope) { match mut expr { ast.SelectorExpr { mut is_mut := false - mut sum_type_casts := []table.Type{} + mut sum_type_casts := []ast.Type{} expr_sym := c.table.get_type_symbol(expr.expr_type) mut orig_type := 0 if field := c.table.find_field(expr_sym, expr.field_name) { @@ -5094,7 +5092,7 @@ fn (c &Checker) smartcast_sumtype(expr ast.Expr, cur_type table.Type, to_type ta } ast.Ident { mut is_mut := false - mut sum_type_casts := []table.Type{} + mut sum_type_casts := []ast.Type{} mut is_already_casted := false mut orig_type := 0 if mut expr.obj is ast.Var { @@ -5123,8 +5121,8 @@ fn (c &Checker) smartcast_sumtype(expr ast.Expr, cur_type table.Type, to_type ta } } -pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) table.Type { - node.is_expr = c.expected_type != table.void_type +pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type { + node.is_expr = c.expected_type != ast.void_type node.expected_type = c.expected_type for branch in node.branches { c.stmt(branch.stmt) @@ -5178,10 +5176,10 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) table.Type { } c.stmts(branch.stmts) } - return table.bool_type + return ast.bool_type } -pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) table.Type { +pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type { if c.rlocked_names.len > 0 || c.locked_names.len > 0 { c.error('nested `lock`/`rlock` not allowed', node.pos) } @@ -5210,21 +5208,21 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) table.Type { c.rlocked_names = [] c.locked_names = [] // handle `x := rlock a { a.getval() }` - mut ret_type := table.void_type + mut ret_type := ast.void_type if node.stmts.len > 0 { last_stmt := node.stmts[node.stmts.len - 1] if last_stmt is ast.ExprStmt { ret_type = last_stmt.typ } } - if ret_type != table.void_type { + if ret_type != ast.void_type { node.is_expr = true } node.typ = ret_type return ret_type } -pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) table.Type { +pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) ast.Type { assert !c.inside_unsafe c.inside_unsafe = true t := c.expr(node.expr) @@ -5232,11 +5230,11 @@ pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) table.Type { return t } -pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { +pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { if_kind := if node.is_comptime { '\$if' } else { 'if' } - expr_required := c.expected_type != table.void_type + expr_required := c.expected_type != ast.void_type former_expected_type := c.expected_type - node.typ = table.void_type + node.typ = ast.void_type mut nbranches_with_return := 0 mut nbranches_without_return := 0 mut should_skip := false // Whether the current branch should be skipped @@ -5253,9 +5251,9 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { should_skip = c.comp_if_branch(branch.cond, branch.pos) } else { // check condition type is boolean - c.expected_type = table.bool_type + c.expected_type = ast.bool_type cond_typ := c.expr(branch.cond) - if cond_typ.idx() != table.bool_type_idx && !c.pref.translated { + if cond_typ.idx() != ast.bool_type_idx && !c.pref.translated { typ_sym := c.table.get_type_symbol(cond_typ) c.error('non-bool type `$typ_sym.name` used as if condition', branch.cond.position()) } @@ -5266,11 +5264,11 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { mut comptime_field_name := '' if branch.cond is ast.InfixExpr { if branch.cond.op == .key_is { - if branch.cond.right !is ast.Type { + if branch.cond.right !is ast.TypeNode { c.error('invalid `\$if` condition: expected a type', branch.cond.right.position()) return 0 } - got_type := c.unwrap_generic((branch.cond.right as ast.Type).typ) + got_type := c.unwrap_generic((branch.cond.right as ast.TypeNode).typ) sym := c.table.get_type_symbol(got_type) if sym.kind == .placeholder || got_type.has_flag(.generic) { c.error('unknown type `$sym.name`', branch.cond.right.position()) @@ -5280,7 +5278,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { comptime_field_name = left.expr.str() c.comptime_fields_type[comptime_field_name] = got_type is_comptime_type_is_expr = true - } else if left is ast.Type { + } else if left is ast.TypeNode { is_comptime_type_is_expr = true left_type := c.unwrap_generic(left.typ) if left_type != got_type { @@ -5312,7 +5310,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { pos := branch.cond.position() if branch.cond is ast.InfixExpr { if branch.cond.op == .key_is { - right_expr := branch.cond.right as ast.Type + right_expr := branch.cond.right as ast.TypeNode left_sym := c.table.get_type_symbol(branch.cond.left_type) expr_type := c.expr(branch.cond.left) if left_sym.kind == .interface_ { @@ -5323,7 +5321,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { c.error('cannot use type `$expect_str` as type `$expr_str`', pos) } if (branch.cond.left is ast.Ident || branch.cond.left is ast.SelectorExpr) - && branch.cond.right is ast.Type { + && branch.cond.right is ast.TypeNode { is_variable := if mut branch.cond.left is ast.Ident { branch.cond.left.kind == .variable } else { @@ -5335,7 +5333,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { // TODO: rewrite interface smartcast left := branch.cond.left as ast.Ident mut is_mut := false - mut sum_type_casts := []table.Type{} + mut sum_type_casts := []ast.Type{} if v := branch.scope.find_var(left.name) { is_mut = v.is_mut sum_type_casts << v.sum_type_casts @@ -5366,14 +5364,14 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { mut last_expr := branch.stmts[branch.stmts.len - 1] as ast.ExprStmt c.expected_type = former_expected_type if c.expected_type.has_flag(.optional) { - if node.typ == table.void_type { + if node.typ == ast.void_type { node.is_expr = true node.typ = c.expected_type } continue } if c.expected_type.has_flag(.generic) { - if node.typ == table.void_type { + if node.typ == ast.void_type { node.is_expr = true node.typ = c.unwrap_generic(c.expected_type) } @@ -5381,13 +5379,13 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { } last_expr.typ = c.expr(last_expr.expr) if !c.check_types(last_expr.typ, node.typ) { - if node.typ == table.void_type { + if node.typ == ast.void_type { // first branch of if expression node.is_expr = true node.typ = last_expr.typ continue - } else if node.typ in [table.float_literal_type, table.int_literal_type] { - if node.typ == table.int_literal_type { + } else if node.typ in [ast.float_literal_type, ast.int_literal_type] { + if node.typ == ast.int_literal_type { if last_expr.typ.is_int() || last_expr.typ.is_float() { node.typ = last_expr.typ continue @@ -5399,8 +5397,8 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { } } } - if last_expr.typ in [table.float_literal_type, table.int_literal_type] { - if last_expr.typ == table.int_literal_type { + if last_expr.typ in [ast.float_literal_type, ast.int_literal_type] { + if last_expr.typ == ast.int_literal_type { if node.typ.is_int() || node.typ.is_float() { continue } @@ -5446,10 +5444,10 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { } } // if only untyped literals were given default to int/f64 - if node.typ == table.int_literal_type { - node.typ = table.int_type - } else if node.typ == table.float_literal_type { - node.typ = table.f64_type + if node.typ == ast.int_literal_type { + node.typ = ast.int_type + } else if node.typ == ast.float_literal_type { + node.typ = ast.f64_type } if expr_required && !node.has_else { d := if node.is_comptime { '$' } else { '' } @@ -5497,7 +5495,7 @@ fn (mut c Checker) comp_if_branch(cond ast.Expr, pos token.Position) bool { return l && r // skip (return true) only if both should be skipped } .key_is, .not_is { - if cond.left is ast.SelectorExpr || cond.left is ast.Type { + if cond.left is ast.SelectorExpr || cond.left is ast.TypeNode { // $if method.@type is string c.expr(cond.left) return false @@ -5568,7 +5566,7 @@ fn (mut c Checker) comp_if_branch(cond ast.Expr, pos token.Position) bool { c.error(err.msg, cond.pos) return false } - if !c.check_types(typ, table.bool_type) { + if !c.check_types(typ, ast.bool_type) { type_name := c.table.type_to_str(typ) c.error('non-bool type `$type_name` used as \$if condition', cond.pos) } @@ -5637,7 +5635,7 @@ fn (c &Checker) has_return(stmts []ast.Stmt) ?bool { return none } -pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) table.Type { +pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type { typ := c.expr(node.expr) typ_sym := c.table.get_type_symbol(typ) is_non_void_pointer := (typ.is_ptr() || typ.is_pointer()) && typ_sym.kind != .voidptr @@ -5653,7 +5651,7 @@ pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) table.Type { return typ } -pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) table.Type { +pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type { old_inside_ref_lit := c.inside_ref_lit c.inside_ref_lit = c.inside_ref_lit || node.op == .amp right_type := c.expr(node.right) @@ -5710,7 +5708,7 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) table.Type { if node.op == .bit_not && !right_type.is_int() && !c.pref.translated { c.error('operator ~ only defined on int types', node.pos) } - if node.op == .not && right_type != table.bool_type_idx && !c.pref.translated { + if node.op == .not && right_type != ast.bool_type_idx && !c.pref.translated { c.error('! operator can only be used with bool types', node.pos) } if node.op == .arrow { @@ -5725,10 +5723,10 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) table.Type { return right_type } -fn (mut c Checker) check_index(typ_sym &table.TypeSymbol, index ast.Expr, index_type table.Type, pos token.Position, range_index bool) { +fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_type ast.Type, pos token.Position, range_index bool) { index_type_sym := c.table.get_type_symbol(index_type) // println('index expr left=$typ_sym.name $node.pos.line_nr') - // if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) && + // if typ_sym.kind == .array && (!(ast.type_idx(index_type) in ast.number_type_idxs) && // index_type_sym.kind != .enum_) { if typ_sym.kind in [.array, .array_fixed, .string, .ustring] { if !(index_type.is_int() || index_type_sym.kind == .enum_) { @@ -5744,7 +5742,7 @@ fn (mut c Checker) check_index(typ_sym &table.TypeSymbol, index ast.Expr, index_ c.error('negative index `$index.val`', index.pos) } else if typ_sym.kind == .array_fixed { i := index.val.int() - info := typ_sym.info as table.ArrayFixed + info := typ_sym.info as ast.ArrayFixed if (!range_index && i >= info.size) || (range_index && i > info.size) { c.error('index out of range (index: $i, len: $info.size)', index.pos) } @@ -5761,7 +5759,7 @@ fn (mut c Checker) check_index(typ_sym &table.TypeSymbol, index ast.Expr, index_ } } -pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { +pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { mut typ := c.expr(node.left) node.left_type = typ typ_sym := c.table.get_final_type_symbol(typ) @@ -5778,7 +5776,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { else {} } if typ_sym.kind !in [.array, .array_fixed, .string, .map] && !typ.is_ptr() - && typ !in [table.byteptr_type, table.charptr_type] && !typ.has_flag(.variadic) { + && typ !in [ast.byteptr_type, ast.charptr_type] && !typ.has_flag(.variadic) { c.error('type `$typ_sym.name` does not support indexing', node.pos) } if typ_sym.kind == .string && !typ.is_ptr() && node.is_setter { @@ -5813,14 +5811,14 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { if typ_sym.kind == .array_fixed { elem_type := c.table.value_type(typ) idx := c.table.find_or_register_array(elem_type) - typ = table.new_type(idx) + typ = ast.new_type(idx) } else { typ = typ.set_nr_muls(0) } } else { // [1] index_type := c.expr(node.index) if typ_sym.kind == .map { - info := typ_sym.info as table.Map + info := typ_sym.info as ast.Map if !c.check_types(index_type, info.key_type) { err := c.expected_msg(index_type, info.key_type) c.error('invalid key: $err', node.pos) @@ -5829,7 +5827,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { c.check_index(typ_sym, node.index, index_type, node.pos, false) } value_type := c.table.value_type(typ) - if value_type != table.void_type { + if value_type != ast.void_type { typ = value_type } } @@ -5840,7 +5838,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { // `.green` or `Color.green` // If a short form is used, `expected_type` needs to be an enum // with this value. -pub fn (mut c Checker) enum_val(mut node ast.EnumVal) table.Type { +pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type { typ_idx := if node.enum_name == '' { c.expected_type.idx() } else { // @@ -5849,35 +5847,35 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) table.Type { // println('checker: enum_val: $node.enum_name typeidx=$typ_idx') if typ_idx == 0 { c.error('not an enum (name=$node.enum_name) (type_idx=0)', node.pos) - return table.void_type + return ast.void_type } - mut typ := table.new_type(typ_idx) + mut typ := ast.new_type(typ_idx) if c.pref.translated { // TODO make more strict node.typ = typ return typ } - if typ == table.void_type { + if typ == ast.void_type { c.error('not an enum', node.pos) - return table.void_type + return ast.void_type } mut typ_sym := c.table.get_type_symbol(typ) // println('tname=$typ_sym.name $node.pos.line_nr $c.file.path') if typ_sym.kind == .array && node.enum_name.len == 0 { - array_info := typ_sym.info as table.Array + array_info := typ_sym.info as ast.Array typ = array_info.elem_type typ_sym = c.table.get_type_symbol(typ) } if typ_sym.kind != .enum_ && !c.pref.translated { // TODO in C int fields can be compared to enums, need to handle that in C2V c.error('expected type is not an enum (`$typ_sym.name`)', node.pos) - return table.void_type + return ast.void_type } - if typ_sym.info !is table.Enum { + if typ_sym.info !is ast.Enum { c.error('not an enum', node.pos) - return table.void_type + return ast.void_type } - // info := typ_sym.info as table.Enum + // info := typ_sym.info as ast.Enum info := typ_sym.enum_info() // rintln('checker: x = $info.x enum val $c.expected_type $typ_sym.name') // println(info.vals) @@ -5890,7 +5888,7 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) table.Type { return typ } -pub fn (mut c Checker) chan_init(mut node ast.ChanInit) table.Type { +pub fn (mut c Checker) chan_init(mut node ast.ChanInit) ast.Type { if node.typ != 0 { info := c.table.get_type_symbol(node.typ).chan_info() node.elem_type = info.elem_type @@ -5904,16 +5902,16 @@ pub fn (mut c Checker) chan_init(mut node ast.ChanInit) table.Type { } } -pub fn (mut c Checker) offset_of(node ast.OffsetOf) table.Type { +pub fn (mut c Checker) offset_of(node ast.OffsetOf) ast.Type { sym := c.table.get_final_type_symbol(node.struct_type) if sym.kind != .struct_ { c.error('first argument of __offsetof must be struct', node.pos) - return table.u32_type + return ast.u32_type } if !c.table.struct_has_field(sym, node.field) { c.error('struct `$sym.name` has no field called `$node.field`', node.pos) } - return table.u32_type + return ast.u32_type } pub fn (mut c Checker) check_dup_keys(node &ast.MapInit, i int) { @@ -5939,7 +5937,7 @@ pub fn (mut c Checker) check_dup_keys(node &ast.MapInit, i int) { } } -pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type { +pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type { // `map = {}` if node.keys.len == 0 && node.vals.len == 0 && node.typ == 0 { sym := c.table.get_type_symbol(c.expected_type) @@ -5997,7 +5995,7 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type { c.check_dup_keys(node, i) } } - map_type := table.new_type(c.table.find_or_register_map(key0_type, val0_type)) + map_type := ast.new_type(c.table.find_or_register_map(key0_type, val0_type)) node.typ = map_type node.key_type = key0_type node.value_type = val0_type @@ -6029,7 +6027,7 @@ pub fn (mut c Checker) error(message string, pos token.Position) { } // check `to` has all fields of `from` -fn (c &Checker) check_struct_signature(from table.Struct, to table.Struct) bool { +fn (c &Checker) check_struct_signature(from ast.Struct, to ast.Struct) bool { // Note: `to` can have extra fields if from.fields.len == 0 { return false @@ -6123,15 +6121,15 @@ fn (c &Checker) fileis(s string) bool { return c.file.path.contains(s) } -fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type { +fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type { c.inside_sql = true defer { c.inside_sql = false } sym := c.table.get_type_symbol(node.table_expr.typ) - c.ensure_type_exists(node.table_expr.typ, node.pos) or { return table.void_type } + c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type } c.cur_orm_ts = sym - info := sym.info as table.Struct + info := sym.info as ast.Struct fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, sym.name) mut sub_structs := map[int]ast.SqlExpr{} for f in fields.filter(c.table.type_symbols[int(it.typ)].kind == .struct_) { @@ -6140,7 +6138,7 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type { has_where: true typ: f.typ db_expr: node.db_expr - table_expr: ast.Type{ + table_expr: ast.TypeNode{ pos: node.table_expr.pos typ: f.typ } @@ -6170,11 +6168,11 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type { is_mut: false scope: c.fn_scope info: ast.IdentVar{ - typ: table.int_type + typ: ast.int_type } } - left_type: table.int_type - right_type: table.int_type + left_type: ast.int_type + right_type: ast.int_type auto_locked: '' or_block: ast.OrExpr{} } @@ -6199,15 +6197,15 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type { return node.typ } -fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) table.Type { +fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type { c.inside_sql = true defer { c.inside_sql = false } - c.ensure_type_exists(node.table_expr.typ, node.pos) or { return table.void_type } + c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type } table_sym := c.table.get_type_symbol(node.table_expr.typ) c.cur_orm_ts = table_sym - info := table_sym.info as table.Struct + info := table_sym.info as ast.Struct fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, table_sym.name) mut sub_structs := map[int]ast.SqlStmt{} for f in fields.filter(c.table.type_symbols[int(it.typ)].kind == .struct_) { @@ -6215,7 +6213,7 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) table.Type { pos: node.pos db_expr: node.db_expr kind: node.kind - table_expr: ast.Type{ + table_expr: ast.TypeNode{ pos: node.table_expr.pos typ: f.typ } @@ -6238,15 +6236,15 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) table.Type { c.expr(node.where_expr) } - return table.void_type + return ast.void_type } -fn (mut c Checker) fetch_and_verify_orm_fields(info table.Struct, pos token.Position, table_name string) []table.Field { - fields := info.fields.filter((it.typ in [table.string_type, table.int_type, table.bool_type] +fn (mut c Checker) fetch_and_verify_orm_fields(info ast.Struct, pos token.Position, table_name string) []ast.StructField { + fields := info.fields.filter((it.typ in [ast.string_type, ast.int_type, ast.bool_type] || c.table.type_symbols[int(it.typ)].kind == .struct_) && !it.attrs.contains('skip')) if fields.len == 0 { c.error('V orm: select: empty fields in `$table_name`', pos) - return []table.Field{} + return []ast.StructField{} } if fields[0].name != 'id' { c.error('V orm: `id int` must be the first field in `$table_name`', pos) @@ -6293,7 +6291,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { if node.name == 'main.main' { c.main_fn_decl_node = node } - if node.return_type != table.void_type { + if node.return_type != ast.void_type { for attr in node.attrs { if attr.is_comptime_define { c.error('only functions that do NOT return values can have `[if $attr.name]` tags', @@ -6319,8 +6317,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { } // make sure interface does not implement its own interface methods if sym.kind == .interface_ && sym.has_method(node.name) { - if sym.info is table.Interface { - info := sym.info as table.Interface + if sym.info is ast.Interface { + info := sym.info as ast.Interface // if the method is in info.methods then it is an interface method if info.has_method(node.name) { c.error('interface `$sym.name` cannot implement its own interface method `$node.name`', @@ -6342,14 +6340,14 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { if node.is_pub { c.error('fn `init` must not be public', node.pos) } - if node.return_type != table.void_type { + if node.return_type != ast.void_type { c.error('fn `init` cannot have a return type', node.pos) } } - if node.return_type != table.Type(0) { + if node.return_type != ast.Type(0) { c.ensure_type_exists(node.return_type, node.pos) or { return } if node.language == .v && node.is_method && node.name == 'str' { - if node.return_type != table.string_type { + if node.return_type != ast.string_type { c.error('.str() methods should return `string`', node.pos) } if node.params.len != 1 { @@ -6375,7 +6373,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { } else if node.receiver.typ != node.params[1].typ { c.error('expected `$receiver_sym.name` not `$param_sym.name` - both operands must be the same type for operator overloading', node.params[1].type_pos) - } else if node.name in ['<', '=='] && node.return_type != table.bool_type { + } else if node.name in ['<', '=='] && node.return_type != ast.bool_type { c.error('operator comparison methods should return `bool`', node.pos) } else if parent_sym.is_primitive() { c.error('cannot define operator methods on type alias for `$parent_sym.name`', @@ -6397,16 +6395,16 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { } } } - if node.return_type != table.void_type_idx - && node.return_type.clear_flag(.optional) != table.void_type_idx { + if node.return_type != ast.void_type_idx + && node.return_type.clear_flag(.optional) != ast.void_type_idx { c.error('test functions should either return nothing at all, or be marked to return `?`', node.pos) } } - c.expected_type = table.void_type + c.expected_type = ast.void_type c.cur_fn = node // Add return if `fn(...) ? {...}` have no return at end - if node.return_type != table.void_type && node.return_type.has_flag(.optional) + if node.return_type != ast.void_type && node.return_type.has_flag(.optional) && (node.stmts.len == 0 || node.stmts[node.stmts.len - 1] !is ast.Return) { sym := c.table.get_type_symbol(node.return_type) if sym.kind == .void { @@ -6418,8 +6416,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.fn_scope = node.scope c.stmts(node.stmts) node.has_return = c.returns || has_top_return(node.stmts) - if node.language == .v && !node.no_body && node.return_type != table.void_type - && !node.has_return && node.name !in ['panic', 'exit'] { + if node.language == .v && !node.no_body && node.return_type != ast.void_type && !node.has_return + && node.name !in ['panic', 'exit'] { if c.inside_anon_fn { c.error('missing return at the end of an anonymous function', node.pos) } else { @@ -6449,7 +6447,7 @@ fn has_top_return(stmts []ast.Stmt) bool { return false } -fn (mut c Checker) verify_vweb_params_for_method(m table.Fn) (bool, int, int) { +fn (mut c Checker) verify_vweb_params_for_method(m ast.Fn) (bool, int, int) { margs := m.params.len - 1 // first arg is the receiver/this if m.attrs.len == 0 { // allow non custom routed methods, with 1:1 mapping @@ -6497,7 +6495,7 @@ fn (mut c Checker) trace(fbase string, message string) { } } -fn (mut c Checker) ensure_type_exists(typ table.Type, pos token.Position) ? { +fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Position) ? { if typ == 0 { c.error('unknown type', pos) } @@ -6524,10 +6522,10 @@ fn (mut c Checker) ensure_type_exists(typ table.Type, pos token.Position) ? { } } .array { - c.ensure_type_exists((sym.info as table.Array).elem_type, pos) ? + c.ensure_type_exists((sym.info as ast.Array).elem_type, pos) ? } .map { - info := sym.info as table.Map + info := sym.info as ast.Map c.ensure_type_exists(info.key_type, pos) ? c.ensure_type_exists(info.value_type, pos) ? } diff --git a/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out b/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out index c17d271954..3b8aae98fe 100644 --- a/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out +++ b/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.out @@ -1,8 +1,7 @@ vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv:12:7: error: possible type mismatch of compared values of `==` operation - 10 | x := ityp == table.string_type + 10 | x := ityp == ast.string_type 11 | // the next line should produce at least a warning, or even an error, without an explicit cast: - 12 | z := isym == table.string_type - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + 12 | z := isym == ast.string_type + | ~~~~~~~~~~~~~~~~~~~~~~~ 13 | println(typeof(isym).name) - 14 | println(typeof(table.string_type).name) - + 14 | println(typeof(ast.string_type).name) diff --git a/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv b/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv index 432b21c541..6a307d38f8 100644 --- a/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv +++ b/vlib/v/checker/tests/comparing_typesymbol_to_a_type_should_not_compile.vv @@ -1,17 +1,17 @@ -import v.table +import v.ast fn main() { - t := table.new_table() - ityp := table.int_type + t := ast.new_table() + ityp := ast.int_type isym := t.get_type_symbol(ityp) println(ityp.debug()) println(isym) println(isym.debug()) - x := ityp == table.string_type + x := ityp == ast.string_type // the next line should produce at least a warning, or even an error, without an explicit cast: - z := isym == table.string_type + z := isym == ast.string_type println(typeof(isym).name) - println(typeof(table.string_type).name) + println(typeof(ast.string_type).name) println(x) println(z) } diff --git a/vlib/v/doc/doc.v b/vlib/v/doc/doc.v index 585caa9733..031e82483c 100644 --- a/vlib/v/doc/doc.v +++ b/vlib/v/doc/doc.v @@ -8,7 +8,6 @@ import v.fmt import v.parser import v.pref import v.scanner -import v.table import v.token // SymbolKind categorizes the symbols it documents. @@ -92,7 +91,7 @@ pub struct Doc { pub mut: prefs &pref.Preferences = new_vdoc_preferences() base_path string - table &table.Table = &table.Table{} + table &ast.Table = &ast.Table{} checker checker.Checker = checker.Checker{ table: 0 cur_fn: 0 @@ -152,7 +151,7 @@ pub fn new_vdoc_preferences() &pref.Preferences { pub fn new(input_path string) Doc { mut d := Doc{ base_path: os.real_path(input_path) - table: table.new_table() + table: ast.new_table() head: DocNode{} contents: map[string]DocNode{} time_generated: time.now() diff --git a/vlib/v/doc/doc_test.v b/vlib/v/doc/doc_test.v index a9c9ab7d28..cdb0ef8329 100644 --- a/vlib/v/doc/doc_test.v +++ b/vlib/v/doc/doc_test.v @@ -1,4 +1,4 @@ -// import v.table +// import v.ast import v.doc // fn test_generate_with_pos() {} diff --git a/vlib/v/doc/module.v b/vlib/v/doc/module.v index 025d78508b..2e3f10c2b9 100644 --- a/vlib/v/doc/module.v +++ b/vlib/v/doc/module.v @@ -1,9 +1,8 @@ module doc import os -import v.table -import v.parser import v.ast +import v.parser import v.pref // get_parent_mod returns the parent mod name, in dot format. @@ -40,7 +39,7 @@ fn get_parent_mod(input_dir string) ?string { } return error('No V files found.') } - tbl := table.new_table() + tbl := ast.new_table() scope := &ast.Scope{ parent: 0 } diff --git a/vlib/v/doc/utils.v b/vlib/v/doc/utils.v index 1c75cc6770..ee74113853 100644 --- a/vlib/v/doc/utils.v +++ b/vlib/v/doc/utils.v @@ -3,7 +3,6 @@ module doc import strings import v.ast import v.token -import v.table // merge_comments merges all the comment contents into a single text. pub fn merge_comments(comments []ast.Comment) string { @@ -140,9 +139,9 @@ pub fn (d Doc) stmt_pub(stmt ast.Stmt) bool { } } -// type_to_str is a wrapper function around `fmt.table.type_to_str`. -pub fn (mut d Doc) type_to_str(typ table.Type) string { - // why is it the default behaviour of table.type_to_str +// type_to_str is a wrapper function around `fmt.ast.type_to_str`. +pub fn (mut d Doc) type_to_str(typ ast.Type) string { + // why is it the default behaviour of ast.type_to_str // to convert math.bits.Type to bits.Type? d.table.cmod_prefix = d.orig_mod_name + '.' return d.fmt.table.type_to_str(typ).all_after('&') diff --git a/vlib/v/eval/eval.v b/vlib/v/eval/eval.v index 0d84b3eb69..45bb687582 100644 --- a/vlib/v/eval/eval.v +++ b/vlib/v/eval/eval.v @@ -5,7 +5,6 @@ module eval import v.ast import v.checker -import v.table import v.pref pub type Object = int | string @@ -14,14 +13,14 @@ pub struct Eval { mut: checker checker.Checker vars map[string]Var - table &table.Table + table &ast.Table } pub struct Var { value Object } -pub fn (mut e Eval) eval(file ast.File, table &table.Table) string { +pub fn (mut e Eval) eval(file ast.File, table &ast.Table) string { vpref := &pref.Preferences{} e.table = table mut res := '' diff --git a/vlib/v/fmt/attrs.v b/vlib/v/fmt/attrs.v index 826b7f6331..4efafb872c 100644 --- a/vlib/v/fmt/attrs.v +++ b/vlib/v/fmt/attrs.v @@ -3,9 +3,9 @@ // that can be found in the LICENSE file. module fmt -import v.table +import v.ast -pub fn (mut f Fmt) attrs(attrs []table.Attr) { +pub fn (mut f Fmt) attrs(attrs []ast.Attr) { mut sorted_attrs := attrs.clone() // Sort the attributes. The ones with arguments come first. sorted_attrs.sort(a.arg.len > b.arg.len) @@ -22,7 +22,7 @@ pub struct AttrsOptions { inline bool } -pub fn (mut f Fmt) single_line_attrs(attrs []table.Attr, options AttrsOptions) { +pub fn (mut f Fmt) single_line_attrs(attrs []ast.Attr, options AttrsOptions) { if attrs.len == 0 { return } @@ -44,7 +44,7 @@ pub fn (mut f Fmt) single_line_attrs(attrs []table.Attr, options AttrsOptions) { } } -fn inline_attrs_len(attrs []table.Attr) int { +fn inline_attrs_len(attrs []ast.Attr) int { if attrs.len == 0 { return 0 } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 31578225f9..1ccad7edca 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -5,7 +5,6 @@ module fmt import math.mathutil as mu import v.ast -import v.table import strings import v.util import v.pref @@ -18,7 +17,7 @@ const ( pub struct Fmt { pub mut: - table &table.Table + table &ast.Table out_imports strings.Builder out strings.Builder indent int @@ -49,7 +48,7 @@ pub mut: pref &pref.Preferences } -pub fn fmt(file ast.File, table &table.Table, pref &pref.Preferences, is_debug bool) string { +pub fn fmt(file ast.File, table &ast.Table, pref &pref.Preferences, is_debug bool) string { mut f := Fmt{ out: strings.new_builder(1000) out_imports: strings.new_builder(200) @@ -113,7 +112,7 @@ fn (mut f Fmt) write_indent() { f.line_len += f.indent * 4 } -fn (mut f Fmt) write_language_prefix(lang table.Language) { +fn (mut f Fmt) write_language_prefix(lang ast.Language) { match lang { .c { f.write('C.') } .js { f.write('JS.') } @@ -223,7 +222,7 @@ pub fn (mut f Fmt) short_module(name string) string { //=== Import-related methods ===// -pub fn (mut f Fmt) mark_types_import_as_used(typ table.Type) { +pub fn (mut f Fmt) mark_types_import_as_used(typ ast.Type) { sym := f.table.get_type_symbol(typ) f.mark_import_as_used(sym.name) } @@ -617,7 +616,7 @@ pub fn (mut f Fmt) expr(node ast.Expr) { ast.StructInit { f.struct_init(node) } - ast.Type { + ast.TypeNode { f.type_expr(node) } ast.TypeOf { @@ -1261,7 +1260,7 @@ pub fn (mut f Fmt) fn_type_decl(node ast.FnTypeDecl) { f.write('pub ') } typ_sym := f.table.get_type_symbol(node.typ) - fn_typ_info := typ_sym.info as table.FnType + fn_typ_info := typ_sym.info as ast.FnType fn_info := fn_typ_info.func fn_name := f.no_cur_mod(node.name) f.write('type $fn_name = fn (') @@ -1293,7 +1292,7 @@ pub fn (mut f Fmt) fn_type_decl(node ast.FnTypeDecl) { } } f.write(')') - if fn_info.return_type.idx() != table.void_type_idx { + if fn_info.return_type.idx() != ast.void_type_idx { ret_str := f.no_cur_mod(f.table.type_to_str_using_aliases(fn_info.return_type, f.mod2alias)) f.write(' $ret_str') @@ -1335,7 +1334,7 @@ pub fn (mut f Fmt) array_decompose(node ast.ArrayDecompose) { } pub fn (mut f Fmt) array_init(node ast.ArrayInit) { - if node.exprs.len == 0 && node.typ != 0 && node.typ != table.void_type { + if node.exprs.len == 0 && node.typ != 0 && node.typ != ast.void_type { // `x := []string{}` f.mark_types_import_as_used(node.typ) f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias)) @@ -1530,7 +1529,7 @@ pub fn (mut f Fmt) call_expr(node ast.CallExpr) { f.use_short_fn_args = false if node.args.len > 0 && node.args.last().expr is ast.StructInit { struct_expr := node.args.last().expr as ast.StructInit - if struct_expr.typ == table.void_type { + if struct_expr.typ == ast.void_type { f.use_short_fn_args = true } } @@ -2005,7 +2004,7 @@ pub fn (mut f Fmt) lock_expr(node ast.LockExpr) { pub fn (mut f Fmt) map_init(node ast.MapInit) { if node.keys.len == 0 { - if node.typ > table.void_type { + if node.typ > ast.void_type { f.mark_types_import_as_used(node.typ) f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias)) } else { @@ -2269,7 +2268,7 @@ pub fn (mut f Fmt) string_literal(node ast.StringLiteral) { use_double_quote := node.val.contains("'") && !node.val.contains('"') if node.is_raw { f.write('r') - } else if node.language == table.Language.c { + } else if node.language == ast.Language.c { f.write('c') } if node.is_raw { @@ -2323,7 +2322,7 @@ pub fn (mut f Fmt) string_inter_literal(node ast.StringInterLiteral) { f.write(quote) } -pub fn (mut f Fmt) type_expr(node ast.Type) { +pub fn (mut f Fmt) type_expr(node ast.TypeNode) { f.write(f.table.type_to_str(node.typ)) } diff --git a/vlib/v/fmt/fmt_keep_test.v b/vlib/v/fmt/fmt_keep_test.v index 5e2bae407e..32c64e2977 100644 --- a/vlib/v/fmt/fmt_keep_test.v +++ b/vlib/v/fmt/fmt_keep_test.v @@ -4,10 +4,9 @@ import os import term import benchmark -import v.ast import v.fmt import v.parser -import v.table +import v.ast import v.pref import v.util import v.util.vtest @@ -54,7 +53,7 @@ fn test_fmt() { eprintln(fmt_bench.step_message_fail('cannot read from $vrelpath')) continue } - table := table.new_table() + table := ast.new_table() file_ast := parser.parse_file(ipath, table, .parse_comments, fpref, &ast.Scope{ parent: 0 }) diff --git a/vlib/v/fmt/fmt_test.v b/vlib/v/fmt/fmt_test.v index 6bf18a9a40..06b33163c9 100644 --- a/vlib/v/fmt/fmt_test.v +++ b/vlib/v/fmt/fmt_test.v @@ -7,7 +7,6 @@ import benchmark import v.ast import v.fmt import v.parser -import v.table import v.pref import v.util @@ -49,7 +48,7 @@ fn test_fmt() { eprintln(fmt_bench.step_message_fail('cannot read from $opath')) continue } - table := table.new_table() + table := ast.new_table() file_ast := parser.parse_file(ipath, table, .parse_comments, fpref, &ast.Scope{ parent: 0 }) diff --git a/vlib/v/fmt/fmt_vlib_test.v b/vlib/v/fmt/fmt_vlib_test.v index 6c90f09649..9fcf3904b4 100644 --- a/vlib/v/fmt/fmt_vlib_test.v +++ b/vlib/v/fmt/fmt_vlib_test.v @@ -7,7 +7,6 @@ import benchmark import v.ast import v.fmt import v.parser -import v.table import v.pref import v.util @@ -47,7 +46,7 @@ fn test_vlib_fmt() { eprintln(fmt_bench.step_message_fail('cannot read from $opath')) continue } - table := table.new_table() + table := ast.new_table() file_ast := parser.parse_file(ipath, table, .parse_comments, fpref, &ast.Scope{ parent: 0 }) diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 8b1b31878b..cce6cd6c15 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -4,7 +4,6 @@ module c import strings import v.ast -import v.table fn (mut g Gen) array_init(node ast.ArrayInit) { type_sym := g.table.get_type_symbol(node.typ) @@ -36,7 +35,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } } else if node.has_default { g.expr(node.default_expr) - info := type_sym.info as table.ArrayFixed + info := type_sym.info as ast.ArrayFixed for _ in 1 .. info.size { g.write(', ') g.expr(node.default_expr) @@ -81,7 +80,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { g.write('&($elem_type_str[]){') g.expr(node.default_expr) g.write('})') - } else if node.has_len && node.elem_type == table.string_type { + } else if node.has_len && node.elem_type == ast.string_type { g.write('&($elem_type_str[]){') g.write('_SLIT("")') g.write('})') @@ -134,9 +133,9 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) { // inp_typ := g.typ(node.receiver_type) ret_sym := g.table.get_type_symbol(node.return_type) inp_sym := g.table.get_type_symbol(node.receiver_type) - ret_info := ret_sym.info as table.Array + ret_info := ret_sym.info as ast.Array ret_elem_type := g.typ(ret_info.elem_type) - inp_info := inp_sym.info as table.Array + inp_info := inp_sym.info as ast.Array inp_elem_type := g.typ(inp_info.elem_type) if inp_sym.kind != .array { verror('map() requires an array') @@ -209,7 +208,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { // println(rec_sym.kind) verror('.sort() is an array method') } - info := rec_sym.info as table.Array + info := rec_sym.info as ast.Array // No arguments means we are sorting an array of builtins (e.g. `numbers.sort()`) // The type for the comparison fns is the type of the element itself. mut typ := info.elem_type @@ -228,10 +227,10 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { if is_default { // users.sort() or users.sort(a > b) compare_fn = match typ { - table.int_type, table.int_type.to_ptr() { 'compare_ints' } - table.u64_type, table.u64_type.to_ptr() { 'compare_u64s' } - table.string_type, table.string_type.to_ptr() { 'compare_strings' } - table.f64_type, table.f64_type.to_ptr() { 'compare_floats' } + ast.int_type, ast.int_type.to_ptr() { 'compare_ints' } + ast.u64_type, ast.u64_type.to_ptr() { 'compare_u64s' } + ast.string_type, ast.string_type.to_ptr() { 'compare_strings' } + ast.f64_type, ast.f64_type.to_ptr() { 'compare_floats' } else { '' } } if compare_fn != '' && is_reverse { @@ -248,7 +247,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { compare_fn += '_reverse' } // Register a new custom `compare_xxx` function for qsort() - g.table.register_fn(name: compare_fn, return_type: table.int_type) + g.table.register_fn(name: compare_fn, return_type: ast.int_type) infix_expr := node.args[0].expr as ast.InfixExpr // Variables `a` and `b` are used in the `.sort(a < b)` syntax, so we can reuse them // when generating the function as long as the args are named the same. @@ -270,7 +269,7 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { g.definitions.writeln('$field_type a_ = $left_expr_str;') g.definitions.writeln('$field_type b_ = $right_expr_str;') mut op1, mut op2 := '', '' - if infix_expr.left_type == table.string_type { + if infix_expr.left_type == ast.string_type { if is_reverse { op1 = 'string_gt(a_, b_)' op2 = 'string_lt(a_, b_)' @@ -316,7 +315,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) { if sym.kind != .array { verror('filter() requires an array') } - info := sym.info as table.Array + info := sym.info as ast.Array styp := g.typ(node.return_type) elem_type_str := g.typ(info.elem_type) g.empty_line = true @@ -379,7 +378,7 @@ fn (mut g Gen) gen_array_filter(node ast.CallExpr) { // `nums.insert(0, 2)` `nums.insert(0, [2,3,4])` fn (mut g Gen) gen_array_insert(node ast.CallExpr) { left_sym := g.table.get_type_symbol(node.left_type) - left_info := left_sym.info as table.Array + left_info := left_sym.info as ast.Array elem_type_str := g.typ(left_info.elem_type) arg2_sym := g.table.get_type_symbol(node.args[1].typ) is_arg2_array := arg2_sym.kind == .array && node.args[1].typ == node.left_type @@ -399,11 +398,11 @@ fn (mut g Gen) gen_array_insert(node ast.CallExpr) { g.write('.len)') } else { g.write(', &($elem_type_str[]){') - if left_info.elem_type == table.string_type { + if left_info.elem_type == ast.string_type { g.write('string_clone(') } g.expr(node.args[1].expr) - if left_info.elem_type == table.string_type { + if left_info.elem_type == ast.string_type { g.write(')') } g.write('})') @@ -413,7 +412,7 @@ fn (mut g Gen) gen_array_insert(node ast.CallExpr) { // `nums.prepend(2)` `nums.prepend([2,3,4])` fn (mut g Gen) gen_array_prepend(node ast.CallExpr) { left_sym := g.table.get_type_symbol(node.left_type) - left_info := left_sym.info as table.Array + left_info := left_sym.info as ast.Array elem_type_str := g.typ(left_info.elem_type) arg_sym := g.table.get_type_symbol(node.args[0].typ) is_arg_array := arg_sym.kind == .array && node.args[0].typ == node.left_type @@ -436,12 +435,12 @@ fn (mut g Gen) gen_array_prepend(node ast.CallExpr) { } } -fn (mut g Gen) gen_array_contains_method(left_type table.Type) string { +fn (mut g Gen) gen_array_contains_method(left_type ast.Type) string { mut left_sym := g.table.get_type_symbol(left_type) mut left_type_str := g.typ(left_type).replace('*', '') fn_name := '${left_type_str}_contains' if !left_sym.has_method('contains') { - left_info := left_sym.info as table.Array + left_info := left_sym.info as ast.Array mut elem_type_str := g.typ(left_info.elem_type) elem_sym := g.table.get_type_symbol(left_info.elem_type) if elem_sym.kind == .function { @@ -474,11 +473,11 @@ fn (mut g Gen) gen_array_contains_method(left_type table.Type) string { fn_builder.writeln('\treturn false;') fn_builder.writeln('}') g.auto_fn_definitions << fn_builder.str() - left_sym.register_method(&table.Fn{ + left_sym.register_method(&ast.Fn{ name: 'contains' - params: [table.Param{ + params: [ast.Param{ typ: left_type - }, table.Param{ + }, ast.Param{ typ: left_info.elem_type }] }) @@ -499,12 +498,12 @@ fn (mut g Gen) gen_array_contains(node ast.CallExpr) { g.write(')') } -fn (mut g Gen) gen_array_index_method(left_type table.Type) string { +fn (mut g Gen) gen_array_index_method(left_type ast.Type) string { mut left_sym := g.table.get_type_symbol(left_type) mut left_type_str := g.typ(left_type).trim('*') fn_name := '${left_type_str}_index' if !left_sym.has_method('index') { - info := left_sym.info as table.Array + info := left_sym.info as ast.Array mut elem_type_str := g.typ(info.elem_type) elem_sym := g.table.get_type_symbol(info.elem_type) if elem_sym.kind == .function { @@ -537,11 +536,11 @@ fn (mut g Gen) gen_array_index_method(left_type table.Type) string { fn_builder.writeln('\treturn -1;') fn_builder.writeln('}') g.auto_fn_definitions << fn_builder.str() - left_sym.register_method(&table.Fn{ + left_sym.register_method(&ast.Fn{ name: 'index' - params: [table.Param{ + params: [ast.Param{ typ: left_type - }, table.Param{ + }, ast.Param{ typ: info.elem_type }] }) @@ -578,7 +577,7 @@ fn (mut g Gen) gen_array_any(node ast.CallExpr) { tmp := g.new_tmp_var() s := g.go_before_stmt(0) sym := g.table.get_type_symbol(node.left_type) - info := sym.info as table.Array + info := sym.info as ast.Array // styp := g.typ(node.return_type) elem_type_str := g.typ(info.elem_type) g.empty_line = true @@ -642,7 +641,7 @@ fn (mut g Gen) gen_array_all(node ast.CallExpr) { tmp := g.new_tmp_var() s := g.go_before_stmt(0) sym := g.table.get_type_symbol(node.left_type) - info := sym.info as table.Array + info := sym.info as ast.Array // styp := g.typ(node.return_type) elem_type_str := g.typ(info.elem_type) g.empty_line = true diff --git a/vlib/v/gen/c/assert.v b/vlib/v/gen/c/assert.v index 1979d0192c..b555b09f01 100644 --- a/vlib/v/gen/c/assert.v +++ b/vlib/v/gen/c/assert.v @@ -4,7 +4,6 @@ module c import v.ast -import v.table fn (mut g Gen) gen_assert_stmt(original_assert_statement ast.AssertStmt) { mut node := original_assert_statement @@ -84,7 +83,7 @@ fn (mut g Gen) gen_assert_metainfo(node ast.AssertStmt) string { return metaname } -fn (mut g Gen) gen_assert_single_expr(expr ast.Expr, typ table.Type) { +fn (mut g Gen) gen_assert_single_expr(expr ast.Expr, typ ast.Type) { unknown_value := '*unknown value*' match expr { ast.CastExpr, ast.IndexExpr, ast.MatchExpr { @@ -100,7 +99,7 @@ fn (mut g Gen) gen_assert_single_expr(expr ast.Expr, typ table.Type) { g.gen_expr_to_string(expr, typ) } } - ast.Type { + ast.TypeNode { sym := g.table.get_type_symbol(typ) g.write(ctoslit('$sym.name')) } diff --git a/vlib/v/gen/c/auto_eq_methods.v b/vlib/v/gen/c/auto_eq_methods.v index 3b158988d1..d8861820a1 100644 --- a/vlib/v/gen/c/auto_eq_methods.v +++ b/vlib/v/gen/c/auto_eq_methods.v @@ -3,9 +3,9 @@ module c import strings -import v.table +import v.ast -fn (mut g Gen) gen_sumtype_equality_fn(left table.Type) string { +fn (mut g Gen) gen_sumtype_equality_fn(left ast.Type) string { ptr_typ := g.typ(left).trim('*') if ptr_typ in g.sumtype_fn_definitions { return ptr_typ @@ -58,7 +58,7 @@ fn (mut g Gen) gen_sumtype_equality_fn(left table.Type) string { return ptr_typ } -fn (mut g Gen) gen_struct_equality_fn(left table.Type) string { +fn (mut g Gen) gen_struct_equality_fn(left ast.Type) string { ptr_typ := g.typ(left).trim('*') if ptr_typ in g.struct_fn_definitions { return ptr_typ @@ -115,14 +115,14 @@ fn (mut g Gen) gen_struct_equality_fn(left table.Type) string { return ptr_typ } -fn (mut g Gen) gen_alias_equality_fn(left table.Type) string { +fn (mut g Gen) gen_alias_equality_fn(left ast.Type) string { ptr_typ := g.typ(left).trim('*') if ptr_typ in g.alias_fn_definitions { return ptr_typ } g.alias_fn_definitions << ptr_typ left_sym := g.table.get_type_symbol(left) - info := left_sym.info as table.Alias + info := left_sym.info as ast.Alias g.type_definitions.writeln('static bool ${ptr_typ}_alias_eq($ptr_typ a, $ptr_typ b); // auto') mut fn_builder := strings.new_builder(512) fn_builder.writeln('static bool ${ptr_typ}_alias_eq($ptr_typ a, $ptr_typ b) {') @@ -157,7 +157,7 @@ fn (mut g Gen) gen_alias_equality_fn(left table.Type) string { return ptr_typ } -fn (mut g Gen) gen_array_equality_fn(left table.Type) string { +fn (mut g Gen) gen_array_equality_fn(left ast.Type) string { ptr_typ := g.typ(left).trim('*') if ptr_typ in g.array_fn_definitions { return ptr_typ @@ -209,7 +209,7 @@ fn (mut g Gen) gen_array_equality_fn(left table.Type) string { return ptr_typ } -fn (mut g Gen) gen_fixed_array_equality_fn(left table.Type) string { +fn (mut g Gen) gen_fixed_array_equality_fn(left ast.Type) string { ptr_typ := g.typ(left).trim('*') if ptr_typ in g.array_fn_definitions { return ptr_typ @@ -259,7 +259,7 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left table.Type) string { return ptr_typ } -fn (mut g Gen) gen_map_equality_fn(left table.Type) string { +fn (mut g Gen) gen_map_equality_fn(left ast.Type) string { ptr_typ := g.typ(left).trim('*') if ptr_typ in g.map_fn_definitions { return ptr_typ @@ -281,7 +281,7 @@ fn (mut g Gen) gen_map_equality_fn(left table.Type) string { kind := g.table.type_kind(value_typ) if kind == .function { value_sym := g.table.get_type_symbol(value_typ) - func := value_sym.info as table.FnType + func := value_sym.info as ast.FnType ret_styp := g.typ(func.func.return_type) fn_builder.write_string('\t\t$ret_styp (*v) (') arg_len := func.func.params.len diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index f853a2cf21..1d8453bd10 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -2,26 +2,26 @@ // Use of this source code is governed by an MIT license that can be found in the LICENSE file. module c -import v.table +import v.ast import v.util -fn should_use_indent_func(kind table.Kind) bool { +fn should_use_indent_func(kind ast.Kind) bool { return kind in [.struct_, .alias, .array, .array_fixed, .map, .sum_type, .interface_] } -fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_default(sym ast.TypeSymbol, styp string, str_fn_name string) { mut convertor := '' mut typename_ := '' - if sym.parent_idx in table.integer_type_idxs { + if sym.parent_idx in ast.integer_type_idxs { convertor = 'int' typename_ = 'int' - } else if sym.parent_idx == table.f32_type_idx { + } else if sym.parent_idx == ast.f32_type_idx { convertor = 'float' typename_ = 'f32' - } else if sym.parent_idx == table.f64_type_idx { + } else if sym.parent_idx == ast.f64_type_idx { convertor = 'double' typename_ = 'f64' - } else if sym.parent_idx == table.bool_type_idx { + } else if sym.parent_idx == ast.bool_type_idx { convertor = 'bool' typename_ = 'bool' } else { @@ -40,7 +40,7 @@ fn (mut g Gen) gen_str_default(sym table.TypeSymbol, styp string, str_fn_name st g.auto_str_funcs.writeln('}') } -fn (g &Gen) type_to_fmt(typ table.Type) string { +fn (g &Gen) type_to_fmt(typ ast.Type) string { sym := g.table.get_type_symbol(typ) if typ.is_ptr() && (typ.is_int() || typ.is_float()) { return '%.*s\\000' @@ -61,11 +61,11 @@ fn (g &Gen) type_to_fmt(typ table.Type) string { return '%d\\000' } -fn (mut g Gen) gen_str_for_type(typ table.Type) string { +fn (mut g Gen) gen_str_for_type(typ ast.Type) string { styp := g.typ(typ).replace('*', '') mut sym := g.table.get_type_symbol(g.unwrap_generic(typ)) mut str_fn_name := styp_to_str_fn_name(styp) - if mut sym.info is table.Alias { + if mut sym.info is ast.Alias { if sym.info.is_import { sym = g.table.get_type_symbol(sym.info.parent_type) str_fn_name = styp_to_str_fn_name(sym.name) @@ -79,38 +79,38 @@ fn (mut g Gen) gen_str_for_type(typ table.Type) string { } g.str_types << already_generated_key match mut sym.info { - table.Alias { + ast.Alias { if sym.info.is_import { g.gen_str_default(sym, styp, str_fn_name) } else { g.gen_str_for_alias(sym.info, styp, str_fn_name) } } - table.Array { + ast.Array { g.gen_str_for_array(sym.info, styp, str_fn_name) } - table.ArrayFixed { + ast.ArrayFixed { g.gen_str_for_array_fixed(sym.info, styp, str_fn_name) } - table.Enum { + ast.Enum { g.gen_str_for_enum(sym.info, styp, str_fn_name) } - table.FnType { + ast.FnType { g.gen_str_for_fn_type(sym.info, styp, str_fn_name) } - table.Struct { + ast.Struct { g.gen_str_for_struct(sym.info, styp, str_fn_name) } - table.Map { + ast.Map { g.gen_str_for_map(sym.info, styp, str_fn_name) } - table.MultiReturn { + ast.MultiReturn { g.gen_str_for_multi_return(sym.info, styp, str_fn_name) } - table.SumType { + ast.SumType { g.gen_str_for_union_sum_type(sym.info, styp, str_fn_name) } - table.Interface { + ast.Interface { g.gen_str_for_interface(sym.info, styp, str_fn_name) } else { @@ -129,7 +129,7 @@ fn (mut g Gen) gen_str_for_type(typ table.Type) string { return str_fn_name } -fn (mut g Gen) gen_str_for_option(typ table.Type, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string) { parent_type := typ.clear_flag(.optional) sym := g.table.get_type_symbol(parent_type) sym_has_str_method, _, _ := sym.str_method_info() @@ -157,7 +157,7 @@ fn (mut g Gen) gen_str_for_option(typ table.Type, styp string, str_fn_name strin g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_alias(info table.Alias, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string) { sym := g.table.get_type_symbol(info.parent_type) sym_has_str_method, _, _ := sym.str_method_info() mut parent_str_fn_name := styp_to_str_fn_name(sym.name.replace('.', '__')) @@ -177,10 +177,10 @@ fn (mut g Gen) gen_str_for_alias(info table.Alias, styp string, str_fn_name stri g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string) { mut typ := info.elem_type mut sym := g.table.get_type_symbol(info.elem_type) - if mut sym.info is table.Alias { + if mut sym.info is ast.Alias { typ = sym.info.parent_type sym = g.table.get_type_symbol(typ) } @@ -245,7 +245,7 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name stri } } g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, x);') - if g.is_autofree && typ != table.bool_type { + if g.is_autofree && typ != ast.bool_type { // no need to free "true"/"false" literals g.auto_str_funcs.writeln('\t\tstring_free(&x);') } @@ -260,10 +260,10 @@ fn (mut g Gen) gen_str_for_array(info table.Array, styp string, str_fn_name stri g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_name string) { mut typ := info.elem_type mut sym := g.table.get_type_symbol(info.elem_type) - if mut sym.info is table.Alias { + if mut sym.info is ast.Alias { typ = sym.info.parent_type sym = g.table.get_type_symbol(typ) } @@ -322,10 +322,10 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp string, str_f g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) { mut key_typ := info.key_type mut key_sym := g.table.get_type_symbol(key_typ) - if mut key_sym.info is table.Alias { + if mut key_sym.info is ast.Alias { key_typ = key_sym.info.parent_type key_sym = g.table.get_type_symbol(key_typ) } @@ -337,7 +337,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string) mut val_typ := info.value_type mut val_sym := g.table.get_type_symbol(val_typ) - if mut val_sym.info is table.Alias { + if mut val_sym.info is ast.Alias { val_typ = val_sym.info.parent_type val_sym = g.table.get_type_symbol(val_typ) } @@ -393,7 +393,7 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string) g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_fn_name string) { for typ in info.types { sym := g.table.get_type_symbol(typ) if !sym.has_method('str') { @@ -447,7 +447,7 @@ fn (mut g Gen) gen_str_for_multi_return(info table.MultiReturn, styp string, str g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name string) { // TODO: short it if possible // generates all definitions of substructs mut fnames2strfunc := map{ @@ -534,7 +534,7 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st g.auto_str_funcs.writeln('}') } -fn struct_auto_str_func(sym &table.TypeSymbol, field_type table.Type, fn_name string, field_name string) string { +fn struct_auto_str_func(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string) string { has_custom_str, expects_ptr, _ := sym.str_method_info() if sym.kind == .enum_ { return '${fn_name}(it.${c_name(field_name)})' @@ -574,7 +574,7 @@ fn struct_auto_str_func(sym &table.TypeSymbol, field_type table.Type, fn_name st } } -fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_enum(info ast.Enum, styp string, str_fn_name string) { s := util.no_dots(styp) g.type_definitions.writeln('static string ${str_fn_name}($styp it); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp it) { /* gen_str_for_enum */') @@ -606,7 +606,7 @@ fn (mut g Gen) gen_str_for_enum(info table.Enum, styp string, str_fn_name string g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_interface(info table.Interface, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_name string) { mut gen_fn_names := map[string]string{} for typ in info.types { sym := g.table.get_type_symbol(typ) @@ -641,7 +641,7 @@ fn (mut g Gen) gen_str_for_interface(info table.Interface, styp string, str_fn_n func_name = 'indent_$func_name' } deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '*' } - value_fmt := if typ == table.string_type { "'%.*s\\000'" } else { '%.*s\\000' } + value_fmt := if typ == ast.string_type { "'%.*s\\000'" } else { '%.*s\\000' } g.auto_str_funcs.write_string('\tif (x._interface_idx == _${styp}_${subtype.cname}_index)') g.auto_str_funcs.write_string(' return _STR("${clean_interface_v_type_name}($value_fmt)", 2, ') @@ -655,7 +655,7 @@ fn (mut g Gen) gen_str_for_interface(info table.Interface, styp string, str_fn_n g.auto_str_funcs.writeln('}') } -fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, str_fn_name string) { mut gen_fn_names := map[string]string{} for typ in info.variants { sym := g.table.get_type_symbol(typ) @@ -678,7 +678,7 @@ fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_f g.auto_str_funcs.writeln('\tswitch(x._typ) {') for typ in info.variants { mut value_fmt := '%.*s\\000' - if typ == table.string_type { + if typ == ast.string_type { value_fmt = "'$value_fmt'" } typ_str := g.typ(typ) @@ -704,7 +704,7 @@ fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_f g.auto_str_funcs.writeln('}') } -fn (mut g Gen) fn_decl_str(info table.FnType) string { +fn (mut g Gen) fn_decl_str(info ast.FnType) string { mut fn_str := 'fn (' for i, arg in info.func.params { if i > 0 { @@ -713,13 +713,13 @@ fn (mut g Gen) fn_decl_str(info table.FnType) string { fn_str += util.strip_main_name(g.table.get_type_name(arg.typ)) } fn_str += ')' - if info.func.return_type != table.void_type { + if info.func.return_type != ast.void_type { fn_str += ' ${util.strip_main_name(g.table.get_type_name(info.func.return_type))}' } return fn_str } -fn (mut g Gen) gen_str_for_fn_type(info table.FnType, styp string, str_fn_name string) { +fn (mut g Gen) gen_str_for_fn_type(info ast.FnType, styp string, str_fn_name string) { g.type_definitions.writeln('static string ${str_fn_name}(); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}() { return _SLIT("${g.fn_decl_str(info)}");}') } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 9ff83c2314..1a19f4aa10 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6,7 +6,6 @@ module c import os import strings import v.ast -import v.table import v.pref import v.token import v.util @@ -32,7 +31,7 @@ struct Gen { pref &pref.Preferences module_built string mut: - table &table.Table + table &ast.Table out strings.Builder cheaders strings.Builder includes strings.Builder // all C #includes required by V modules @@ -114,7 +113,7 @@ mut: hotcode_fn_names []string embedded_files []ast.EmbeddedFile cur_fn ast.FnDecl - cur_generic_types []table.Type // `int`, `string`, etc in `foo()` + cur_generic_types []ast.Type // `int`, `string`, etc in `foo()` sql_i int sql_stmt_name string sql_side SqlExprSide // left or right, to distinguish idents in `name == name` @@ -126,11 +125,11 @@ mut: inside_call bool has_main bool inside_const bool - comp_for_method string // $for method in T.methods {} - comp_for_field_var string // $for field in T.fields {}; the variable name - comp_for_field_value table.Field // value of the field variable - comp_for_field_type table.Type // type of the field variable inferred from `$if field.typ is T {}` - comptime_var_type_map map[string]table.Type + comp_for_method string // $for method in T.methods {} + comp_for_field_var string // $for field in T.fields {}; the variable name + comp_for_field_value ast.StructField // value of the field variable + comp_for_field_type ast.Type // type of the field variable inferred from `$if field.typ is T {}` + comptime_var_type_map map[string]ast.Type // tmp_arg_vars_to_free []string // autofree_pregen map[string]string // autofree_pregen_buf strings.Builder @@ -157,7 +156,7 @@ mut: // main_fn_decl_node ast.FnDecl } -pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string { +pub fn gen(files []ast.File, table &ast.Table, pref &pref.Preferences) string { // println('start cgen2') mut module_built := '' if pref.build_mode == .build_module { @@ -446,7 +445,7 @@ pub fn (mut g Gen) init() { g.generate_hotcode_reloading_declarations() } // Obfuscate only functions in the main module for now. - // Generate the obf_table. + // Generate the obf_ast. if g.pref.obfuscate { mut i := 0 // fns @@ -497,7 +496,7 @@ pub fn (mut g Gen) write_typeof_functions() { g.writeln('// >> typeof() support for sum types / interfaces') for typ in g.table.type_symbols { if typ.kind == .sum_type { - sum_info := typ.info as table.SumType + sum_info := typ.info as ast.SumType g.writeln('static char * v_typeof_sumtype_${typ.cname}(int sidx) { /* $typ.name */ ') if g.pref.build_mode == .build_module { g.writeln('\t\tif( sidx == _v_type_idx_${typ.cname}() ) return "${util.strip_main_name(typ.name)}";') @@ -519,7 +518,7 @@ pub fn (mut g Gen) write_typeof_functions() { } g.writeln('}') } else if typ.kind == .interface_ { - inter_info := typ.info as table.Interface + inter_info := typ.info as ast.Interface g.writeln('static char * v_typeof_interface_${typ.cname}(int sidx) { /* $typ.name */ ') for t in inter_info.types { subtype := g.table.get_type_symbol(t) @@ -534,7 +533,7 @@ pub fn (mut g Gen) write_typeof_functions() { } // V type to C typecc -fn (mut g Gen) typ(t table.Type) string { +fn (mut g Gen) typ(t ast.Type) string { styp := g.base_type(t) if t.has_flag(.optional) { // Register an optional if it's not registered yet @@ -548,7 +547,7 @@ fn (mut g Gen) typ(t table.Type) string { return styp } -fn (mut g Gen) base_type(t table.Type) string { +fn (mut g Gen) base_type(t ast.Type) string { share := t.share() mut styp := if share == .atomic_t { t.atomic_typename() } else { g.cc_type(t, true) } if t.has_flag(.shared_f) { @@ -573,7 +572,7 @@ fn (mut g Gen) expr_string(expr ast.Expr) string { // but I(emily) would rather have this generation // all unified in one place so that it doesnt break // if one location changes -fn (mut g Gen) optional_type_name(t table.Type) (string, string) { +fn (mut g Gen) optional_type_name(t ast.Type) (string, string) { base := g.base_type(t) mut styp := 'Option_$base' if t.is_ptr() { @@ -593,7 +592,7 @@ fn (g &Gen) optional_type_text(styp string, base string) string { return ret } -fn (mut g Gen) register_optional(t table.Type) string { +fn (mut g Gen) register_optional(t ast.Type) string { styp, base := g.optional_type_name(t) if styp !in g.optionals { g.typedefs2.writeln('typedef struct $styp $styp;') @@ -604,7 +603,7 @@ fn (mut g Gen) register_optional(t table.Type) string { return styp } -fn (mut g Gen) find_or_register_shared(t table.Type, base string) string { +fn (mut g Gen) find_or_register_shared(t ast.Type, base string) string { sh_typ := '__shared__$base' t_idx := t.idx() if t_idx in g.shareds { @@ -682,11 +681,11 @@ static inline Option_void __Option_${styp}_pushval($styp ch, $el_type e) { } // cc_type whether to prefix 'struct' or not (C__Foo -> struct Foo) -fn (g &Gen) cc_type(typ table.Type, is_prefix_struct bool) string { +fn (g &Gen) cc_type(typ ast.Type, is_prefix_struct bool) string { sym := g.table.get_type_symbol(g.unwrap_generic(typ)) mut styp := sym.cname // TODO: this needs to be removed; cgen shouldn't resolve generic types (job of checker) - if mut sym.info is table.Struct { + if mut sym.info is ast.Struct { if sym.info.generic_types.len > 0 { mut sgtyps := '_T' for gt in sym.info.generic_types { @@ -699,7 +698,7 @@ fn (g &Gen) cc_type(typ table.Type, is_prefix_struct bool) string { } styp += sgtyps } - } else if mut sym.info is table.MultiReturn { + } else if mut sym.info is ast.MultiReturn { // TODO: this doesn't belong here, but makes it working for now mut cname := 'multi_return' for mr_typ in sym.info.types { @@ -711,7 +710,7 @@ fn (g &Gen) cc_type(typ table.Type, is_prefix_struct bool) string { if is_prefix_struct && styp.starts_with('C__') { styp = styp[3..] if sym.kind == .struct_ { - info := sym.info as table.Struct + info := sym.info as ast.Struct if !info.is_typedef { styp = 'struct $styp' } @@ -721,7 +720,7 @@ fn (g &Gen) cc_type(typ table.Type, is_prefix_struct bool) string { } [inline] -fn (g &Gen) type_sidx(t table.Type) string { +fn (g &Gen) type_sidx(t ast.Type) string { if g.pref.build_mode == .build_module { sym := g.table.get_type_symbol(t) return '_v_type_idx_${sym.cname}()' @@ -740,7 +739,7 @@ pub fn (mut g Gen) write_typedef_types() { parent := unsafe { &g.table.type_symbols[typ.parent_idx] } is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.` mut is_typedef := false - if parent.info is table.Struct { + if parent.info is ast.Struct { is_typedef = parent.info.is_typedef } mut parent_styp := parent.cname @@ -751,7 +750,7 @@ pub fn (mut g Gen) write_typedef_types() { parent_styp = parent.cname[3..] } } else { - if typ.info is table.Alias { + if typ.info is ast.Alias { parent_styp = g.typ(typ.info.parent_type) } } @@ -761,7 +760,7 @@ pub fn (mut g Gen) write_typedef_types() { g.type_definitions.writeln('typedef array $typ.cname;') } .array_fixed { - info := typ.info as table.ArrayFixed + info := typ.info as ast.ArrayFixed elem_sym := g.table.get_type_symbol(info.elem_type) if elem_sym.is_builtin() { // .array_fixed { @@ -773,7 +772,7 @@ pub fn (mut g Gen) write_typedef_types() { if fixed.starts_with('C__') { fixed = fixed[3..] } - if elem_sym.info is table.FnType { + if elem_sym.info is ast.FnType { pos := g.out.len g.write_fn_ptr_decl(&elem_sym.info, '') fixed = g.out.after(pos) @@ -822,8 +821,8 @@ static inline void __${typ.cname}_pushval($typ.cname ch, $el_stype val) { } } -pub fn (mut g Gen) write_interface_typesymbol_declaration(sym table.TypeSymbol) { - info := sym.info as table.Interface +pub fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol) { + info := sym.info as ast.Interface g.type_definitions.writeln('typedef struct {') g.type_definitions.writeln('\tvoid* _object;') g.type_definitions.writeln('\tint _interface_idx;') @@ -835,8 +834,8 @@ pub fn (mut g Gen) write_interface_typesymbol_declaration(sym table.TypeSymbol) g.type_definitions.writeln('} ${c_name(sym.name)};\n') } -pub fn (mut g Gen) write_fn_typesymbol_declaration(sym table.TypeSymbol) { - info := sym.info as table.FnType +pub fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol) { + info := sym.info as ast.FnType func := info.func is_fn_sig := func.name == '' not_anon := !info.is_anon @@ -943,7 +942,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) { g.stmt_path_pos << g.out.len g.skip_stmt_pos = true if stmt is ast.ExprStmt { - if stmt.typ == table.error_type_idx || stmt.expr is ast.None { + if stmt.typ == ast.error_type_idx || stmt.expr is ast.None { g.writeln('${tmp_var}.state = 2;') g.write('${tmp_var}.err = ') g.expr(stmt.expr) @@ -951,9 +950,9 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) { } else { mut styp := g.base_type(stmt.typ) $if tinyc && x32 && windows { - if stmt.typ == table.int_literal_type { + if stmt.typ == ast.int_literal_type { styp = 'int' - } else if stmt.typ == table.float_literal_type { + } else if stmt.typ == ast.float_literal_type { styp = 'f64' } } @@ -1428,7 +1427,7 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { if node.val_var != '_' { if val_sym.kind == .function { g.write('\t') - g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var)) + g.write_fn_ptr_decl(val_sym.info as ast.FnType, c_name(node.val_var)) g.writeln(' = ((voidptr*)$cond_var${op_field}data)[$i];') } else if val_sym.kind == .array_fixed && !node.val_is_mut { right := '(($styp*)$cond_var${op_field}data)[$i]' @@ -1473,14 +1472,14 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { } idx := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var } cond_sym := g.table.get_type_symbol(node.cond_type) - info := cond_sym.info as table.ArrayFixed + info := cond_sym.info as ast.ArrayFixed g.writeln('for (int $idx = 0; $idx != $info.size; ++$idx) {') if node.val_var != '_' { val_sym := g.table.get_type_symbol(node.val_type) is_fixed_array := val_sym.kind == .array_fixed && !node.val_is_mut if val_sym.kind == .function { g.write('\t') - g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var)) + g.write_fn_ptr_decl(val_sym.info as ast.FnType, c_name(node.val_var)) } else if is_fixed_array { styp := g.typ(node.val_type) g.writeln('\t$styp ${c_name(node.val_var)};') @@ -1537,14 +1536,14 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { key := c_name(node.key_var) g.writeln('$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&$cond_var${arw_or_pt}key_values, $idx);') // TODO: analyze whether node.key_type has a .clone() method and call .clone() for all types: - if node.key_type == table.string_type { + if node.key_type == ast.string_type { g.writeln('$key = string_clone($key);') } } if node.val_var != '_' { val_sym := g.table.get_type_symbol(node.val_type) if val_sym.kind == .function { - g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var)) + g.write_fn_ptr_decl(val_sym.info as ast.FnType, c_name(node.val_var)) g.write(' = (*(voidptr*)') g.writeln('DenseArray_value(&$cond_var${arw_or_pt}key_values, $idx));') } else if val_sym.kind == .array_fixed && !node.val_is_mut { @@ -1564,7 +1563,7 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { g.indent-- } else if node.kind == .string { cond := if node.cond is ast.StringLiteral || node.cond is ast.StringInterLiteral { - ast.Expr(g.new_ctemp_var_then_gen(node.cond, table.string_type)) + ast.Expr(g.new_ctemp_var_then_gen(node.cond, ast.string_type)) } else { node.cond } @@ -1626,7 +1625,7 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { } } -fn (mut g Gen) write_sumtype_casting_fn(got_ table.Type, exp_ table.Type) { +fn (mut g Gen) write_sumtype_casting_fn(got_ ast.Type, exp_ ast.Type) { got, exp := got_.idx(), exp_.idx() i := got | (exp << 16) if got == exp || g.sumtype_definitions[i] { @@ -1640,7 +1639,7 @@ fn (mut g Gen) write_sumtype_casting_fn(got_ table.Type, exp_ table.Type) { sb.writeln('static inline $exp_cname ${got_cname}_to_sumtype_${exp_cname}($got_cname* x) {') sb.writeln('\t$got_cname* ptr = memdup(x, sizeof($got_cname));') sb.write_string('\treturn ($exp_cname){ ._$got_cname = ptr, ._typ = ${g.type_sidx(got)}') - for field in (exp_sym.info as table.SumType).fields { + for field in (exp_sym.info as ast.SumType).fields { field_styp := g.typ(field.typ) if got_sym.kind in [.sum_type, .interface_] { // the field is already a wrapped pointer; we shouldn't wrap it once again @@ -1654,7 +1653,7 @@ fn (mut g Gen) write_sumtype_casting_fn(got_ table.Type, exp_ table.Type) { } // use instead of expr() when you need to cast to a different type -fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_type table.Type) { +fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_type ast.Type) { got_type := g.table.mktyp(got_type_raw) exp_sym := g.table.get_type_symbol(expected_type) expected_is_ptr := expected_type.is_ptr() @@ -1662,7 +1661,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_t got_sym := g.table.get_type_symbol(got_type) // allow using the new Error struct as a string, to avoid a breaking change // TODO: temporary to allow people to migrate their code; remove soon - if got_type == table.error_type_idx && expected_type == table.string_type_idx { + if got_type == ast.error_type_idx && expected_type == ast.string_type_idx { g.write('(*(') g.expr(expr) g.write('.msg))') @@ -1689,7 +1688,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_t // cast to sum type exp_styp := g.typ(expected_type) got_styp := g.typ(got_type) - if expected_type != table.void_type { + if expected_type != ast.void_type { expected_deref_type := if expected_is_ptr { expected_type.deref() } else { expected_type } got_deref_type := if got_is_ptr { got_type.deref() } else { got_type } if g.table.sumtype_has_variant(expected_deref_type, got_deref_type) { @@ -1732,7 +1731,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_t } } // Generic dereferencing logic - neither_void := table.voidptr_type !in [got_type, expected_type] + neither_void := ast.voidptr_type !in [got_type, expected_type] to_shared := expected_type.has_flag(.shared_f) && !got_type_raw.has_flag(.shared_f) && !expected_type.has_flag(.optional) // from_shared := got_type_raw.has_flag(.shared_f) && !expected_type.has_flag(.shared_f) @@ -1776,7 +1775,7 @@ fn ctoslit(s string) string { return '_SLIT("' + cestring(s) + '")' } -fn (mut g Gen) gen_attrs(attrs []table.Attr) { +fn (mut g Gen) gen_attrs(attrs []ast.Attr) { for attr in attrs { g.writeln('// Attr: [$attr.name]') } @@ -1967,7 +1966,7 @@ fn cnewlines(s string) string { return s.replace('\n', r'\n') } -fn (mut g Gen) write_fn_ptr_decl(func &table.FnType, ptr_name string) { +fn (mut g Gen) write_fn_ptr_decl(func &ast.FnType, ptr_name string) { ret_styp := g.typ(func.func.return_type) g.write('$ret_styp (*$ptr_name) (') arg_len := func.func.params.len @@ -1986,7 +1985,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if assign_stmt.is_static { g.write('static ') } - mut return_type := table.void_type + mut return_type := ast.void_type is_decl := assign_stmt.op == .decl_assign op := if is_decl { token.Kind.assign } else { assign_stmt.op } right_expr := assign_stmt.right[0] @@ -2002,14 +2001,14 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { mut af := g.is_autofree && !g.is_builtin_mod && assign_stmt.op == .assign && assign_stmt.left_types.len == 1 && (assign_stmt.left[0] is ast.Ident || assign_stmt.left[0] is ast.SelectorExpr) - // assign_stmt.left_types[0] in [table.string_type, table.array_type] && + // assign_stmt.left_types[0] in [ast.string_type, ast.array_type] && mut sref_name := '' mut type_to_free := '' if af { first_left_type := assign_stmt.left_types[0] first_left_sym := g.table.get_type_symbol(assign_stmt.left_types[0]) - if first_left_type == table.string_type || first_left_sym.kind == .array { - type_to_free = if first_left_type == table.string_type { 'string' } else { 'array' } + if first_left_type == ast.string_type || first_left_sym.kind == .array { + type_to_free = if first_left_type == ast.string_type { 'string' } else { 'array' } mut ok := true left0 := assign_stmt.left[0] if left0 is ast.Ident { @@ -2076,7 +2075,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { } */ // json_test failed w/o this check - if return_type != table.void_type && return_type != 0 { + if return_type != ast.void_type && return_type != 0 { sym := g.table.get_type_symbol(return_type) if sym.kind == .multi_return { // multi return @@ -2116,7 +2115,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { left_typ := assign_stmt.left_types[i] left_sym := g.table.get_type_symbol(left_typ) if left_sym.kind == .function { - g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos') + g.write_fn_ptr_decl(left_sym.info as ast.FnType, '_var_$left.pos.pos') g.writeln(' = $left.name;') } else { styp := g.typ(left_typ) @@ -2126,12 +2125,12 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { ast.IndexExpr { sym := g.table.get_type_symbol(left.left_type) if sym.kind == .array { - info := sym.info as table.Array + info := sym.info as ast.Array elem_typ := g.table.get_type_symbol(info.elem_type) if elem_typ.kind == .function { left_typ := assign_stmt.left_types[i] left_sym := g.table.get_type_symbol(left_typ) - g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos') + g.write_fn_ptr_decl(left_sym.info as ast.FnType, '_var_$left.pos.pos') g.write(' = *(voidptr*)array_get(') } else { styp := g.typ(info.elem_type) @@ -2140,7 +2139,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if left.left_type.is_ptr() { g.write('*') } - needs_clone := info.elem_type == table.string_type && g.is_autofree + needs_clone := info.elem_type == ast.string_type && g.is_autofree if needs_clone { g.write('/*1*/string_clone(') } @@ -2152,7 +2151,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { g.expr(left.index) g.writeln(');') } else if sym.kind == .map { - info := sym.info as table.Map + info := sym.info as ast.Map skeytyp := g.typ(info.key_type) styp := g.typ(info.value_type) zero := g.type_default(info.value_type) @@ -2160,7 +2159,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if val_typ.kind == .function { left_type := assign_stmt.left_types[i] left_sym := g.table.get_type_symbol(left_type) - g.write_fn_ptr_decl(left_sym.info as table.FnType, '_var_$left.pos.pos') + g.write_fn_ptr_decl(left_sym.info as ast.FnType, '_var_$left.pos.pos') g.write(' = *(voidptr*)map_get_1(') } else { g.write('$styp _var_$left.pos.pos = *($styp*)map_get_1(') @@ -2329,7 +2328,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { } mut str_add := false mut op_overloaded := false - if var_type == table.string_type_idx && assign_stmt.op == .plus_assign { + if var_type == ast.string_type_idx && assign_stmt.op == .plus_assign { if left is ast.IndexExpr { // a[0] += str => `array_set(&a, 0, &(string[]) {string_add(...))})` g.expr(left) @@ -2362,7 +2361,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if is_inside_ternary && is_decl { g.out.write_string(util.tabs(g.indent - g.inside_ternary)) } - func := right_sym.info as table.FnType + func := right_sym.info as ast.FnType ret_styp := g.typ(func.func.return_type) g.write('$ret_styp (*${g.get_ternary_name(ident.name)}) (') def_pos := g.definitions.len @@ -2429,7 +2428,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if !cloned { if is_fixed_array_copy { i_var := g.new_tmp_var() - fixed_array := right_sym.info as table.ArrayFixed + fixed_array := right_sym.info as ast.ArrayFixed g.write('for (int $i_var=0; $i_var<$fixed_array.size; $i_var++) {') g.expr(left) g.write('[$i_var] = ') @@ -2445,7 +2444,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if val.has_default { g.write('{') g.expr(val.default_expr) - info := right_sym.info as table.ArrayFixed + info := right_sym.info as ast.ArrayFixed for _ in 1 .. info.size { g.write(', ') g.expr(val.default_expr) @@ -2573,7 +2572,7 @@ fn (mut g Gen) get_ternary_name(name string) string { return g.ternary_names[name] } -fn (mut g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, add_eq bool) bool { +fn (mut g Gen) gen_clone_assignment(val ast.Expr, right_sym ast.TypeSymbol, add_eq bool) bool { if val !is ast.Ident && val !is ast.SelectorExpr { return false } @@ -2748,7 +2747,7 @@ fn (mut g Gen) autofree_var_call(free_fn_name string, v ast.Var) { if v.typ.is_ptr() { g.writeln('\t${free_fn_name}(${c_name(v.name)}); // autofreed ptr var') } else { - if v.typ == table.error_type && !v.is_autofree_tmp { + if v.typ == ast.error_type && !v.is_autofree_tmp { return } g.writeln('\t${free_fn_name}(&${c_name(v.name)}); // autofreed var $g.cur_mod.name $g.is_builtin_mod') @@ -2766,7 +2765,7 @@ fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) { } } -fn (mut g Gen) map_fn_ptrs(key_typ table.TypeSymbol) (string, string, string, string) { +fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, string) { mut hash_fn := '' mut key_eq_fn := '' mut clone_fn := '' @@ -2789,9 +2788,9 @@ fn (mut g Gen) map_fn_ptrs(key_typ table.TypeSymbol) (string, string, string, st } .voidptr { ts := if g.pref.m64 { - &g.table.type_symbols[table.u64_type_idx] + &g.table.type_symbols[ast.u64_type_idx] } else { - &g.table.type_symbols[table.u32_type_idx] + &g.table.type_symbols[ast.u32_type_idx] } return g.map_fn_ptrs(ts) } @@ -2937,7 +2936,7 @@ fn (mut g Gen) expr(node ast.Expr) { } else if sym.kind in [.sum_type, .interface_] { g.expr_with_cast(node.expr, node.expr_type, node.typ) } else if sym.kind == .struct_ && !node.typ.is_ptr() - && !(sym.info as table.Struct).is_typedef { + && !(sym.info as ast.Struct).is_typedef { // deprecated, replaced by Struct{...exr} styp := g.typ(node.typ) g.write('*(($styp *)(&') @@ -2946,15 +2945,15 @@ fn (mut g Gen) expr(node ast.Expr) { } else { styp := g.typ(node.typ) mut cast_label := '' - // `table.string_type` is done for MSVC's bug + // `ast.string_type` is done for MSVC's bug if sym.kind != .alias - || (sym.info as table.Alias).parent_type !in [node.expr_type, table.string_type] { + || (sym.info as ast.Alias).parent_type !in [node.expr_type, ast.string_type] { cast_label = '($styp)' } g.write('(${cast_label}(') g.expr(node.expr) if node.expr is ast.IntegerLiteral { - if node.typ in [table.u64_type, table.u32_type, table.u16_type] { + if node.typ in [ast.u64_type, ast.u32_type, ast.u16_type] { if !node.expr.val.starts_with('-') { g.write('U') } @@ -3093,7 +3092,7 @@ fn (mut g Gen) expr(node ast.Expr) { if node.op == .arrow { styp := g.typ(node.right_type) right_sym := g.table.get_type_symbol(node.right_type) - mut right_inf := right_sym.info as table.Chan + mut right_inf := right_sym.info as ast.Chan elem_type := right_inf.elem_type is_gen_or_and_assign_rhs := gen_or && !g.discard_or_result cur_line := if is_gen_or_and_assign_rhs { @@ -3169,7 +3168,7 @@ fn (mut g Gen) expr(node ast.Expr) { ast.SelectorExpr { g.selector_expr(node) } - ast.Type { + ast.TypeNode { // match sum Type // g.write('/* Type */') // type_idx := node.typ.idx() @@ -3200,7 +3199,7 @@ fn (mut g Gen) expr(node ast.Expr) { } // T.name, typeof(expr).name -fn (mut g Gen) type_name(type_ table.Type) { +fn (mut g Gen) type_name(type_ ast.Type) { mut typ := type_ if typ.has_flag(.generic) { typ = g.cur_generic_types[0] @@ -3218,11 +3217,11 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) { g.expr(node.expr) g.write(')._typ ))') } else if sym.kind == .array_fixed { - fixed_info := sym.info as table.ArrayFixed + fixed_info := sym.info as ast.ArrayFixed typ_name := g.table.get_type_name(fixed_info.elem_type) g.write('_SLIT("[$fixed_info.size]${util.strip_main_name(typ_name)}")') } else if sym.kind == .function { - info := sym.info as table.FnType + info := sym.info as ast.FnType g.write('_SLIT("${g.fn_decl_str(info)}")') } else if node.expr_type.has_flag(.variadic) { varg_elem_type_sym := g.table.get_type_symbol(g.table.value_type(node.expr_type)) @@ -3256,7 +3255,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { if node.field_name != 'len' { g.error('field_name should be `len`', node.pos) } - info := sym.info as table.ArrayFixed + info := sym.info as ast.ArrayFixed g.write('$info.size') return } @@ -3286,7 +3285,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { dot := if field.typ.is_ptr() { '->' } else { '.' } sum_type_deref_field += ')$dot' } - if mut cast_sym.info is table.Aggregate { + if mut cast_sym.info is ast.Aggregate { agg_sym := g.table.get_type_symbol(cast_sym.info.types[g.aggregate_type_idx]) sum_type_deref_field += '_$agg_sym.cname' } else { @@ -3302,7 +3301,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { g.write('.data)') } // struct embedding - if sym.info is table.Struct { + if sym.info is ast.Struct { if node.from_embed_type != 0 { embed_sym := g.table.get_type_symbol(node.from_embed_type) embed_name := embed_sym.embed_name() @@ -3342,7 +3341,7 @@ fn (mut g Gen) enum_expr(node ast.Expr) { } } -fn (mut g Gen) infix_gen_equality(node ast.InfixExpr, left_type table.Type, left_sym table.TypeSymbol, right_sym table.TypeSymbol) { +fn (mut g Gen) infix_gen_equality(node ast.InfixExpr, left_type ast.Type, left_sym ast.TypeSymbol, right_sym ast.TypeSymbol) { if left_sym.kind != right_sym.kind { return } @@ -3477,7 +3476,7 @@ fn (mut g Gen) infix_gen_equality(node ast.InfixExpr, left_type table.Type, left } } -fn (mut g Gen) infix_in_or_not_in(node ast.InfixExpr, left_sym table.TypeSymbol, right_sym table.TypeSymbol) { +fn (mut g Gen) infix_in_or_not_in(node ast.InfixExpr, left_sym ast.TypeSymbol, right_sym ast.TypeSymbol) { if node.op == .not_in { g.write('!') } @@ -3544,7 +3543,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { left_sym := g.table.get_type_symbol(left_type) left_final_sym := g.table.get_final_type_symbol(left_type) unaliased_left := if left_sym.kind == .alias { - (left_sym.info as table.Alias).parent_type + (left_sym.info as ast.Alias).parent_type } else { left_type } @@ -3552,12 +3551,12 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { op_is_eq_or_ne := node.op in [.eq, .ne] right_sym := g.table.get_type_symbol(node.right_type) right_final_sym := g.table.get_final_type_symbol(node.right_type) - unaliased_right := if right_sym.info is table.Alias { + unaliased_right := if right_sym.info is ast.Alias { right_sym.info.parent_type } else { node.right_type } - if unaliased_left == table.ustring_type_idx && !op_is_key_in_or_not_in { + if unaliased_left == ast.ustring_type_idx && !op_is_key_in_or_not_in { fn_name := match node.op { .plus { 'ustring_add(' @@ -3590,7 +3589,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.write(', ') g.expr(node.right) g.write(')') - } else if unaliased_left == table.string_type_idx && !op_is_key_in_or_not_in { + } else if unaliased_left == ast.string_type_idx && !op_is_key_in_or_not_in { // `str == ''` -> `str.len == 0` optimization if node.op in [.eq, .ne] && node.right is ast.StringLiteral && (node.right as ast.StringLiteral).val == '' { @@ -3641,7 +3640,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { } else if node.op == .left_shift && left_final_sym.kind == .array { // arr << val tmp := g.new_tmp_var() - info := left_final_sym.info as table.Array + info := left_final_sym.info as ast.Array if right_final_sym.kind == .array && info.elem_type != node.right_type { // push an array => PUSH_MANY, but not if pushing an array to 2d array (`[][]int << []int`) g.write('_PUSH_MANY(') @@ -3672,7 +3671,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.write(', _MOV(($elem_type_str[]){ ') } // if g.autofree - needs_clone := info.elem_type == table.string_type && !g.is_builtin_mod + needs_clone := info.elem_type == ast.string_type && !g.is_builtin_mod if needs_clone { g.write('string_clone(') } @@ -3686,7 +3685,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { // chan <- val gen_or := node.or_block.kind != .absent styp := left_sym.cname - mut left_inf := left_sym.info as table.Chan + mut left_inf := left_sym.info as ast.Chan elem_type := left_inf.elem_type tmp_opt := if gen_or { g.new_tmp_var() } else { '' } if gen_or { @@ -3701,12 +3700,12 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.expr(node.right) g.write(')') if gen_or { - g.or_block(tmp_opt, node.or_block, table.void_type) + g.or_block(tmp_opt, node.or_block, ast.void_type) } - } else if unaliased_left.idx() in [table.u32_type_idx, table.u64_type_idx] + } else if unaliased_left.idx() in [ast.u32_type_idx, ast.u64_type_idx] && unaliased_right.is_signed() && node.op in [.eq, .ne, .gt, .lt, .ge, .le] { - bitsize := if unaliased_left.idx() == table.u32_type_idx - && unaliased_right.idx() != table.i64_type_idx { + bitsize := if unaliased_left.idx() == ast.u32_type_idx + && unaliased_right.idx() != ast.i64_type_idx { 32 } else { 64 @@ -3716,10 +3715,10 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.write(',') g.expr(node.right) g.write(')') - } else if unaliased_right.idx() in [table.u32_type_idx, table.u64_type_idx] + } else if unaliased_right.idx() in [ast.u32_type_idx, ast.u64_type_idx] && unaliased_left.is_signed() && node.op in [.eq, .ne, .gt, .lt, .ge, .le] { - bitsize := if unaliased_right.idx() == table.u32_type_idx - && unaliased_left.idx() != table.i64_type_idx { + bitsize := if unaliased_right.idx() == ast.u32_type_idx + && unaliased_left.idx() != ast.i64_type_idx { 32 } else { 64 @@ -3734,19 +3733,19 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { && left_sym.kind !in [.enum_, .function, .interface_, .sum_type] && left_sym.language != .c b := left_sym.kind != .alias - c := left_sym.kind == .alias && (left_sym.info as table.Alias).language == .c + c := left_sym.kind == .alias && (left_sym.info as ast.Alias).language == .c // Check if aliased type is a struct d := !b - && g.typ((left_sym.info as table.Alias).parent_type).split('__').last()[0].is_capital() + && g.typ((left_sym.info as ast.Alias).parent_type).split('__').last()[0].is_capital() // Do not generate operator overloading with these `right_sym.kind`. e := right_sym.kind !in [.voidptr, .int_literal, .int] if node.op in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && ((a && b && e) || c || d) { // Overloaded operators the_left_type := if !d - || g.table.get_type_symbol((left_sym.info as table.Alias).parent_type).kind in [.array, .array_fixed, .map] { + || g.table.get_type_symbol((left_sym.info as ast.Alias).parent_type).kind in [.array, .array_fixed, .map] { left_type } else { - (left_sym.info as table.Alias).parent_type + (left_sym.info as ast.Alias).parent_type } g.write(g.typ(the_left_type)) g.write('_') @@ -3757,7 +3756,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.expr(node.right) g.write(')') } else if node.op in [.ne, .gt, .ge, .le] && ((a && b && e) || c || d) { - the_left_type := if !d { left_type } else { (left_sym.info as table.Alias).parent_type } + the_left_type := if !d { left_type } else { (left_sym.info as ast.Alias).parent_type } typ := g.typ(the_left_type) if node.op == .gt { g.write('$typ') @@ -3886,7 +3885,7 @@ fn (mut g Gen) lock_expr(node ast.LockExpr) { } fn (mut g Gen) need_tmp_var_in_match(node ast.MatchExpr) bool { - if node.is_expr && node.return_type != table.void_type && node.return_type != 0 { + if node.is_expr && node.return_type != ast.void_type && node.return_type != 0 { sym := g.table.get_type_symbol(node.return_type) if sym.kind == .multi_return { return false @@ -3917,7 +3916,7 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) { return } need_tmp_var := g.need_tmp_var_in_match(node) - is_expr := (node.is_expr && node.return_type != table.void_type) || g.inside_ternary > 0 + is_expr := (node.is_expr && node.return_type != ast.void_type) || g.inside_ternary > 0 mut cond_var := '' mut tmp_var := '' mut cur_line := '' @@ -4009,8 +4008,8 @@ fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var str g.write('${dot_or_ptr}_typ == ') g.expr(branch.exprs[sumtype_index]) } else if sym.kind == .interface_ { - if branch.exprs[sumtype_index] is ast.Type { - typ := branch.exprs[sumtype_index] as ast.Type + if branch.exprs[sumtype_index] is ast.TypeNode { + typ := branch.exprs[sumtype_index] as ast.TypeNode branch_sym := g.table.get_type_symbol(typ.typ) g.write('${dot_or_ptr}_interface_idx == _${sym.cname}_${branch_sym.cname}_index') } else if branch.exprs[sumtype_index] is ast.None && sym.name == 'IError' { @@ -4089,7 +4088,7 @@ fn (mut g Gen) match_expr_classic(node ast.MatchExpr, is_expr bool, cond_var str // if type is unsigned and low is 0, check is unneeded mut skip_low := false if expr.low is ast.IntegerLiteral { - if node.cond_type in [table.u16_type, table.u32_type, table.u64_type] + if node.cond_type in [ast.u16_type, ast.u32_type, ast.u64_type] && expr.low.val == '0' { skip_low = true } @@ -4384,7 +4383,7 @@ fn (mut g Gen) ident(node ast.Ident) { } } dot := if is_ptr { '->' } else { '.' } - if mut cast_sym.info is table.Aggregate { + if mut cast_sym.info is ast.Aggregate { sym := g.table.get_type_symbol(cast_sym.info.types[g.aggregate_type_idx]) g.write('${dot}_$sym.cname') } else { @@ -4565,7 +4564,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) { if branch.smartcast && branch.stmts.len > 0 { infix := branch.cond as ast.InfixExpr if mut infix.left is ast.Ident { - right_type := infix.right as ast.Type + right_type := infix.right as ast.TypeNode left_type := infix.left_type it_type := g.typ(right_type.typ) g.write('\t$it_type* _sc_tmp_$branch.pos.pos = ($it_type*)') @@ -4646,7 +4645,7 @@ fn (mut g Gen) return_statement(node ast.Return) { g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type) g.writeln(' };') return - } else if node.types[0] == table.error_type_idx { + } else if node.types[0] == ast.error_type_idx { // foo() or { return err } styp := g.typ(g.fn_decl.return_type) g.write('return ($styp){.state=2, .err=') @@ -4658,7 +4657,7 @@ fn (mut g Gen) return_statement(node ast.Return) { // regular cases if fn_return_is_multi && node.exprs.len > 0 && !g.expr_is_multi_return_call(node.exprs[0]) { // not_optional_none { //&& !fn_return_is_optional { // typ_sym := g.table.get_type_symbol(g.fn_decl.return_type) - // mr_info := typ_sym.info as table.MultiReturn + // mr_info := typ_sym.info as ast.MultiReturn mut styp := '' mut opt_tmp := '' mut opt_type := '' @@ -4853,15 +4852,15 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) { val := g.out.after(pos) g.out.go_back(val.len) /* - if field.typ == table.byte_type { + if field.typ == ast.byte_type { g.const_decl_simple_define(name, val) return } */ /* - if table.is_number(field.typ) { + if ast.is_number(field.typ) { g.const_decl_simple_define(name, val) - } else if field.typ == table.string_type { + } else if field.typ == ast.string_type { g.definitions.writeln('string _const_$name; // a string literal, inited later') if g.pref.build_mode != .build_module { g.stringliterals.writeln('\t_const_$name = $val;') @@ -4916,7 +4915,7 @@ fn (mut g Gen) const_decl_simple_define(name string, val string) { g.definitions.writeln(val) } -fn (mut g Gen) const_decl_init_later(mod string, name string, val string, typ table.Type, unwrap_option bool) { +fn (mut g Gen) const_decl_init_later(mod string, name string, val string, typ ast.Type, unwrap_option bool) { // Initialize more complex consts in `void _vinit/2{}` // (C doesn't allow init expressions that can't be resolved at compile time). mut styp := g.typ(typ) @@ -5061,7 +5060,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { // `inited_fields` is a list of fields that have been init'ed, they are skipped // mut nr_fields := 0 if sym.kind == .struct_ { - info := sym.info as table.Struct + info := sym.info as ast.Struct if info.is_union && struct_init.fields.len > 1 { verror('union must not have more than 1 initializer') } @@ -5085,7 +5084,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { // g.zero_struct_fields(info, inited_fields) // nr_fields = info.fields.len for field in info.fields { - if mut sym.info is table.Struct { + if mut sym.info is ast.Struct { equal_fields := sym.info.fields.filter(it.name == field.name) if equal_fields.len == 0 { continue @@ -5168,23 +5167,22 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { } } -fn (mut g Gen) zero_struct_field(field table.Field) { +fn (mut g Gen) zero_struct_field(field ast.StructField) { field_name := c_name(field.name) g.write('.$field_name = ') sym := g.table.get_type_symbol(field.typ) - defex := ast.fe2ex(field.default_expr) if field.has_default_expr { if sym.kind in [.sum_type, .interface_] { - g.expr_with_cast(defex, field.default_expr_typ, field.typ) + g.expr_with_cast(field.default_expr, field.default_expr_typ, field.typ) return } - g.expr(defex) + g.expr(field.default_expr) } else { g.write(g.type_default(field.typ)) } } -// fn (mut g Gen) zero_struct_fields(info table.Struct, inited_fields map[string]int) { +// fn (mut g Gen) zero_struct_fields(info ast.Struct, inited_fields map[string]int) { // } // { user | name: 'new name' } fn (mut g Gen) assoc(node ast.Assoc) { @@ -5200,7 +5198,7 @@ fn (mut g Gen) assoc(node ast.Assoc) { } // Merge inited_fields in the rest of the fields. sym := g.table.get_type_symbol(node.typ) - info := sym.info as table.Struct + info := sym.info as ast.Struct for field in info.fields { field_name := c_name(field.name) if field.name in inited_fields { @@ -5262,7 +5260,7 @@ fn (mut g Gen) write_init_function() { g.write(g.inits[mod_name].str()) init_fn_name := '${mod_name}.init' if initfn := g.table.find_fn(init_fn_name) { - if initfn.return_type == table.void_type && initfn.params.len == 0 { + if initfn.return_type == ast.void_type && initfn.params.len == 0 { mod_c_name := util.no_dots(mod_name) init_fn_c_name := '${mod_c_name}__init' g.writeln('\t${init_fn_c_name}();') @@ -5316,7 +5314,7 @@ const ( ) fn (mut g Gen) write_builtin_types() { - mut builtin_types := []table.TypeSymbol{} // builtin types + mut builtin_types := []ast.TypeSymbol{} // builtin types // builtin types need to be on top // everything except builtin will get sorted for builtin_name in c.builtins { @@ -5342,7 +5340,7 @@ fn (mut g Gen) write_builtin_types() { // Sort the types, make sure types that are referenced by other types // are added before them. fn (mut g Gen) write_sorted_types() { - mut types := []table.TypeSymbol{} // structs that need to be sorted + mut types := []ast.TypeSymbol{} // structs that need to be sorted for typ in g.table.type_symbols { if typ.name !in c.builtins { types << typ @@ -5356,7 +5354,7 @@ fn (mut g Gen) write_sorted_types() { g.write_types(types_sorted) } -fn (mut g Gen) write_types(types []table.TypeSymbol) { +fn (mut g Gen) write_types(types []ast.TypeSymbol) { for typ in types { if typ.name.starts_with('C.') { continue @@ -5364,7 +5362,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { // sym := g.table.get_type_symbol(typ) mut name := typ.cname match mut typ.info { - table.Struct { + ast.Struct { if typ.info.generic_types.len > 0 { continue } @@ -5410,10 +5408,10 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { // g.type_definitions.writeln('};\n') } - table.Alias { - // table.Alias { TODO + ast.Alias { + // ast.Alias { TODO } - table.Thread { + ast.Thread { if g.pref.os == .windows { if name == '__v_thread' { g.type_definitions.writeln('typedef HANDLE $name;') @@ -5429,7 +5427,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { g.type_definitions.writeln('typedef pthread_t $name;') } } - table.SumType { + ast.SumType { g.typedefs.writeln('typedef struct $name $name;') g.type_definitions.writeln('') g.type_definitions.writeln('// Union sum type $name = ') @@ -5453,7 +5451,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { g.type_definitions.writeln('};') g.type_definitions.writeln('') } - table.ArrayFixed { + ast.ArrayFixed { elem_sym := g.table.get_type_symbol(typ.info.elem_type) if !elem_sym.is_builtin() { // .array_fixed { @@ -5465,7 +5463,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { if fixed.starts_with('C__') { fixed = fixed[3..] } - if elem_sym.info is table.FnType { + if elem_sym.info is ast.FnType { pos := g.out.len g.write_fn_ptr_decl(&elem_sym.info, '') fixed = g.out.after(pos) @@ -5484,7 +5482,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { } // sort structs by dependant fields -fn (g &Gen) sort_structs(typesa []table.TypeSymbol) []table.TypeSymbol { +fn (g &Gen) sort_structs(typesa []ast.TypeSymbol) []ast.TypeSymbol { mut dep_graph := depgraph.new_dep_graph() // types name list mut type_names := []string{} @@ -5500,13 +5498,13 @@ fn (g &Gen) sort_structs(typesa []table.TypeSymbol) []table.TypeSymbol { // create list of deps mut field_deps := []string{} match mut t.info { - table.ArrayFixed { + ast.ArrayFixed { dep := g.table.get_type_symbol(t.info.elem_type).name if dep in type_names { field_deps << dep } } - table.Struct { + ast.Struct { for embed in t.info.embeds { dep := g.table.get_type_symbol(embed).name // skip if not in types list or already in deps @@ -5524,7 +5522,7 @@ fn (g &Gen) sort_structs(typesa []table.TypeSymbol) []table.TypeSymbol { field_deps << dep } } - // table.Interface {} + // ast.Interface {} else {} } // add type and dependant types to graph @@ -5541,7 +5539,7 @@ fn (g &Gen) sort_structs(typesa []table.TypeSymbol) []table.TypeSymbol { '\nif you feel this is an error, please create a new issue here: https://github.com/vlang/v/issues and tag @joe-conigliaro') } // sort types - mut types_sorted := []table.TypeSymbol{} + mut types_sorted := []ast.TypeSymbol{} for node in dep_graph_sorted.nodes { types_sorted << g.table.type_symbols[g.table.type_idxs[node.name]] } @@ -5584,7 +5582,7 @@ fn (mut g Gen) write_expr_to_string(expr ast.Expr) string { // to access its fields (`.ok`, `.error` etc) // `os.cp(...)` => `Option bool tmp = os__cp(...); if (tmp.state != 0) { ... }` // Returns the type of the last stmt -fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table.Type) { +fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Type) { cvar_name := c_name(var_name) mr_styp := g.base_type(return_type) is_none_ok := mr_styp == 'void' @@ -5606,7 +5604,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table. } stmts := or_block.stmts if stmts.len > 0 && stmts[or_block.stmts.len - 1] is ast.ExprStmt - && (stmts[stmts.len - 1] as ast.ExprStmt).typ != table.void_type { + && (stmts[stmts.len - 1] as ast.ExprStmt).typ != ast.void_type { g.indent++ for i, stmt in stmts { if i == stmts.len - 1 { @@ -5647,7 +5645,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table. // the defered statements are generated. g.write_defer_stmts() // Now that option types are distinct we need a cast here - if g.fn_decl.return_type == table.void_type { + if g.fn_decl.return_type == ast.void_type { g.writeln('\treturn;') } else { styp := g.typ(g.fn_decl.return_type) @@ -5663,7 +5661,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table. // `a in [1,2,3]` => `a == 1 || a == 2 || a == 3` fn (mut g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) { - is_str := right.elem_type == table.string_type + is_str := right.elem_type == ast.string_type elem_sym := g.table.get_type_symbol(right.elem_type) is_array := elem_sym.kind == .array for i, array_expr in right.exprs { @@ -5711,7 +5709,7 @@ fn c_name(name_ string) string { return name } -fn (mut g Gen) type_default(typ_ table.Type) string { +fn (mut g Gen) type_default(typ_ ast.Type) string { typ := g.unwrap_generic(typ_) if typ.has_flag(.optional) { return '{0}' @@ -5740,12 +5738,12 @@ fn (mut g Gen) type_default(typ_ table.Type) string { if sym.kind == .struct_ { mut has_none_zero := false mut init_str := '{' - info := sym.info as table.Struct + info := sym.info as ast.Struct for field in info.fields { field_sym := g.table.get_type_symbol(field.typ) if field_sym.kind in [.array, .map] || field.has_default_expr { if field.has_default_expr { - expr_str := g.expr_string(ast.fe2ex(field.default_expr)) + expr_str := g.expr_string(field.default_expr) init_str += '.$field.name = $expr_str,' } else { init_str += '.$field.name = ${g.type_default(field.typ)},' @@ -5772,7 +5770,7 @@ fn (mut g Gen) type_default(typ_ table.Type) string { } /* match idx { - table.bool_type_idx { + ast.bool_type_idx { return '0' } else {} @@ -5789,7 +5787,7 @@ fn (mut g Gen) type_default(typ_ table.Type) string { } return match sym.kind { .interface_, .sum_type, .array_fixed, .multi_return { '{0}' } - .alias { g.type_default((sym.info as table.Alias).parent_type) } + .alias { g.type_default((sym.info as ast.Alias).parent_type) } else { '0' } } // TODO this results in @@ -5854,7 +5852,7 @@ fn (mut g Gen) go_stmt(node ast.GoStmt, joinable bool) string { mut name := expr.name // util.no_dots(expr.name) // TODO: fn call is duplicated. merge with fn_call(). for i, generic_type in expr.generic_types { - if generic_type != table.void_type && generic_type != 0 { + if generic_type != ast.void_type && generic_type != 0 { // Using _T_ to differentiate between get and get_string // `foo()` => `foo_T_int()` if i == 0 { @@ -5905,25 +5903,25 @@ fn (mut g Gen) go_stmt(node ast.GoStmt, joinable bool) string { g.writeln(';') } s_ret_typ := g.typ(node.call_expr.return_type) - if g.pref.os == .windows && node.call_expr.return_type != table.void_type { + if g.pref.os == .windows && node.call_expr.return_type != ast.void_type { g.writeln('$arg_tmp_var->ret_ptr = malloc(sizeof($s_ret_typ));') } is_opt := node.call_expr.return_type.has_flag(.optional) mut gohandle_name := '' - if node.call_expr.return_type == table.void_type { + if node.call_expr.return_type == ast.void_type { gohandle_name = if is_opt { '__v_thread_Option_void' } else { '__v_thread' } } else { opt := if is_opt { 'Option_' } else { '' } gohandle_name = '__v_thread_$opt${g.table.get_type_symbol(g.unwrap_generic(node.call_expr.return_type)).cname}' } if g.pref.os == .windows { - simple_handle := if joinable && node.call_expr.return_type != table.void_type { + simple_handle := if joinable && node.call_expr.return_type != ast.void_type { 'thread_handle_$tmp' } else { 'thread_$tmp' } g.writeln('HANDLE $simple_handle = CreateThread(0,0, (LPTHREAD_START_ROUTINE)$wrapper_fn_name, $arg_tmp_var, 0,0);') - if joinable && node.call_expr.return_type != table.void_type { + if joinable && node.call_expr.return_type != ast.void_type { g.writeln('$gohandle_name thread_$tmp = {') g.writeln('\t.ret_ptr = $arg_tmp_var->ret_ptr,') g.writeln('\t.handle = thread_handle_$tmp') @@ -5947,12 +5945,12 @@ fn (mut g Gen) go_stmt(node ast.GoStmt, joinable bool) string { if waiter_fn_name !in g.waiter_fns { g.gowrappers.writeln('\n$s_ret_typ ${waiter_fn_name}($gohandle_name thread) {') mut c_ret_ptr_ptr := 'NULL' - if node.call_expr.return_type != table.void_type { + if node.call_expr.return_type != ast.void_type { g.gowrappers.writeln('\t$s_ret_typ* ret_ptr;') c_ret_ptr_ptr = '&ret_ptr' } if g.pref.os == .windows { - if node.call_expr.return_type == table.void_type { + if node.call_expr.return_type == ast.void_type { g.gowrappers.writeln('\tu32 stat = WaitForSingleObject(thread, INFINITE);') } else { g.gowrappers.writeln('\tu32 stat = WaitForSingleObject(thread.handle, INFINITE);') @@ -5963,13 +5961,13 @@ fn (mut g Gen) go_stmt(node ast.GoStmt, joinable bool) string { } g.gowrappers.writeln('\tif (stat != 0) { v_panic(_SLIT("unable to join thread")); }') if g.pref.os == .windows { - if node.call_expr.return_type == table.void_type { + if node.call_expr.return_type == ast.void_type { g.gowrappers.writeln('\tCloseHandle(thread);') } else { g.gowrappers.writeln('\tCloseHandle(thread.handle);') } } - if node.call_expr.return_type != table.void_type { + if node.call_expr.return_type != ast.void_type { g.gowrappers.writeln('\t$s_ret_typ ret = *ret_ptr;') g.gowrappers.writeln('\tfree(ret_ptr);') g.gowrappers.writeln('\treturn ret;') @@ -5989,7 +5987,7 @@ fn (mut g Gen) go_stmt(node ast.GoStmt, joinable bool) string { styp := g.typ(expr.receiver_type) g.type_definitions.writeln('\t$styp arg0;') } - need_return_ptr := g.pref.os == .windows && node.call_expr.return_type != table.void_type + need_return_ptr := g.pref.os == .windows && node.call_expr.return_type != ast.void_type if expr.args.len == 0 && !need_return_ptr { g.type_definitions.writeln('EMPTY_STRUCT_DECLARATION;') } else { @@ -6005,7 +6003,7 @@ fn (mut g Gen) go_stmt(node ast.GoStmt, joinable bool) string { thread_ret_type := if g.pref.os == .windows { 'u32' } else { 'void*' } g.type_definitions.writeln('$thread_ret_type ${wrapper_fn_name}($wrapper_struct_name *arg);') g.gowrappers.writeln('$thread_ret_type ${wrapper_fn_name}($wrapper_struct_name *arg) {') - if node.call_expr.return_type != table.void_type { + if node.call_expr.return_type != ast.void_type { if g.pref.os == .windows { g.gowrappers.write_string('\t*(($s_ret_typ*)(arg->ret_ptr)) = ') } else { @@ -6030,7 +6028,7 @@ fn (mut g Gen) go_stmt(node ast.GoStmt, joinable bool) string { } g.gowrappers.writeln(');') g.gowrappers.writeln('\tfree(arg);') - if g.pref.os != .windows && node.call_expr.return_type != table.void_type { + if g.pref.os != .windows && node.call_expr.return_type != ast.void_type { g.gowrappers.writeln('\treturn ret_ptr;') } else { g.gowrappers.writeln('\treturn 0;') @@ -6047,7 +6045,7 @@ fn (mut g Gen) as_cast(node ast.AsCast) { styp := g.typ(node.typ) sym := g.table.get_type_symbol(node.typ) expr_type_sym := g.table.get_type_symbol(node.expr_type) - if expr_type_sym.info is table.SumType { + if expr_type_sym.info is ast.SumType { dot := if node.expr_type.is_ptr() { '->' } else { '.' } g.write('/* as */ *($styp*)__as_cast(') g.write('(') @@ -6080,15 +6078,15 @@ fn (g Gen) as_cast_name_table() string { if g.as_cast_type_names.len == 0 { return 'new_array_from_c_array(1, 1, sizeof(VCastTypeIndexName), _MOV((VCastTypeIndexName[1]){(VCastTypeIndexName){.tindex = 0,.tname = _SLIT("unknown")}}));' } - mut name_table := strings.new_builder(1024) + mut name_ast := strings.new_builder(1024) casts_len := g.as_cast_type_names.len + 1 - name_table.writeln('new_array_from_c_array($casts_len, $casts_len, sizeof(VCastTypeIndexName), _MOV((VCastTypeIndexName[$casts_len]){') - name_table.writeln('\t\t (VCastTypeIndexName){.tindex = 0, .tname = _SLIT("unknown")}') + name_ast.writeln('new_array_from_c_array($casts_len, $casts_len, sizeof(VCastTypeIndexName), _MOV((VCastTypeIndexName[$casts_len]){') + name_ast.writeln('\t\t (VCastTypeIndexName){.tindex = 0, .tname = _SLIT("unknown")}') for key, value in g.as_cast_type_names { - name_table.writeln('\t\t, (VCastTypeIndexName){.tindex = $key, .tname = _SLIT("$value")}') + name_ast.writeln('\t\t, (VCastTypeIndexName){.tindex = $key, .tname = _SLIT("$value")}') } - name_table.writeln('\t}));') - return name_table.str() + name_ast.writeln('\t}));') + return name_ast.str() } fn (mut g Gen) is_expr(node ast.InfixExpr) { @@ -6106,9 +6104,9 @@ fn (mut g Gen) is_expr(node ast.InfixExpr) { g.write('_interface_idx $eq ') // `_Animal_Dog_index` sub_type := match mut node.right { - ast.Type { node.right.typ } + ast.TypeNode { node.right.typ } ast.None { g.table.type_idxs['None__'] } - else { table.Type(0) } + else { ast.Type(0) } } sub_sym := g.table.get_type_symbol(sub_type) g.write('_${c_name(sym.name)}_${c_name(sub_sym.name)}_index') @@ -6126,7 +6124,7 @@ fn (mut g Gen) interface_table() string { if ityp.kind != .interface_ { continue } - inter_info := ityp.info as table.Interface + inter_info := ityp.info as ast.Interface // interface_name is for example Speaker interface_name := ityp.cname // generate a struct that references interface methods @@ -6250,7 +6248,7 @@ $staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}( methods_wrapper.write_string(g.out.cut_last(g.out.len - params_start_pos)) methods_wrapper.writeln(') {') methods_wrapper.write_string('\t') - if method.return_type != table.void_type { + if method.return_type != ast.void_type { methods_wrapper.write_string('return ') } methods_wrapper.writeln('${method_call}(*${fargs.join(', ')});') diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index b3bc2d2d93..45dd41b7c0 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -5,7 +5,6 @@ module c import os import v.ast -import v.table import v.util fn (mut g Gen) comptime_selector(node ast.ComptimeSelector) { @@ -123,7 +122,7 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) { } else { // last argument; try to expand if it's []string idx := i - node.args.len - if m.params[i].typ.is_int() || m.params[i].typ.idx() == table.bool_type_idx { + if m.params[i].typ.is_int() || m.params[i].typ.idx() == ast.bool_type_idx { // Gets the type name and cast the string to the type with the string_ function type_name := g.table.type_symbols[int(m.params[i].typ)].str() g.write('string_${type_name}(((string*)${node.args[node.args.len - 1]}.data) [$idx])') @@ -140,7 +139,7 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) { } mut j := 0 for method in node.sym.methods { - // if method.return_type != table.void_type { + // if method.return_type != ast.void_type { if method.return_type != node.result_type { continue } @@ -165,7 +164,7 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) { } } -fn cgen_attrs(attrs []table.Attr) []string { +fn cgen_attrs(attrs []ast.Attr) []string { mut res := []string{cap: attrs.len} for attr in attrs { // we currently don't quote 'arg' (otherwise we could just use `s := attr.str()`) @@ -287,12 +286,12 @@ fn (mut g Gen) comp_if_cond(cond ast.Expr) bool { .key_is, .not_is { left := cond.left mut name := '' - mut exp_type := table.Type(0) - got_type := (cond.right as ast.Type).typ + mut exp_type := ast.Type(0) + got_type := (cond.right as ast.TypeNode).typ if left is ast.SelectorExpr { name = '${left.expr}.$left.field_name' exp_type = g.comptime_var_type_map[name] - } else if left is ast.Type { + } else if left is ast.TypeNode { name = left.str() // this is only allowed for generics currently, otherwise blocked by checker exp_type = g.unwrap_generic(left.typ) @@ -333,7 +332,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) { sym := g.table.get_type_symbol(g.unwrap_generic(node.typ)) g.writeln('/* \$for $node.val_var in ${sym.name}($node.kind.str()) */ {') g.indent++ - // vweb_result_type := table.new_type(g.table.find_type_idx('vweb.Result')) + // vweb_result_type := ast.new_type(g.table.find_type_idx('vweb.Result')) mut i := 0 // g.writeln('string method = _SLIT("");') if node.kind == .methods { @@ -345,7 +344,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) { } for method in methods { // sym.methods { /* - if method.return_type != vweb_result_type { // table.void_type { + if method.return_type != vweb_result_type { // ast.void_type { continue } */ @@ -414,7 +413,7 @@ fn (mut g Gen) comp_for(node ast.CompFor) { } } else if node.kind == .fields { // TODO add fields - if sym.info is table.Struct { + if sym.info is ast.Struct { mut fields := sym.info.fields.filter(it.attrs.len == 0) fields_with_attrs := sym.info.fields.filter(it.attrs.len > 0) fields << fields_with_attrs diff --git a/vlib/v/gen/c/ctempvars.v b/vlib/v/gen/c/ctempvars.v index 73b5b147a2..f0484ed45a 100644 --- a/vlib/v/gen/c/ctempvars.v +++ b/vlib/v/gen/c/ctempvars.v @@ -1,9 +1,8 @@ module c import v.ast -import v.table -fn (mut g Gen) new_ctemp_var(expr ast.Expr, expr_type table.Type) ast.CTempVar { +fn (mut g Gen) new_ctemp_var(expr ast.Expr, expr_type ast.Type) ast.CTempVar { return ast.CTempVar{ name: g.new_tmp_var() typ: expr_type @@ -12,7 +11,7 @@ fn (mut g Gen) new_ctemp_var(expr ast.Expr, expr_type table.Type) ast.CTempVar { } } -fn (mut g Gen) new_ctemp_var_then_gen(expr ast.Expr, expr_type table.Type) ast.CTempVar { +fn (mut g Gen) new_ctemp_var_then_gen(expr ast.Expr, expr_type ast.Type) ast.CTempVar { x := g.new_ctemp_var(expr, expr_type) g.gen_ctemp_var(x) return x diff --git a/vlib/v/gen/c/dumpexpr.v b/vlib/v/gen/c/dumpexpr.v index f6d2a607b8..e67ff517df 100644 --- a/vlib/v/gen/c/dumpexpr.v +++ b/vlib/v/gen/c/dumpexpr.v @@ -1,7 +1,6 @@ module c import v.ast -import v.table fn (mut g Gen) dump_expr(node ast.DumpExpr) { sexpr := ctoslit(node.expr.str()) @@ -20,7 +19,7 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) { fn (mut g Gen) dump_expr_definitions() { if g.pref.build_mode == .build_module { for dump_type, cname in g.table.dumps { - is_ptr := table.Type(dump_type).is_ptr() + is_ptr := ast.Type(dump_type).is_ptr() ptr_suffix := if is_ptr { '*' } else { '' } dump_fn_name := '_v_dump_expr_$cname' + (if is_ptr { '_ptr' } else { '' }) g.definitions.writeln('$cname$ptr_suffix ${dump_fn_name}(string fpath, int line, string sexpr, $cname$ptr_suffix x) {') @@ -28,7 +27,7 @@ fn (mut g Gen) dump_expr_definitions() { } else { for dump_type, cname in g.table.dumps { to_string_fn_name := g.gen_str_for_type(dump_type) - is_ptr := table.Type(dump_type).is_ptr() + is_ptr := ast.Type(dump_type).is_ptr() ptr_astarisk := if is_ptr { '*' } else { '' } dump_fn_name := '_v_dump_expr_$cname' + (if is_ptr { '_ptr' } else { '' }) g.definitions.writeln('$cname$ptr_astarisk ${dump_fn_name}(string fpath, int line, string sexpr, $cname$ptr_astarisk x) {') diff --git a/vlib/v/gen/c/embed.v b/vlib/v/gen/c/embed.v index 690dd3f7de..22eb05ef19 100644 --- a/vlib/v/gen/c/embed.v +++ b/vlib/v/gen/c/embed.v @@ -30,7 +30,7 @@ fn (mut g Gen) gen_embed_file_init(node ast.ComptimeCall) { g.writeln('} // \$embed_file("$node.embed_file.apath")') } -// gen_embedded_data embeds data into the V target executable. +// gen_embedded_data embeds data into the V target execuast. fn (mut g Gen) gen_embedded_data() { /* TODO implement compression. diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index b5bd895a79..73125609a6 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -4,7 +4,6 @@ module c import v.ast -import v.table import v.util fn (mut g Gen) is_used_by_main(node ast.FnDecl) bool { @@ -302,7 +301,7 @@ fn (mut g Gen) gen_fn_decl(node ast.FnDecl, skip bool) { } else { g.defer_stmts = [] } - if node.return_type != table.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return { + if node.return_type != ast.void_type && node.stmts.len > 0 && node.stmts.last() !is ast.Return { default_expr := g.type_default(node.return_type) // TODO: perf? if default_expr == '{0}' { @@ -353,7 +352,7 @@ fn (mut g Gen) write_defer_stmts_when_needed() { } // fn decl args -fn (mut g Gen) fn_args(args []table.Param, is_variadic bool) ([]string, []string) { +fn (mut g Gen) fn_args(args []ast.Param, is_variadic bool) ([]string, []string) { mut fargs := []string{} mut fargtypes := []string{} if args.len == 0 { @@ -366,7 +365,7 @@ fn (mut g Gen) fn_args(args []table.Param, is_variadic bool) ([]string, []string arg_type_sym := g.table.get_type_symbol(typ) mut arg_type_name := g.typ(typ) // util.no_dots(arg_type_sym.name) if arg_type_sym.kind == .function { - info := arg_type_sym.info as table.FnType + info := arg_type_sym.info as ast.FnType func := info.func if !info.is_anon { g.write(arg_type_name + ' ' + caname) @@ -449,7 +448,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { if is_gen_or_and_assign_rhs { unwrapped_typ := node.return_type.clear_flag(.optional) unwrapped_styp := g.typ(unwrapped_typ) - if unwrapped_typ == table.void_type { + if unwrapped_typ == ast.void_type { g.write('\n $cur_line') } else if g.table.get_type_symbol(node.return_type).kind == .multi_return { g.write('\n $cur_line $tmp_opt /*U*/') @@ -462,7 +461,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { } } -pub fn (g &Gen) unwrap_generic(typ table.Type) table.Type { +pub fn (g &Gen) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) { sym := g.table.get_type_symbol(typ) for i, generic_param in g.cur_fn.generic_params { @@ -486,7 +485,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { typ_sym := g.table.get_type_symbol(unwrapped_rec_type) rec_cc_type := g.cc_type(unwrapped_rec_type, false) mut receiver_type_name := util.no_dots(rec_cc_type) - if typ_sym.kind == .interface_ && (typ_sym.info as table.Interface).defines_method(node.name) { + if typ_sym.kind == .interface_ && (typ_sym.info as ast.Interface).defines_method(node.name) { // Speaker_name_table[s._interface_idx].speak(s._object) $if debug_interface_method_call ? { eprintln('>>> interface typ_sym.name: $typ_sym.name | receiver_type_name: $receiver_type_name') @@ -628,7 +627,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } } for i, generic_type in node.generic_types { - if generic_type != table.void_type && generic_type != 0 { + if generic_type != ast.void_type && generic_type != 0 { // Using _T_ to differentiate between get and get_string // `foo()` => `foo_T_int()` if i == 0 { @@ -767,7 +766,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { g.writeln('string $tmp2 = json__json_print_pretty($json_obj);') } } else { - ast_type := node.args[0].expr as ast.Type + ast_type := node.args[0].expr as ast.TypeNode // `json.decode(User, s)` => json.decode_User(s) typ := c_name(g.typ(ast_type.typ)) fn_name := c_name(name) + '_' + typ @@ -818,18 +817,18 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { // g.generate_tmp_autofree_arg_vars(node, name) // Handle `print(x)` mut print_auto_str := false - if is_print && node.args[0].typ != table.string_type { // && !free_tmp_arg_vars { + if is_print && node.args[0].typ != ast.string_type { // && !free_tmp_arg_vars { mut typ := node.args[0].typ if typ == 0 { g.checker_bug('print arg.typ is 0', node.pos) } mut sym := g.table.get_type_symbol(typ) - if mut sym.info is table.Alias { + if mut sym.info is ast.Alias { typ = sym.info.parent_type sym = g.table.get_type_symbol(typ) } // check if alias parent also not a string - if typ != table.string_type { + if typ != ast.string_type { expr := node.args[0].expr if g.is_autofree && !typ.has_flag(.optional) { // Create a temporary variable so that the value can be freed @@ -930,7 +929,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) { } else { scope.register(ast.Var{ name: t - typ: table.string_type + typ: ast.string_type is_autofree_tmp: true pos: node.pos }) @@ -1009,7 +1008,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) { if is_variadic && i == expected_types.len - 1 { break } - use_tmp_var_autofree := g.is_autofree && arg.typ == table.string_type && arg.is_tmp_autofree + use_tmp_var_autofree := g.is_autofree && arg.typ == ast.string_type && arg.is_tmp_autofree && !g.inside_const && !g.is_builtin_mod // g.write('/* af=$arg.is_tmp_autofree */') // some c fn definitions dont have args (cfns.v) or are not updated in checker @@ -1053,7 +1052,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) { varg_type := expected_types.last() variadic_count := args.len - arg_nr arr_sym := g.table.get_type_symbol(varg_type) - mut arr_info := arr_sym.info as table.Array + mut arr_info := arr_sym.info as ast.Array if varg_type.has_flag(.generic) { if fn_def := g.table.find_fn(node.name) { varg_type_name := g.table.type_to_str(varg_type) @@ -1088,9 +1087,9 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } [inline] -fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type, lang table.Language) { - arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in table.pointer_type_idxs - expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in table.pointer_type_idxs +fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language) { + arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in ast.pointer_type_idxs + expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in ast.pointer_type_idxs if expected_type == 0 { g.checker_bug('ref_or_deref_arg expected_type is 0', arg.pos) } @@ -1158,7 +1157,7 @@ fn (g &Gen) fileis(s string) bool { return g.file.path.contains(s) } -fn (mut g Gen) write_fn_attrs(attrs []table.Attr) string { +fn (mut g Gen) write_fn_attrs(attrs []ast.Attr) string { mut msvc_attrs := '' for attr in attrs { match attr.name { diff --git a/vlib/v/gen/c/index.v b/vlib/v/gen/c/index.v index e5ba1d45c5..18cb7e095b 100644 --- a/vlib/v/gen/c/index.v +++ b/vlib/v/gen/c/index.v @@ -4,7 +4,6 @@ module c import v.ast -import v.table import v.util fn (mut g Gen) index_expr(node ast.IndexExpr) { @@ -46,7 +45,7 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) { g.expr(node.left) } else if sym.kind == .array_fixed { // Convert a fixed array to V array when doing `fixed_arr[start..end]` - info := sym.info as table.ArrayFixed + info := sym.info as ast.ArrayFixed g.write('array_slice(new_array_from_c_array(') g.write('$info.size') g.write(', $info.size') @@ -77,7 +76,7 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) { if range.has_high { g.expr(range.high) } else if sym.kind == .array_fixed { - info := sym.info as table.ArrayFixed + info := sym.info as ast.ArrayFixed g.write('$info.size') } else if node.left_type.is_ptr() { g.write('(') @@ -92,10 +91,10 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) { g.write(')') } -fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) { +fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) { gen_or := node.or_expr.kind != .absent || node.is_option left_is_ptr := node.left_type.is_ptr() - info := sym.info as table.Array + info := sym.info as ast.Array elem_type_str := g.typ(info.elem_type) elem_type := info.elem_type elem_typ := g.table.get_type_symbol(elem_type) @@ -104,7 +103,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) { is_selector := node.left is ast.SelectorExpr if g.is_assign_lhs && !is_selector && node.is_setter { is_direct_array_access := g.fn_decl != 0 && g.fn_decl.is_direct_arr - is_op_assign := g.assign_op != .assign && info.elem_type != table.string_type + is_op_assign := g.assign_op != .assign && info.elem_type != ast.string_type array_ptr_type_str := match elem_typ.kind { .function { 'voidptr*' } else { '$elem_type_str*' } @@ -175,7 +174,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) { .function { 'voidptr*' } else { '$elem_type_str*' } } - needs_clone := info.elem_type == table.string_type_idx && g.is_autofree && !g.is_assign_lhs + needs_clone := info.elem_type == ast.string_type_idx && g.is_autofree && !g.is_assign_lhs is_gen_or_and_assign_rhs := gen_or && !g.discard_or_result cur_line := if is_gen_or_and_assign_rhs { line := g.go_before_stmt(0) @@ -193,7 +192,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) { g.write('/*2*/string_clone(') } if g.is_fn_index_call { - if elem_typ.info is table.FnType { + if elem_typ.info is ast.FnType { g.write('((') g.write_fn_ptr_decl(&elem_typ.info, '') g.write(')(*($array_ptr_type_str)/*ee elem_typ */array_get(') @@ -257,11 +256,11 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym table.TypeSymbol) { } } -fn (mut g Gen) index_of_fixed_array(node ast.IndexExpr, sym table.TypeSymbol) { - info := sym.info as table.ArrayFixed +fn (mut g Gen) index_of_fixed_array(node ast.IndexExpr, sym ast.TypeSymbol) { + info := sym.info as ast.ArrayFixed elem_type := info.elem_type elem_sym := g.table.get_type_symbol(elem_type) - is_fn_index_call := g.is_fn_index_call && elem_sym.info is table.FnType + is_fn_index_call := g.is_fn_index_call && elem_sym.info is ast.FnType if is_fn_index_call { g.write('(*') @@ -289,17 +288,17 @@ fn (mut g Gen) index_of_fixed_array(node ast.IndexExpr, sym table.TypeSymbol) { } } -fn (mut g Gen) index_of_map(node ast.IndexExpr, sym table.TypeSymbol) { +fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) { gen_or := node.or_expr.kind != .absent || node.is_option left_is_ptr := node.left_type.is_ptr() - info := sym.info as table.Map + info := sym.info as ast.Map key_type_str := g.typ(info.key_type) elem_type := info.value_type elem_type_str := g.typ(elem_type) elem_typ := g.table.get_type_symbol(elem_type) get_and_set_types := elem_typ.kind in [.struct_, .map] if g.is_assign_lhs && !g.is_arraymap_set && !get_and_set_types { - if g.assign_op == .assign || info.value_type == table.string_type { + if g.assign_op == .assign || info.value_type == ast.string_type { g.is_arraymap_set = true g.write('map_set_1(') } else { @@ -335,7 +334,7 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym table.TypeSymbol) { g.arraymap_set_pos = g.out.len g.write(', &($elem_type_str[]) { ') } - if g.assign_op != .assign && info.value_type != table.string_type { + if g.assign_op != .assign && info.value_type != ast.string_type { zero := g.type_default(info.value_type) g.write('$zero })))') } @@ -370,7 +369,7 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym table.TypeSymbol) { g.write('$elem_type_str* $tmp_opt_ptr = ($elem_type_str*)/*ee elem_ptr_typ */(map_get_1_check(') } else { if g.is_fn_index_call { - if elem_typ.info is table.FnType { + if elem_typ.info is ast.FnType { g.write('((') g.write_fn_ptr_decl(&elem_typ.info, '') g.write(')(*(voidptr*)map_get_1(') diff --git a/vlib/v/gen/c/json.v b/vlib/v/gen/c/json.v index 018cb373e5..9acd2be821 100644 --- a/vlib/v/gen/c/json.v +++ b/vlib/v/gen/c/json.v @@ -3,7 +3,7 @@ // that can be found in the LICENSE file. module c -import v.table +import v.ast import v.util import strings @@ -18,7 +18,7 @@ import strings // return res; // } // Codegen json_decode/encode funcs -fn (mut g Gen) gen_json_for_type(typ table.Type) { +fn (mut g Gen) gen_json_for_type(typ ast.Type) { utyp := g.unwrap_generic(typ) mut dec := strings.new_builder(100) mut enc := strings.new_builder(100) @@ -73,13 +73,13 @@ $enc_fn_dec { // enc += g.encode_array(t) } else if sym.kind == .map { // Handle maps - m := sym.info as table.Map + m := sym.info as ast.Map g.gen_json_for_type(m.key_type) g.gen_json_for_type(m.value_type) dec.writeln(g.decode_map(m.key_type, m.value_type)) enc.writeln(g.encode_map(m.key_type, m.value_type)) } else if sym.kind == .alias { - a := sym.info as table.Alias + a := sym.info as ast.Alias parent_typ := a.parent_type psym := g.table.get_type_symbol(parent_typ) if is_js_prim(g.typ(parent_typ)) { @@ -87,14 +87,14 @@ $enc_fn_dec { return } enc.writeln('\to = cJSON_CreateObject();') - if psym.info !is table.Struct { + if psym.info !is ast.Struct { verror('json: $sym.name is not struct') } g.gen_struct_enc_dec(psym.info, styp, mut enc, mut dec) } else { enc.writeln('\to = cJSON_CreateObject();') // Structs. Range through fields - if sym.info !is table.Struct { + if sym.info !is ast.Struct { verror('json: $sym.name is not struct') } g.gen_struct_enc_dec(sym.info, styp, mut enc, mut dec) @@ -110,8 +110,8 @@ $enc_fn_dec { } [inline] -fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc strings.Builder, mut dec strings.Builder) { - info := type_info as table.Struct +fn (mut g Gen) gen_struct_enc_dec(type_info ast.TypeInfo, styp string, mut enc strings.Builder, mut dec strings.Builder) { + info := type_info as ast.Struct for field in info.fields { if field.attrs.contains('skip') { continue @@ -143,7 +143,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc // it has to be decoded from a unix timestamp number dec.writeln('\tres.${c_name(field.name)} = time__unix(json__decode_u64(js_get(root, "$name")));') } else if field_sym.kind == .alias { - alias := field_sym.info as table.Alias + alias := field_sym.info as ast.Alias parent_type := g.typ(alias.parent_type) parent_dec_name := js_dec_name(parent_type) if is_js_prim(parent_type) { @@ -171,7 +171,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc mut enc_name := js_enc_name(field_type) if !is_js_prim(field_type) { if field_sym.kind == .alias { - ainfo := field_sym.info as table.Alias + ainfo := field_sym.info as ast.Alias enc_name = js_enc_name(g.typ(ainfo.parent_type)) } } @@ -206,7 +206,7 @@ fn is_js_prim(typ string) bool { ] } -fn (mut g Gen) decode_array(value_type table.Type) string { +fn (mut g Gen) decode_array(value_type ast.Type) string { styp := g.typ(value_type) fn_name := js_dec_name(styp) mut s := '' @@ -236,7 +236,7 @@ fn (mut g Gen) decode_array(value_type table.Type) string { ' } -fn (mut g Gen) encode_array(value_type table.Type) string { +fn (mut g Gen) encode_array(value_type ast.Type) string { styp := g.typ(value_type) fn_name := js_enc_name(styp) return ' @@ -247,7 +247,7 @@ fn (mut g Gen) encode_array(value_type table.Type) string { ' } -fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string { +fn (mut g Gen) decode_map(key_type ast.Type, value_type ast.Type) string { styp := g.typ(key_type) styp_v := g.typ(value_type) key_type_symbol := g.table.get_type_symbol(key_type) @@ -281,7 +281,7 @@ fn (mut g Gen) decode_map(key_type table.Type, value_type table.Type) string { ' } -fn (mut g Gen) encode_map(key_type table.Type, value_type table.Type) string { +fn (mut g Gen) encode_map(key_type ast.Type, value_type ast.Type) string { styp := g.typ(key_type) styp_v := g.typ(value_type) fn_name_v := js_enc_name(styp_v) diff --git a/vlib/v/gen/c/sql.v b/vlib/v/gen/c/sql.v index 933ddcd77b..09d65bcc90 100644 --- a/vlib/v/gen/c/sql.v +++ b/vlib/v/gen/c/sql.v @@ -4,7 +4,6 @@ module c import v.ast import strings -import v.table import v.util // pg,mysql etc @@ -133,7 +132,7 @@ fn (mut g Gen) sqlite3_stmt(node ast.SqlStmt, typ SqlType) { continue } x := '${node.object_var_name}.$field.name' - if field.typ == table.string_type { + if field.typ == ast.string_type { g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i + 0}, ${x}.str, ${x}.len, 0);') } else if g.table.type_symbols[int(field.typ)].kind == .struct_ { // insert again @@ -249,14 +248,14 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_ // array_User array_tmp; // for { User tmp; ... array_tmp << tmp; } array_sym := g.table.get_type_symbol(node.typ) - array_info := array_sym.info as table.Array + array_info := array_sym.info as ast.Array elem_type_str = g.typ(array_info.elem_type) g.writeln('$styp ${tmp}_array = __new_array(0, 10, sizeof($elem_type_str));') g.writeln('while (1) {') g.writeln('\t$elem_type_str $tmp = ($elem_type_str) {') // sym := g.table.get_type_symbol(array_info.elem_type) - info := sym.info as table.Struct + info := sym.info as ast.Struct for i, field in info.fields { g.zero_struct_field(field) if i != info.fields.len - 1 { @@ -271,7 +270,7 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_ // If we don't, string values are going to be nil etc for fields that are not returned // by the db engine. sym := g.table.get_type_symbol(node.typ) - info := sym.info as table.Struct + info := sym.info as ast.Struct for i, field in info.fields { g.zero_struct_field(field) if i != info.fields.len - 1 { @@ -293,7 +292,7 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_ } for i, field in node.fields { mut func := 'sqlite3_column_int' - if field.typ == table.string_type { + if field.typ == ast.string_type { func = 'sqlite3_column_text' string_data := g.new_tmp_var() g.writeln('byteptr $string_data = ${func}($g.sql_stmt_name, $i);') @@ -415,9 +414,9 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) { g.inc_sql_i() info := expr.info as ast.IdentVar ityp := info.typ - if ityp == table.string_type { + if ityp == ast.string_type { g.sql_bind_string('${expr.name}.str', '${expr.name}.len', typ) - } else if ityp == table.int_type { + } else if ityp == ast.int_type { g.sql_bind_int(expr.name, typ) } else { verror('bad sql type=$ityp ident_name=$expr.name') @@ -426,7 +425,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) { } ast.SelectorExpr { g.inc_sql_i() - if expr.typ == table.int_type { + if expr.typ == ast.int_type { if expr.expr !is ast.Ident { verror('orm selector not ident') } diff --git a/vlib/v/gen/c/str.v b/vlib/v/gen/c/str.v index 357a51d3fa..3d5c719a71 100644 --- a/vlib/v/gen/c/str.v +++ b/vlib/v/gen/c/str.v @@ -4,7 +4,6 @@ module c import v.ast import v.util -import v.table fn (mut g Gen) write_str_fn_definitions() { // _STR function can't be defined in vlib @@ -26,7 +25,7 @@ void _STR_PRINT_ARG(const char *fmt, char** refbufp, int *nbytes, int *memsize, } // increase buffer (somewhat exponentially) *memsize += (*memsize + *memsize) / 3 + guess; -#ifdef _VGCBOEHM +#ifdef _VGCBOEHM *refbufp = (char*)GC_REALLOC((void*)*refbufp, *memsize); #else *refbufp = (char*)realloc((void*)*refbufp, *memsize); @@ -39,7 +38,7 @@ string _STR(const char *fmt, int nfmts, ...) { va_list argptr; int memsize = 128; int nbytes = 0; -#ifdef _VGCBOEHM +#ifdef _VGCBOEHM char* buf = (char*)GC_MALLOC(memsize); #else char* buf = (char*)malloc(memsize); @@ -222,7 +221,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { mut typ := g.unwrap_generic(node.expr_types[i]) sym := g.table.get_type_symbol(typ) if sym.kind == .alias { - typ = (sym.info as table.Alias).parent_type + typ = (sym.info as ast.Alias).parent_type } // write correct format specifier to intermediate string g.write('%') @@ -256,11 +255,11 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { g.write('${fmt}c') } else { g.write('$fmt"PRI${fspec:c}') - if typ in [table.i8_type, table.byte_type] { + if typ in [ast.i8_type, ast.byte_type] { g.write('8') - } else if typ in [table.i16_type, table.u16_type] { + } else if typ in [ast.i16_type, ast.u16_type] { g.write('16') - } else if typ in [table.i64_type, table.u64_type] { + } else if typ in [ast.i64_type, ast.u64_type] { g.write('64') } else { g.write('32') @@ -280,7 +279,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { // Build args for i, expr in node.exprs { typ := g.unwrap_generic(node.expr_types[i]) - if typ == table.string_type { + if typ == ast.string_type { if g.inside_vweb_tmpl { g.write('vweb__filter(') if expr.is_auto_deref_var() { @@ -299,11 +298,11 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { } else if typ.is_number() || typ.is_pointer() || node.fmts[i] == `d` { if typ.is_signed() && node.fmts[i] in [`x`, `X`, `o`] { // convert to unsigned first befors C's integer propagation strikes - if typ == table.i8_type { + if typ == ast.i8_type { g.write('(byte)(') - } else if typ == table.i16_type { + } else if typ == ast.i16_type { g.write('(u16)(') - } else if typ == table.int_type { + } else if typ == ast.int_type { g.write('(u32)(') } else { g.write('(u64)(') @@ -335,7 +334,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { g.write(')') } -fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) { +fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype ast.Type) { is_shared := etype.has_flag(.shared_f) mut typ := etype if is_shared { @@ -343,7 +342,7 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) { } mut sym := g.table.get_type_symbol(typ) // when type is alias, print the aliased value - if mut sym.info is table.Alias { + if mut sym.info is ast.Alias { parent_sym := g.table.get_type_symbol(sym.info.parent_type) if parent_sym.has_method('str') { typ = sym.info.parent_type @@ -356,9 +355,9 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) { g.write('${str_fn_name}(') g.expr(expr) g.write(')') - } else if typ == table.string_type { + } else if typ == ast.string_type { g.expr(expr) - } else if typ == table.bool_type { + } else if typ == ast.bool_type { g.expr(expr) g.write(' ? _SLIT("true") : _SLIT("false")') } else if sym.kind == .none_ { diff --git a/vlib/v/gen/js/builtin_types.v b/vlib/v/gen/js/builtin_types.v index 792823be04..4576919682 100644 --- a/vlib/v/gen/js/builtin_types.v +++ b/vlib/v/gen/js/builtin_types.v @@ -1,5 +1,6 @@ module js -import v.table + +import v.ast fn (mut g JsGen) to_js_typ_def_val(s string) string { mut dval := '' @@ -13,25 +14,26 @@ fn (mut g JsGen) to_js_typ_def_val(s string) string { return dval } -fn (mut g JsGen) to_js_typ_val(t table.Type) string { +fn (mut g JsGen) to_js_typ_val(t ast.Type) string { sym := g.table.get_type_symbol(t) mut styp := '' - mut prefix := if g.file.mod.name == 'builtin' { 'new ' } else { '' } + mut prefix := if g.file.mod.name == 'builtin' { 'new ' } else { '' } match sym.kind { - .i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal, .size_t { - styp = '${prefix}${g.sym_to_js_typ(sym)}(0)' + .i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal, + .size_t { + styp = '$prefix${g.sym_to_js_typ(sym)}(0)' } .bool { - styp = '${prefix}${g.sym_to_js_typ(sym)}(false)' + styp = '$prefix${g.sym_to_js_typ(sym)}(false)' } .string { - styp = '${prefix}${g.sym_to_js_typ(sym)}("")' + styp = '$prefix${g.sym_to_js_typ(sym)}("")' } .map { styp = 'new Map()' } .array { - styp = '${prefix}${g.sym_to_js_typ(sym)}()' + styp = '$prefix${g.sym_to_js_typ(sym)}()' } .struct_ { styp = 'new ${g.js_name(sym.name)}(${g.to_js_typ_def_val(sym.name)})' @@ -44,26 +46,60 @@ fn (mut g JsGen) to_js_typ_val(t table.Type) string { return styp } -fn (mut g JsGen) sym_to_js_typ(sym table.TypeSymbol) string { +fn (mut g JsGen) sym_to_js_typ(sym ast.TypeSymbol) string { mut styp := '' match sym.kind { - .i8 { styp = 'i8' } - .i16 { styp = 'i16' } - .int { styp = 'int' } - .i64 { styp = 'i64' } - .byte { styp = 'byte' } - .u16 { styp = 'u16' } - .u32 { styp = 'u32' } - .u64 { styp = 'u64' } - .f32 { styp = 'f32' } - .f64 { styp = 'f64' } - .int_literal { styp = 'int_literal' } - .float_literal { styp = 'float_literal' } - .size_t { styp = 'size_t' } - .bool { styp = 'bool' } - .string { styp = 'string' } - .map { styp = 'map' } - .array { styp = 'array' } + .i8 { + styp = 'i8' + } + .i16 { + styp = 'i16' + } + .int { + styp = 'int' + } + .i64 { + styp = 'i64' + } + .byte { + styp = 'byte' + } + .u16 { + styp = 'u16' + } + .u32 { + styp = 'u32' + } + .u64 { + styp = 'u64' + } + .f32 { + styp = 'f32' + } + .f64 { + styp = 'f64' + } + .int_literal { + styp = 'int_literal' + } + .float_literal { + styp = 'float_literal' + } + .size_t { + styp = 'size_t' + } + .bool { + styp = 'bool' + } + .string { + styp = 'string' + } + .map { + styp = 'map' + } + .array { + styp = 'array' + } else { // TODO styp = 'undefined' @@ -73,7 +109,7 @@ fn (mut g JsGen) sym_to_js_typ(sym table.TypeSymbol) string { } // V type to JS type -pub fn (mut g JsGen) typ(t table.Type) string { +pub fn (mut g JsGen) typ(t ast.Type) string { sym := g.table.get_type_symbol(t) mut styp := '' match sym.kind { @@ -90,7 +126,8 @@ pub fn (mut g JsGen) typ(t table.Type) string { .byteptr, .charptr { styp = '${g.sym_to_js_typ(sym)}' } - .i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal, .size_t { + .i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal, + .size_t { styp = '${g.sym_to_js_typ(sym)}' } .bool { @@ -104,11 +141,11 @@ pub fn (mut g JsGen) typ(t table.Type) string { } // 'array_array_int' => 'number[][]' .array { - info := sym.info as table.Array + info := sym.info as ast.Array styp = '${g.sym_to_js_typ(sym)}(${g.typ(info.elem_type)})' } .array_fixed { - info := sym.info as table.ArrayFixed + info := sym.info as ast.ArrayFixed styp = '${g.sym_to_js_typ(sym)}(${g.typ(info.elem_type)})' } .chan { @@ -116,7 +153,7 @@ pub fn (mut g JsGen) typ(t table.Type) string { } // 'map[string]int' => 'Map' .map { - info := sym.info as table.Map + info := sym.info as ast.Map key := g.typ(info.key_type) val := g.typ(info.value_type) styp = 'Map<$key, $val>' @@ -131,7 +168,7 @@ pub fn (mut g JsGen) typ(t table.Type) string { .generic_struct_inst {} // 'multi_return_int_int' => '[number, number]' .multi_return { - info := sym.info as table.MultiReturn + info := sym.info as ast.MultiReturn types := info.types.map(g.typ(it)) joined := types.join(', ') styp = '[$joined]' @@ -153,7 +190,7 @@ pub fn (mut g JsGen) typ(t table.Type) string { } // 'anon_fn_7_7_1' => '(a number, b number) => void' .function { - info := sym.info as table.FnType + info := sym.info as ast.FnType styp = g.fn_typ(info.func.params, info.func.return_type) } .interface_ { @@ -181,7 +218,7 @@ pub fn (mut g JsGen) typ(t table.Type) string { return styp } -fn (mut g JsGen) fn_typ(args []table.Param, return_type table.Type) string { +fn (mut g JsGen) fn_typ(args []ast.Param, return_type ast.Type) string { mut res := '(' for i, arg in args { res += '$arg.name: ${g.typ(arg.typ)}' @@ -194,7 +231,9 @@ fn (mut g JsGen) fn_typ(args []table.Param, return_type table.Type) string { fn (mut g JsGen) struct_typ(s string) string { ns := get_ns(s) - if ns == 'JS' { return s[3..] } + if ns == 'JS' { + return s[3..] + } mut name := if ns == g.ns.name { s.split('.').last() } else { g.get_alias(s) } mut styp := '' for i, v in name.split('.') { @@ -210,26 +249,25 @@ fn (mut g JsGen) struct_typ(s string) string { return styp + '["prototype"]' } -struct BuiltinPrototypeCongig { - typ_name string - val_name string = 'val' - default_value string - constructor string = 'this.val = val' - value_of string = 'this.val' - to_string string = 'this.val.toString()' - eq string = 'this.val === other.val' - extras string - has_strfn bool +struct BuiltinPrototypeConfig { + typ_name string + val_name string = 'val' + default_value string + constructor string = 'this.val = val' + value_of string = 'this.val' + to_string string = 'this.val.toString()' + eq string = 'this.val === other.val' + extras string + has_strfn bool } -// ugly arguments but not sure a config struct would be worth it -fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeCongig) { - g.writeln('function ${c.typ_name}(${c.val_name} = ${c.default_value}) { ${c.constructor} }') +fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeConfig) { + g.writeln('function ${c.typ_name}($c.val_name = $c.default_value) { $c.constructor }') g.writeln('${c.typ_name}.prototype = {') g.inc_indent() - g.writeln('${c.val_name}: ${c.default_value},') + g.writeln('$c.val_name: $c.default_value,') if c.extras.len > 0 { - g.writeln('${c.extras},') + g.writeln('$c.extras,') } for method in g.method_fn_decls[c.typ_name] { g.inside_def_typ_decl = true @@ -237,10 +275,12 @@ fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeCongig) { g.inside_def_typ_decl = false g.writeln(',') } - g.writeln('valueOf() { return ${c.value_of} },') - g.writeln('toString() { return ${c.to_string} },') - g.writeln('eq(other) { return ${c.eq} },') - if c.has_strfn { g.writeln('str() { return new string(this.toString()) }') } + g.writeln('valueOf() { return $c.value_of },') + g.writeln('toString() { return $c.to_string },') + g.writeln('eq(other) { return $c.eq },') + if c.has_strfn { + g.writeln('str() { return new string(this.toString()) }') + } g.dec_indent() g.writeln('};\n') } @@ -253,39 +293,39 @@ fn (mut g JsGen) gen_builtin_type_defs() { match typ_name { 'i8', 'i16', 'int', 'i64', 'u16', 'u32', 'u64', 'int_literal', 'size_t' { // TODO: Bounds checking - g.gen_builtin_prototype({ + g.gen_builtin_prototype( typ_name: typ_name default_value: 'new Number(0)' constructor: 'this.val = val | 0' value_of: 'this.val | 0' to_string: 'this.valueOf().toString()' eq: 'this.valueOf() === other.valueOf()' - }) + ) } 'byte' { - g.gen_builtin_prototype({ + g.gen_builtin_prototype( typ_name: typ_name default_value: 'new Number(0)' constructor: 'this.val = typeof(val) == "string" ? val.charCodeAt() : (val | 0)' value_of: 'this.val | 0' to_string: 'String.fromCharCode(this.val)' eq: 'this.valueOf() === other.valueOf()' - }) + ) } 'f32', 'f64', 'float_literal' { - g.gen_builtin_prototype({ + g.gen_builtin_prototype( typ_name: typ_name default_value: 'new Number(0)' - }) + ) } 'bool' { - g.gen_builtin_prototype({ + g.gen_builtin_prototype( typ_name: typ_name default_value: 'new Boolean(false)' - }) + ) } 'string' { - g.gen_builtin_prototype({ + g.gen_builtin_prototype( typ_name: typ_name val_name: 'str' default_value: 'new String("")' @@ -294,10 +334,10 @@ fn (mut g JsGen) gen_builtin_type_defs() { to_string: 'this.str' eq: 'this.str === other.str' has_strfn: false - }) + ) } 'map' { - g.gen_builtin_prototype({ + g.gen_builtin_prototype( typ_name: typ_name val_name: 'map' default_value: 'new Map()' @@ -305,10 +345,10 @@ fn (mut g JsGen) gen_builtin_type_defs() { value_of: 'this.map' to_string: 'this.map.toString()' eq: 'vEq(this, other)' - }) + ) } 'array' { - g.gen_builtin_prototype({ + g.gen_builtin_prototype( typ_name: typ_name val_name: 'arr' default_value: 'new Array()' @@ -316,7 +356,7 @@ fn (mut g JsGen) gen_builtin_type_defs() { value_of: 'this.arr' to_string: 'JSON.stringify(this.arr.map(it => it.valueOf()))' eq: 'vEq(this, other)' - }) + ) } else {} } diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index 8854f1e304..ad5e99a0a8 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -2,7 +2,6 @@ module js import strings import v.ast -import v.table import v.token import v.pref import v.util @@ -19,7 +18,7 @@ const ( // used to generate type structs v_types = ['i8', 'i16', 'int', 'i64', 'byte', 'u16', 'u32', 'u64', 'f32', 'f64', 'int_literal', 'float_literal', 'size_t', 'bool', 'string', 'map', 'array'] - shallow_equatables = [table.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, + shallow_equatables = [ast.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .int_literal, .float_literal, .size_t, .bool, .string] ) @@ -34,7 +33,7 @@ mut: } struct JsGen { - table &table.Table + table &ast.Table pref &pref.Preferences mut: definitions strings.Builder @@ -58,11 +57,11 @@ mut: method_fn_decls map[string][]ast.FnDecl builtin_fns []string // Functions defined in `builtin` empty_line bool - cast_stack []table.Type + cast_stack []ast.Type call_stack []ast.CallExpr } -pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string { +pub fn gen(files []ast.File, table &ast.Table, pref &pref.Preferences) string { mut g := &JsGen{ definitions: strings.new_builder(100) table: table @@ -356,7 +355,7 @@ fn (mut g JsGen) stmts(stmts []ast.Stmt) { fn (mut g JsGen) stmt(node ast.Stmt) { g.stmt_start_pos = g.ns.out.len match node { - ast.EmptyStmt{} + ast.EmptyStmt {} ast.AsmStmt { panic('inline asm is not supported by js') } @@ -587,7 +586,7 @@ fn (mut g JsGen) expr(node ast.Expr) { // `user := User{name: 'Bob'}` g.gen_struct_init(node) } - ast.Type { + ast.TypeNode { // skip: JS has no types // TODO maybe? } @@ -697,7 +696,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { } else { g.write(' $op ') // TODO: Multiple types?? - should_cast := + should_cast := (g.table.type_kind(stmt.left_types.first()) in js.shallow_equatables) && (g.cast_stack.len <= 0 || stmt.left_types.first() != g.cast_stack.last()) @@ -723,7 +722,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) { } } -fn (mut g JsGen) gen_attrs(attrs []table.Attr) { +fn (mut g JsGen) gen_attrs(attrs []ast.Attr) { for attr in attrs { g.writeln('/* [$attr.name] */') } @@ -875,7 +874,7 @@ fn (mut g JsGen) gen_method_decl(it ast.FnDecl) { g.fn_decl = voidptr(0) } -fn (mut g JsGen) fn_args(args []table.Param, is_variadic bool) { +fn (mut g JsGen) fn_args(args []ast.Param, is_variadic bool) { for i, arg in args { name := g.js_name(arg.name) is_varg := i == args.len - 1 && is_variadic @@ -1388,7 +1387,7 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) { // TODO Does this cover all cases? g.expr(expr.left) g.write('[') - g.cast_stack << table.int_type_idx + g.cast_stack << ast.int_type_idx g.expr(expr.index) g.cast_stack.delete_last() g.write(']') @@ -1480,52 +1479,52 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { } } -fn (mut g JsGen) greater_typ(left table.Type, right table.Type) table.Type { +fn (mut g JsGen) greater_typ(left ast.Type, right ast.Type) ast.Type { l := int(left) r := int(right) lr := [l, r] - if table.string_type_idx in lr { - return table.Type(table.string_type_idx) + if ast.string_type_idx in lr { + return ast.Type(ast.string_type_idx) } - should_float := (l in table.integer_type_idxs && r in table.float_type_idxs) - || (r in table.integer_type_idxs && l in table.float_type_idxs) + should_float := (l in ast.integer_type_idxs && r in ast.float_type_idxs) + || (r in ast.integer_type_idxs && l in ast.float_type_idxs) if should_float { - if table.f64_type_idx in lr { - return table.Type(table.f64_type_idx) + if ast.f64_type_idx in lr { + return ast.Type(ast.f64_type_idx) } - if table.f32_type_idx in lr { - return table.Type(table.f32_type_idx) + if ast.f32_type_idx in lr { + return ast.Type(ast.f32_type_idx) } - return table.Type(table.float_literal_type) + return ast.Type(ast.float_literal_type) } - should_int := (l in table.integer_type_idxs && r in table.integer_type_idxs) + should_int := (l in ast.integer_type_idxs && r in ast.integer_type_idxs) if should_int { - // cant add to u64 - if (table.u64_type_idx in lr) { return table.Type(table.u64_type_idx) } + // cant add to u64 - if (ast.u64_type_idx in lr) { return ast.Type(ast.u64_type_idx) } // just guessing this order - if table.i64_type_idx in lr { - return table.Type(table.i64_type_idx) + if ast.i64_type_idx in lr { + return ast.Type(ast.i64_type_idx) } - if table.u32_type_idx in lr { - return table.Type(table.u32_type_idx) + if ast.u32_type_idx in lr { + return ast.Type(ast.u32_type_idx) } - if table.int_type_idx in lr { - return table.Type(table.int_type_idx) + if ast.int_type_idx in lr { + return ast.Type(ast.int_type_idx) } - if table.u16_type_idx in lr { - return table.Type(table.u16_type_idx) + if ast.u16_type_idx in lr { + return ast.Type(ast.u16_type_idx) } - if table.i16_type_idx in lr { - return table.Type(table.i16_type_idx) + if ast.i16_type_idx in lr { + return ast.Type(ast.i16_type_idx) } - if table.byte_type_idx in lr { - return table.Type(table.byte_type_idx) + if ast.byte_type_idx in lr { + return ast.Type(ast.byte_type_idx) } - if table.i8_type_idx in lr { - return table.Type(table.i8_type_idx) + if ast.i8_type_idx in lr { + return ast.Type(ast.i8_type_idx) } - return table.Type(table.int_literal_type_idx) + return ast.Type(ast.int_literal_type_idx) } - return table.Type(l) + return ast.Type(l) } fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) { @@ -1561,7 +1560,7 @@ fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) { } fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) { - should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == table.string_type_idx) + should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == ast.string_type_idx) if should_cast { if g.file.mod.name == 'builtin' { g.write('new ') @@ -1600,7 +1599,7 @@ fn (mut g JsGen) gen_string_inter_literal(it ast.StringInterLiteral) { fn (mut g JsGen) gen_string_literal(it ast.StringLiteral) { text := it.val.replace("'", "\\'") - should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == table.string_type_idx) + should_cast := !(g.cast_stack.len > 0 && g.cast_stack.last() == ast.string_type_idx) if should_cast { if g.file.mod.name == 'builtin' { g.write('new ') @@ -1639,11 +1638,11 @@ fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) { if sym.kind == .sum_type { // TODO: JS sumtypes not implemented yet } else if sym.kind == .array_fixed { - fixed_info := sym.info as table.ArrayFixed + fixed_info := sym.info as ast.ArrayFixed typ_name := g.table.get_type_name(fixed_info.elem_type) g.write('"[$fixed_info.size]$typ_name"') } else if sym.kind == .function { - info := sym.info as table.FnType + info := sym.info as ast.FnType fn_info := info.func mut repr := 'fn (' for i, arg in fn_info.params { @@ -1653,7 +1652,7 @@ fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) { repr += g.table.get_type_name(arg.typ) } repr += ')' - if fn_info.return_type != table.void_type { + if fn_info.return_type != ast.void_type { repr += ' ${g.table.get_type_name(fn_info.return_type)}' } g.write('"$repr"') @@ -1663,8 +1662,8 @@ fn (mut g JsGen) gen_typeof_expr(it ast.TypeOf) { } fn (mut g JsGen) gen_type_cast_expr(it ast.CastExpr) { - is_literal := ((it.expr is ast.IntegerLiteral && it.typ in table.integer_type_idxs) - || (it.expr is ast.FloatLiteral && it.typ in table.float_type_idxs)) + is_literal := ((it.expr is ast.IntegerLiteral && it.typ in ast.integer_type_idxs) + || (it.expr is ast.FloatLiteral && it.typ in ast.float_type_idxs)) // Skip cast if type is the same as the parrent caster if g.cast_stack.len > 0 && is_literal { if it.typ == g.cast_stack[g.cast_stack.len - 1] { @@ -1690,7 +1689,7 @@ fn (mut g JsGen) gen_type_cast_expr(it ast.CastExpr) { } fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) { - typ := table.Type(table.int_type) + typ := ast.Type(ast.int_type) // Don't wrap integers for use in JS.foo functions. // TODO: call.language always seems to be "v", parser bug? @@ -1710,7 +1709,7 @@ fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) { // Skip cast if type is the same as the parrent caster if g.cast_stack.len > 0 { - if g.cast_stack[g.cast_stack.len - 1] in table.integer_type_idxs { + if g.cast_stack[g.cast_stack.len - 1] in ast.integer_type_idxs { g.write('$it.val') return } @@ -1724,7 +1723,7 @@ fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) { } fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) { - typ := table.Type(table.f32_type) + typ := ast.Type(ast.f32_type) // Don't wrap integers for use in JS.foo functions. // TODO: call.language always seems to be "v", parser bug? @@ -1734,7 +1733,7 @@ fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) { for i, t in call.args { if t.expr is ast.FloatLiteral { if t.expr == it { - if call.expected_arg_types[i] in table.integer_type_idxs { + if call.expected_arg_types[i] in ast.integer_type_idxs { g.write(int(it.val.f64()).str()) } else { g.write(it.val) @@ -1748,10 +1747,10 @@ fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) { // Skip cast if type is the same as the parrent caster if g.cast_stack.len > 0 { - if g.cast_stack[g.cast_stack.len - 1] in table.float_type_idxs { + if g.cast_stack[g.cast_stack.len - 1] in ast.float_type_idxs { g.write('$it.val') return - } else if g.cast_stack[g.cast_stack.len - 1] in table.integer_type_idxs { + } else if g.cast_stack[g.cast_stack.len - 1] in ast.integer_type_idxs { g.write(int(it.val.f64()).str()) return } diff --git a/vlib/v/gen/js/jsdoc.v b/vlib/v/gen/js/jsdoc.v index f25d27acb9..359687e3a0 100644 --- a/vlib/v/gen/js/jsdoc.v +++ b/vlib/v/gen/js/jsdoc.v @@ -4,7 +4,7 @@ import v.ast struct JsDoc { mut: - gen &JsGen + gen &JsGen } fn new_jsdoc(gen &JsGen) &JsDoc { @@ -14,12 +14,16 @@ fn new_jsdoc(gen &JsGen) &JsDoc { } fn (mut d JsDoc) write(s string) { - if !d.gen.enable_doc { return } + if !d.gen.enable_doc { + return + } d.gen.write(s) } fn (mut d JsDoc) writeln(s string) { - if !d.gen.enable_doc { return } + if !d.gen.enable_doc { + return + } d.gen.writeln(s) } @@ -45,7 +49,9 @@ fn (mut d JsDoc) gen_fac_fn(fields []ast.StructField) { // Marked as optional: structs have default default values, // so all struct members don't have to be initialized. d.write('$field.name?: ${d.gen.typ(field.typ)}') - if i < fields.len - 1 { d.write(', ') } + if i < fields.len - 1 { + d.write(', ') + } } d.writeln('}} init') d.writeln('*/') diff --git a/vlib/v/gen/js/jsgen_test.v b/vlib/v/gen/js/jsgen_test.v index 8bae0074e3..df37172e16 100644 --- a/vlib/v/gen/js/jsgen_test.v +++ b/vlib/v/gen/js/jsgen_test.v @@ -7,7 +7,7 @@ const ( ) fn testsuite_end() { - os.rmdir_all(output_dir) or { } + os.rmdir_all(output_dir) or {} } const there_is_node_available = is_nodejs_working() diff --git a/vlib/v/gen/js/temp_fast_deep_equal.v b/vlib/v/gen/js/temp_fast_deep_equal.v index fcd1d089a6..553fc3d10f 100644 --- a/vlib/v/gen/js/temp_fast_deep_equal.v +++ b/vlib/v/gen/js/temp_fast_deep_equal.v @@ -69,4 +69,4 @@ function vEq(a, b) { return a!==a && b!==b; }; " -) \ No newline at end of file +) diff --git a/vlib/v/gen/js/tests/array.v b/vlib/v/gen/js/tests/array.v index ee302a4ee0..f07e1b65a2 100644 --- a/vlib/v/gen/js/tests/array.v +++ b/vlib/v/gen/js/tests/array.v @@ -1,5 +1,10 @@ -fn map_cb(s string) string { return 'CB: $s' } -fn filter_cb(n int) bool { return n < 4 } +fn map_cb(s string) string { + return 'CB: $s' +} + +fn filter_cb(n int) bool { + return n < 4 +} fn variadic(args ...int) { println(args) @@ -13,111 +18,119 @@ fn vararg_test() { // TODO Remove `fn main` once vet supports scripts fn main() { -vararg_test() + vararg_test() -arr1 := ['Hello', 'JS', 'Backend'] -mut arr2 := [1, 2, 3, 4, 5] + arr1 := ['Hello', 'JS', 'Backend'] + mut arr2 := [1, 2, 3, 4, 5] -// Array slices -slice1 := arr1[1..3] -slice2 := arr2[..3] -slice3 := arr2[3..] + // Array slices + slice1 := arr1[1..3] + slice2 := arr2[..3] + slice3 := arr2[3..] -// Array indexes -idx1 := slice1[1] -arr2[0] = 1 -arr2[0 + 1] = 2 -println(arr2) + // Array indexes + idx1 := slice1[1] + arr2[0] = 1 + arr2[0 + 1] = 2 + println(arr2) -// TODO: This does not work for now -// arr2[0..1] = arr2[3..4] -// println(arr2) + // TODO: This does not work for now + // arr2[0..1] = arr2[3..4] + // println(arr2) -// Array push operator -arr2 << 6 -arr2 << [7, 8, 9] -println(arr2) -println('\n\n') + // Array push operator + arr2 << 6 + arr2 << [7, 8, 9] + println(arr2) + println('\n\n') -// String slices -mut slice4 := idx1[..4] -print('Back\t=> ') -println(slice4) // 'Back' + // String slices + mut slice4 := idx1[..4] + print('Back\t=> ') + println(slice4) // 'Back' -// String indexes -idx2 := slice4[0] -print('66\t=> ') -println(idx2) -// TODO: -// slice4[3] = `c` + // String indexes + idx2 := slice4[0] + print('66\t=> ') + println(idx2) + // TODO: + // slice4[3] = `c` -// Maps -mut m := map[string]string -key := 'key' -m[key] = 'value' -val := m['key'] -print('value\t=> ') -println(val) + // Maps + mut m := map[string]string{} + key := 'key' + m[key] = 'value' + val := m['key'] + print('value\t=> ') + println(val) -// 'in' / '!in' -print('true\t=> ') -println('JS' in arr1) -print('false\t=> ') -println(3 !in arr2) -print('true\t=> ') -println('key' in m) -print('true\t=> ') -println('badkey' !in m) -print('true\t=> ') -println('o' in 'hello') + // 'in' / '!in' + print('true\t=> ') + println('JS' in arr1) + print('false\t=> ') + println(3 !in arr2) + print('true\t=> ') + println('key' in m) + print('true\t=> ') + println('badkey' !in m) + print('true\t=> ') + println('o' in 'hello') -// for in -for _ in arr1 {} -println('0 to 8\t=>') -for i, _ in arr2 { println(i) } -println('\n\n4 to 5\t=> ') -for _, v in slice3 { println(v) } + // for in + for _ in arr1 {} + println('0 to 8\t=>') + for i, _ in arr2 { + println(i) + } + println('\n\n4 to 5\t=> ') + for _, v in slice3 { + println(v) + } -println(int(1.5)) + println(int(1.5)) -println('\n\n') + println('\n\n') -// map -a := arr1.map('VAL: $it') -b := arr1.map(map_cb) -c := arr1.map(map_cb(it)) -d := arr1.map(fn(a string) string { return 'ANON: $a' }) -// I don't know when this would ever be used, -// but it's what the C backend does ¯\_(ツ)_/¯ -e := arr1.map(456) + // map + a := arr1.map('VAL: $it') + b := arr1.map(map_cb) + c := arr1.map(map_cb(it)) + d := arr1.map(fn (a string) string { + return 'ANON: $a' + }) + // I don't know when this would ever be used, + // but it's what the C backend does ¯\_(ツ)_/¯ + e := arr1.map(456) -println(a) -println(b) -println(c) -println(d) -println(e) + println(a) + println(b) + println(c) + println(d) + println(e) -println('\n\n') + println('\n\n') -// filter -aa := arr2.filter(it < 4) -bb := arr2.filter(filter_cb) -cc := arr2.filter(filter_cb(it)) -dd := arr2.filter(fn(a int) bool { return a < 4 }) + // filter + aa := arr2.filter(it < 4) + bb := arr2.filter(filter_cb) + cc := arr2.filter(filter_cb(it)) + dd := arr2.filter(fn (a int) bool { + return a < 4 + }) -println(aa) -println(bb) -println(cc) -println(dd) + println(aa) + println(bb) + println(cc) + println(dd) -// fixed arrays: implemented as normal arrays -f1 := [1, 2, 3, 4, 5]! -mut f2 := [8]f32 -f2[0] = f32(1.23) -f3 := ['foo', 'bar']! -f4 := [u64(0xffffffffffffffff), 0xdeadface]! + // fixed arrays: implemented as normal arrays + f1 := [1, 2, 3, 4, 5]! + mut f2 := [8]f32{} + f2[0] = f32(1.23) + f3 := ['foo', 'bar']! + f4 := [u64(0xffffffffffffffff), 0xdeadface]! -println(' + println(' $f1 $f2 $f3 diff --git a/vlib/v/gen/js/tests/enum.v b/vlib/v/gen/js/tests/enum.v index 762ae71abf..2d1bfc0c19 100644 --- a/vlib/v/gen/js/tests/enum.v +++ b/vlib/v/gen/js/tests/enum.v @@ -1,4 +1,4 @@ -import hello +import v.gen.js.tests.hello enum Test { foo = 2 @@ -8,13 +8,12 @@ enum Test { // TODO Remove `fn main` once vet supports scripts fn main() { -mut a := hello.Ccc.a -a = .b -a = .c -println(a) + mut a := hello.Ccc.a + a = .b + a = .c + println(a) - -mut b := Test.foo -b = .bar -println(b) + mut b := Test.foo + b = .bar + println(b) } diff --git a/vlib/v/gen/js/tests/hello/hello.v b/vlib/v/gen/js/tests/hello/hello.v index 40fb89c86e..9b75511526 100644 --- a/vlib/v/gen/js/tests/hello/hello.v +++ b/vlib/v/gen/js/tests/hello/hello.v @@ -1,6 +1,6 @@ module hello -import hello.hello1 +import v.gen.js.tests.hello.hello1 pub const ( hello = 'Hello' @@ -25,9 +25,9 @@ pub enum Ccc { pub fn debugger() string { v := Bbb{} - return hello + return hello.hello } pub fn excited() string { - return "$hello1.nested() $debugger()!" + return '$hello1.nested() $debugger()!' } diff --git a/vlib/v/gen/js/tests/interp.v b/vlib/v/gen/js/tests/interp.v index 6e6f4595ad..5b00aa8d8b 100644 --- a/vlib/v/gen/js/tests/interp.v +++ b/vlib/v/gen/js/tests/interp.v @@ -1,5 +1,5 @@ -fn test_fn(s1, s2 string) { - print(if s1 == s2 {'true'} else {'false'}) +fn test_fn(s1 string, s2 string) { + print(if s1 == s2 { 'true' } else { 'false' }) print('\t=> ') println('"$s1", "$s2"') } @@ -60,7 +60,7 @@ fn implicit_str() { test_fn('int $i', 'int 42') test_fn('$i', '42') check := '$i' == '42' - //println(check) + // println(check) text := '$i' + '42' test_fn(text, '4242') } @@ -89,9 +89,9 @@ fn interpolation_string_prefix_expr() { r := 1 c := 2 js := 1 - test_fn('>${3+r}<', '>4<') + test_fn('>${3 + r}<', '>4<') test_fn('${r == js} $js', 'true 1') - test_fn('>${js+c} ${js+r==c}<', '>3 true<') + test_fn('>${js + c} ${js + r == c}<', '>3 true<') } /* @@ -134,8 +134,8 @@ fn utf8_string_interpolation() { test_fn('$a $st $m', 'à-côté Sträßle 10€') zz := '>${a:10}< >${st:-8}< >${m:5}<-' zz_expected := '> à-côté< >Sträßle < > 10€<-' - //println(' zz: $zz') - //println('zz_expected: $zz_expected') + // println(' zz: $zz') + // println('zz_expected: $zz_expected') test_fn(zz, zz_expected) // e := '\u20AC' // Eurosign doesn' work with MSVC and tcc e := '€' @@ -153,7 +153,7 @@ struct Sss { } fn (s Sss) str() string { - return '[${s.v1}, ${s.v2:.3f}]' + return '[$s.v1, ${s.v2:.3f}]' } fn string_interpolation_str_evaluation() { diff --git a/vlib/v/gen/js/tests/js.v b/vlib/v/gen/js/tests/js.v index 0722e9f5d2..ee7ba084ec 100644 --- a/vlib/v/gen/js/tests/js.v +++ b/vlib/v/gen/js/tests/js.v @@ -1,5 +1,5 @@ -import hello as hl -import hello.hello1 as hl1 +import v.gen.js.tests.hello as hl +import v.gen.js.tests.hello.hello1 as hl1 const ( i_am_a_const = 21214 @@ -71,7 +71,7 @@ fn main() { arr := [1, 2, 3, 4, 5] for i in arr { } - ma := { + ma := map{ 'str': 'done' 'ddo': 'baba' } @@ -91,15 +91,14 @@ fn main() { propagation() or { println(err) } } -fn anon_consumer(greeting string, anon fn (message string)) { +fn anon_consumer(greeting string, anon fn (string)) { anon(greeting) } fn async(num int, def string) { } -[inline] -[deprecated] +[deprecated; inline] fn hello(game_on int, dummy ...string) (int, int) { defer { do := 'not' @@ -130,7 +129,9 @@ fn (it Companies) method() int { } fn error_if_even(num int) ?int { - if num % 2 == 0 { return error('number is even') } + if num % 2 == 0 { + return error('number is even') + } return num } diff --git a/vlib/v/gen/js/tests/life.v b/vlib/v/gen/js/tests/life.v index c066307e62..a89da5aeb3 100644 --- a/vlib/v/gen/js/tests/life.v +++ b/vlib/v/gen/js/tests/life.v @@ -1,24 +1,49 @@ -fn clear() { JS.console.clear() } +fn clear() { + JS.console.clear() +} -const (w = 30 h = 30) +const ( + w = 30 + h = 30 +) fn get(game [][]bool, x int, y int) bool { - if y < 0 || x < 0 { return false } - if y >= h || x >= w { return false } + if y < 0 || x < 0 { + return false + } + if y >= h || x >= w { + return false + } return game[y][x] } fn neighbours(game [][]bool, x int, y int) int { mut count := 0 - if get(game, x-1, y-1) { count++ } - if get(game, x, y-1) { count++ } - if get(game, x+1, y-1) { count++ } - if get(game, x-1, y) { count++ } - if get(game, x+1, y) { count++ } - if get(game, x-1, y+1) { count++ } - if get(game, x, y+1) { count++ } - if get(game, x+1, y+1) { count++ } + if get(game, x - 1, y - 1) { + count++ + } + if get(game, x, y - 1) { + count++ + } + if get(game, x + 1, y - 1) { + count++ + } + if get(game, x - 1, y) { + count++ + } + if get(game, x + 1, y) { + count++ + } + if get(game, x - 1, y + 1) { + count++ + } + if get(game, x, y + 1) { + count++ + } + if get(game, x + 1, y + 1) { + count++ + } return count } @@ -38,8 +63,11 @@ fn step(game [][]bool) [][]bool { fn row_str(row []bool) string { mut str := '' for cell in row { - if cell { str += '◼ ' } - else { str += '◻ ' } + if cell { + str += '◼ ' + } else { + str += '◻ ' + } } return str } @@ -53,15 +81,18 @@ fn show(game [][]bool) { // TODO Remove `fn main` once vet supports scripts fn main() { -mut game := [][]bool{ len: h, init: []bool{ len: w } } + mut game := [][]bool{len: h, init: []bool{len: w}} -game[11][15] = true -game[11][16] = true -game[12][16] = true -game[10][21] = true -game[12][20] = true -game[12][21] = true -game[12][22] = true + game[11][15] = true + game[11][16] = true + game[12][16] = true + game[10][21] = true + game[12][20] = true + game[12][21] = true + game[12][22] = true -JS.setInterval(fn () { show(game) game = step(game) }, 500) + JS.setInterval(fn () { + show(game) + game = step(game) + }, 500) } diff --git a/vlib/v/gen/js/tests/optional.v b/vlib/v/gen/js/tests/optional.v index 1bcd78dcda..6d52eac8d5 100644 --- a/vlib/v/gen/js/tests/optional.v +++ b/vlib/v/gen/js/tests/optional.v @@ -1,28 +1,30 @@ module main fn main() { - try_propagation() or { println("captured: $err") } + try_propagation() or { println('captured: $err') } } fn try_propagation() ? { - try_numbers()? + try_numbers() ? } fn try_numbers() ? { for x in 1 .. 10 { y := error_if_even(x) or { x + 1 } - println("$x rounded to $y") - error_if_prime(y)? + println('$x rounded to $y') + error_if_prime(y) ? } } fn error_if_even(num int) ?int { - if num % 2 == 0 { return error('number is even') } + if num % 2 == 0 { + return error('number is even') + } return num } fn error_if_prime(num int) ?int { - for i in 2..num { + for i in 2 .. num { if num % i == 0 { return error('$num is prime') } diff --git a/vlib/v/gen/js/tests/simple.v b/vlib/v/gen/js/tests/simple.v index 9d84af50e5..ec46286bb0 100644 --- a/vlib/v/gen/js/tests/simple.v +++ b/vlib/v/gen/js/tests/simple.v @@ -1,5 +1,5 @@ module main fn main() { - println("hello world") + println('hello world') } diff --git a/vlib/v/gen/js/tests/struct.v b/vlib/v/gen/js/tests/struct.v index 0640c877b1..306d46ad23 100644 --- a/vlib/v/gen/js/tests/struct.v +++ b/vlib/v/gen/js/tests/struct.v @@ -33,8 +33,8 @@ fn main() { b.add(10) println(b.get()) // 10 use_config(Config{2, 'bar'}) - use_config({ + use_config( foo: 2 bar: 'bar' - }) + ) } diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 0f6c27c6ba..cff521002c 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -10,13 +10,12 @@ import v.errors import v.pref import term import strings -import v.table pub struct Gen { out_name string pref &pref.Preferences // Preferences shared from V struct mut: - table &table.Table + table &ast.Table buf []byte sect_header_name_pos int offset i64 @@ -82,7 +81,7 @@ enum Size { _64 } -pub fn gen(files []ast.File, table &table.Table, out_name string, pref &pref.Preferences) { +pub fn gen(files []ast.File, table &ast.Table, out_name string, pref &pref.Preferences) { mut g := Gen{ table: table sect_header_name_pos: 0 @@ -776,7 +775,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { sym := g.table.get_type_symbol(right.typ) // println(sym) // println(typeof(sym.info)) - info := sym.info as table.Struct + info := sym.info as ast.Struct for field in info.fields { field_name := name + '.' + field.name println(field_name) diff --git a/vlib/v/gen/x64/macho_test.v b/vlib/v/gen/x64/macho_test.v index 32d62e82e6..538feef629 100644 --- a/vlib/v/gen/x64/macho_test.v +++ b/vlib/v/gen/x64/macho_test.v @@ -1,12 +1,12 @@ import v.gen.x64 import v.pref -import v.table +import v.ast fn test_macho() { mut g := x64.Gen{ pref: &pref.Preferences{} out_name: 'test.bin' - table: &table.Table{} + table: &ast.Table{} } g.generate_macho_header() g.generate_macho_footer() diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index 6046387979..0fa59cc21a 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -3,12 +3,11 @@ module markused import v.ast -import v.table import v.util import v.pref // mark_used walks the AST, starting at main() and marks all used fns transitively -pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files []ast.File) { +pub fn mark_used(mut t ast.Table, pref &pref.Preferences, ast_files []ast.File) { mut all_fns, all_consts := all_fn_and_const(ast_files) util.timing_start(@METHOD) @@ -103,7 +102,7 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files [] // implicit string builders are generated in auto_eq_methods.v mut sb_mut_type := '' - if sbfn := the_table.find_fn('strings.new_builder') { + if sbfn := t.find_fn('strings.new_builder') { sb_mut_type = sbfn.return_type.set_nr_muls(1).str() + '.' } @@ -141,7 +140,7 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files [] if pref.is_test { all_fn_root_names << 'main.cb_assertion_ok' all_fn_root_names << 'main.cb_assertion_failed' - if benched_tests_sym := the_table.find_type('main.BenchedTests') { + if benched_tests_sym := t.find_type('main.BenchedTests') { bts_type := benched_tests_sym.methods[0].params[0].typ all_fn_root_names << '${bts_type}.testing_step_start' all_fn_root_names << '${bts_type}.testing_step_end' @@ -151,7 +150,7 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files [] } mut walker := Walker{ - table: the_table + table: t files: ast_files all_fns: all_fns all_consts: all_consts @@ -181,12 +180,12 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files [] } } - the_table.used_fns = walker.used_fns.move() - the_table.used_consts = walker.used_consts.move() + t.used_fns = walker.used_fns.move() + t.used_consts = walker.used_consts.move() $if trace_skip_unused ? { - eprintln('>> the_table.used_fns: $the_table.used_fns.keys()') - eprintln('>> the_table.used_consts: $the_table.used_consts.keys()') + eprintln('>> t.used_fns: $t.used_fns.keys()') + eprintln('>> t.used_consts: $t.used_consts.keys()') eprintln('>> walker.n_maps: $walker.n_maps') } } diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index ac427e77f2..1b88c61db9 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -5,11 +5,10 @@ module markused // Walk the entire program starting at fn main and marks used (called) functions. // Unused functions can be safely skipped by the backends to save CPU time and space. import v.ast -import v.table pub struct Walker { pub mut: - table &table.Table + table &ast.Table used_fns map[string]bool // used_fns['println'] == true used_consts map[string]bool // used_consts['os.args'] == true n_maps int @@ -288,11 +287,10 @@ fn (mut w Walker) expr(node ast.Expr) { ast.StructInit { sym := w.table.get_type_symbol(node.typ) if sym.kind == .struct_ { - info := sym.info as table.Struct + info := sym.info as ast.Struct for ifield in info.fields { if ifield.has_default_expr { - defex := ast.fe2ex(ifield.default_expr) - w.expr(defex) + w.expr(ifield.default_expr) } } } @@ -337,7 +335,7 @@ fn (mut w Walker) expr(node ast.Expr) { w.stmts(branch.stmts) } } - ast.Type {} + ast.TypeNode {} ast.UnsafeExpr { w.expr(node.expr) } diff --git a/vlib/v/parser/assign.v b/vlib/v/parser/assign.v index 136018704f..d893b9f7d7 100644 --- a/vlib/v/parser/assign.v +++ b/vlib/v/parser/assign.v @@ -4,7 +4,6 @@ module parser import v.ast -import v.table fn (mut p Parser) assign_stmt() ast.Stmt { exprs, comments := p.expr_list() @@ -134,7 +133,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme if p.scope.known_var(lx.name) { return p.error_with_pos('redefinition of `$lx.name`', lx.pos) } - mut share := table.ShareType(0) + mut share := ast.ShareType(0) if lx.info is ast.IdentVar { iv := lx.info as ast.IdentVar share = iv.share diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index 8398989bb2..de4ea64df9 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -6,7 +6,6 @@ module parser import os import v.ast import v.pref -import v.table import v.token const ( diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index 18ff477c23..93dc818c48 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -4,15 +4,14 @@ module parser import v.ast -import v.table fn (mut p Parser) array_init() ast.ArrayInit { first_pos := p.tok.position() mut last_pos := p.tok.position() p.check(.lsbr) // p.warn('array_init() exp=$p.expected_type') - mut array_type := table.void_type - mut elem_type := table.void_type + mut array_type := ast.void_type + mut elem_type := ast.void_type mut elem_type_pos := first_pos mut exprs := []ast.Expr{} mut ecmnts := [][]ast.Comment{} @@ -34,7 +33,7 @@ fn (mut p Parser) array_init() ast.ArrayInit { // this is set here because it's a known type, others could be the // result of expr so we do those in checker idx := p.table.find_or_register_array(elem_type) - array_type = table.new_type(idx) + array_type = ast.new_type(idx) has_type = true } last_pos = p.tok.position() @@ -105,7 +104,7 @@ fn (mut p Parser) array_init() ast.ArrayInit { mut has_cap := false mut len_expr := ast.empty_expr() mut cap_expr := ast.empty_expr() - if p.tok.kind == .lcbr && exprs.len == 0 && array_type != table.void_type { + if p.tok.kind == .lcbr && exprs.len == 0 && array_type != ast.void_type { // `[]int{ len: 10, cap: 100}` syntax p.next() for p.tok.kind != .rcbr { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index f66bfa8c61..2524e6eaee 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -4,11 +4,10 @@ module parser import v.ast -import v.table import v.token import v.util -pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExpr { +pub fn (mut p Parser) call_expr(language ast.Language, mod string) ast.CallExpr { first_pos := p.tok.position() mut fn_name := if language == .c { 'C.$p.check_name()' @@ -34,7 +33,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp } p.expr_mod = '' // - mut generic_types := []table.Type{} + mut generic_types := []ast.Type{} mut generic_list_pos := p.tok.position() if p.tok.kind == .lt { // `foo(10)` @@ -69,7 +68,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp p.open_scope() p.scope.register(ast.Var{ name: 'err' - typ: table.error_type + typ: ast.error_type pos: p.tok.position() is_used: true }) @@ -150,7 +149,7 @@ pub fn (mut p Parser) call_args() []ast.CallArg { comments << p.eat_comments({}) args << ast.CallArg{ is_mut: is_mut - share: table.sharetype_from_flags(is_shared, is_atomic) + share: ast.sharetype_from_flags(is_shared, is_atomic) expr: expr comments: comments pos: pos @@ -166,10 +165,10 @@ struct ReceiverParsingInfo { mut: name string pos token.Position - typ table.Type + typ ast.Type type_pos token.Position is_mut bool - language table.Language + language ast.Language } fn (mut p Parser) fn_decl() ast.FnDecl { @@ -187,12 +186,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl { p.check(.key_fn) p.open_scope() // C. || JS. - mut language := table.Language.v + mut language := ast.Language.v if p.tok.kind == .name && p.tok.lit == 'C' { is_unsafe = !p.attrs.contains('trusted') - language = table.Language.c + language = ast.Language.c } else if p.tok.kind == .name && p.tok.lit == 'JS' { - language = table.Language.js + language = ast.Language.js } if language != .v { p.next() @@ -201,11 +200,11 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } // Receiver? mut rec := ReceiverParsingInfo{ - typ: table.void_type + typ: ast.void_type language: language } mut is_method := false - mut params := []table.Param{} + mut params := []ast.Param{} if p.tok.kind == .lpar { is_method = true p.fn_receiver(mut params, mut rec) or { return ast.FnDecl{ @@ -233,7 +232,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { mut is_duplicate := type_sym.has_method(name) // make sure this is a normal method and not an interface method if type_sym.kind == .interface_ && is_duplicate { - if type_sym.info is table.Interface { + if type_sym.info is ast.Interface { // if the method is in info then its an interface method is_duplicate = !type_sym.info.has_method(name) } @@ -254,7 +253,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } } else if p.tok.kind in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && p.peek_tok.kind == .lpar { name = p.tok.kind.str() // op_to_fn_name() - if rec.typ == table.void_type { + if rec.typ == ast.void_type { p.error_with_pos('cannot use operator overloading with normal functions', p.tok.position()) } @@ -294,7 +293,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } } // Return type - mut return_type := table.void_type + mut return_type := ast.void_type // don't confuse token on the next line: fn decl, [attribute] same_line := p.tok.line_nr == p.prev_tok.line_nr if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr)) @@ -327,7 +326,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { scope: 0 } } - type_sym_method_idx = type_sym.register_method(table.Fn{ + type_sym_method_idx = type_sym.register_method(ast.Fn{ name: name params: params return_type: return_type @@ -355,7 +354,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { if !p.pref.translated && language == .v && name in p.table.fns { p.table.redefined_fns << name } - p.table.register_fn(table.Fn{ + p.table.register_fn(ast.Fn{ name: name params: params return_type: return_type @@ -408,7 +407,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { is_main: is_main is_test: is_test is_conditional: is_conditional - receiver: ast.Field{ + receiver: ast.StructField{ name: rec.name typ: rec.typ } @@ -433,7 +432,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { return fn_decl } -fn (mut p Parser) fn_receiver(mut params []table.Param, mut rec ReceiverParsingInfo) ? { +fn (mut p Parser) fn_receiver(mut params []ast.Param, mut rec ReceiverParsingInfo) ? { lpar_pos := p.tok.position() p.next() // ( is_shared := p.tok.kind == .key_shared @@ -458,7 +457,7 @@ fn (mut p Parser) fn_receiver(mut params []table.Param, mut rec ReceiverParsingI rec.pos = rec_start_pos.extend(p.tok.position()) is_amp := p.tok.kind == .amp if p.tok.kind == .name && p.tok.lit == 'JS' { - rec.language = table.Language.js + rec.language = ast.Language.js } // if rec.is_mut { // p.check(.key_mut) @@ -487,14 +486,14 @@ fn (mut p Parser) fn_receiver(mut params []table.Param, mut rec ReceiverParsingI type_sym := p.table.get_type_symbol(rec.typ) mut is_auto_rec := false if type_sym.kind == .struct_ { - info := type_sym.info as table.Struct + info := type_sym.info as ast.Struct if !rec.is_mut && !rec.typ.is_ptr() && info.fields.len > 8 { rec.typ = rec.typ.to_ptr() is_auto_rec = true } } - params << table.Param{ + params << ast.Param{ pos: rec_start_pos name: rec.name is_mut: rec.is_mut @@ -574,7 +573,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn { }) } mut same_line := p.tok.line_nr == p.prev_tok.line_nr - mut return_type := table.void_type + mut return_type := ast.void_type // lpar: multiple return types if same_line { if p.tok.kind.is_start_of_type() { @@ -592,7 +591,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn { p.tok.position()) } mut label_names := []string{} - mut func := table.Fn{ + mut func := ast.Fn{ params: args is_variadic: is_variadic return_type: return_type @@ -611,7 +610,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn { p.close_scope() func.name = name idx := p.table.find_or_register_fn_type(p.mod, func, true, false) - typ := table.new_type(idx) + typ := ast.new_type(idx) // name := p.table.get_type_name(typ) return ast.AnonFn{ decl: ast.FnDecl{ @@ -634,9 +633,9 @@ fn (mut p Parser) anon_fn() ast.AnonFn { } // part of fn declaration -fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { +fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) { p.check(.lpar) - mut args := []table.Param{} + mut args := []ast.Param{} mut is_variadic := false // `int, int, string` (no names, just types) argname := if p.tok.kind == .name && p.tok.lit.len > 0 && p.tok.lit[0].is_capital() { @@ -653,7 +652,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { for p.tok.kind != .rpar { if p.tok.kind == .eof { p.error_with_pos('expecting `)`', p.tok.position()) - return []table.Param{}, false, false + return []ast.Param{}, false, false } is_shared := p.tok.kind == .key_shared is_atomic := p.tok.kind == .key_atomic @@ -669,7 +668,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { mut arg_type := p.parse_type() if arg_type == 0 { // error is added in parse_type - return []table.Param{}, false, false + return []ast.Param{}, false, false } if is_mut { if !arg_type.has_flag(.generic) { @@ -682,7 +681,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } } else if is_shared || is_atomic { p.error_with_pos('generic object cannot be `atomic`or `shared`', pos) - return []table.Param{}, false, false + return []ast.Param{}, false, false } // if arg_type.is_ptr() { // p.error('cannot mut') @@ -697,21 +696,21 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } } if is_variadic { - arg_type = table.new_type(p.table.find_or_register_array(arg_type)).set_flag(.variadic) + arg_type = ast.new_type(p.table.find_or_register_array(arg_type)).set_flag(.variadic) } if p.tok.kind == .eof { p.error_with_pos('expecting `)`', p.prev_tok.position()) - return []table.Param{}, false, false + return []ast.Param{}, false, false } if p.tok.kind == .comma { if is_variadic { p.error_with_pos('cannot use ...(variadic) with non-final parameter no $arg_no', pos) - return []table.Param{}, false, false + return []ast.Param{}, false, false } p.next() } - args << table.Param{ + args << ast.Param{ pos: pos name: '' is_mut: is_mut @@ -720,14 +719,14 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { arg_no++ if arg_no > 1024 { p.error_with_pos('too many args', pos) - return []table.Param{}, false, false + return []ast.Param{}, false, false } } } else { for p.tok.kind != .rpar { if p.tok.kind == .eof { p.error_with_pos('expecting `)`', p.tok.position()) - return []table.Param{}, false, false + return []ast.Param{}, false, false } is_shared := p.tok.kind == .key_shared is_atomic := p.tok.kind == .key_atomic @@ -768,7 +767,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { mut typ := p.parse_type() if typ == 0 { // error is added in parse_type - return []table.Param{}, false, false + return []ast.Param{}, false, false } if is_mut { if !typ.has_flag(.generic) { @@ -782,7 +781,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } else if is_shared || is_atomic { p.error_with_pos('generic object cannot be `atomic` or `shared`', pos) - return []table.Param{}, false, false + return []ast.Param{}, false, false } typ = typ.set_nr_muls(1) if is_shared { @@ -793,10 +792,10 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } } if is_variadic { - typ = table.new_type(p.table.find_or_register_array(typ)).derive(typ).set_flag(.variadic) + typ = ast.new_type(p.table.find_or_register_array(typ)).derive(typ).set_flag(.variadic) } for i, arg_name in arg_names { - args << table.Param{ + args << ast.Param{ pos: arg_pos[i] name: arg_name is_mut: is_mut @@ -807,12 +806,12 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { if is_variadic && p.tok.kind == .comma { p.error_with_pos('cannot use ...(variadic) with non-final parameter $arg_name', arg_pos[i]) - return []table.Param{}, false, false + return []ast.Param{}, false, false } } if p.tok.kind == .eof { p.error_with_pos('expecting `)`', p.prev_tok.position()) - return []table.Param{}, false, false + return []ast.Param{}, false, false } if p.tok.kind != .rpar { p.check(.comma) @@ -823,7 +822,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { return args, types_only, is_variadic } -fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) { +fn (mut p Parser) check_fn_mutable_arguments(typ ast.Type, pos token.Position) { sym := p.table.get_type_symbol(typ) if sym.kind in [.array, .array_fixed, .interface_, .map, .placeholder, .struct_, .sum_type] { return @@ -832,7 +831,7 @@ fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) return } if sym.kind == .alias { - atyp := (sym.info as table.Alias).parent_type + atyp := (sym.info as ast.Alias).parent_type p.check_fn_mutable_arguments(atyp, pos) return } @@ -842,7 +841,7 @@ fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) pos) } -fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position) { +fn (mut p Parser) check_fn_shared_arguments(typ ast.Type, pos token.Position) { sym := p.table.get_type_symbol(typ) if sym.kind !in [.array, .struct_, .map, .placeholder] && !typ.is_ptr() { p.error_with_pos('shared arguments are only allowed for arrays, maps, and structs\n', @@ -850,7 +849,7 @@ fn (mut p Parser) check_fn_shared_arguments(typ table.Type, pos token.Position) } } -fn (mut p Parser) check_fn_atomic_arguments(typ table.Type, pos token.Position) { +fn (mut p Parser) check_fn_atomic_arguments(typ ast.Type, pos token.Position) { sym := p.table.get_type_symbol(typ) if sym.kind !in [.u32, .int, .u64] { p.error_with_pos('atomic arguments are only allowed for 32/64 bit integers\n' + diff --git a/vlib/v/parser/for.v b/vlib/v/parser/for.v index 546585fa90..23986ab7bc 100644 --- a/vlib/v/parser/for.v +++ b/vlib/v/parser/for.v @@ -4,7 +4,6 @@ module parser import v.ast -import v.table fn (mut p Parser) for_stmt() ast.Stmt { p.check(.key_for) @@ -120,7 +119,7 @@ fn (mut p Parser) for_stmt() ast.Stmt { } p.scope.register(ast.Var{ name: key_var_name - typ: table.int_type + typ: ast.int_type pos: key_var_pos is_tmp: true }) @@ -144,7 +143,7 @@ fn (mut p Parser) for_stmt() ast.Stmt { high_expr = p.expr(0) p.scope.register(ast.Var{ name: val_var_name - typ: table.int_type + typ: ast.int_type pos: val_var_pos is_tmp: true }) diff --git a/vlib/v/parser/if_match.v b/vlib/v/parser/if_match.v index dd37d18f33..69707af67b 100644 --- a/vlib/v/parser/if_match.v +++ b/vlib/v/parser/if_match.v @@ -4,7 +4,6 @@ module parser import v.ast -import v.table import v.token fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr { @@ -52,7 +51,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr { if prev_guard { p.scope.register(ast.Var{ name: 'err' - typ: table.error_type + typ: ast.error_type pos: p.tok.position() is_used: true }) @@ -178,16 +177,16 @@ fn (mut p Parser) match_expr() ast.MatchExpr { is_else = true p.next() } else if (p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot) - && (p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() + && (p.tok.lit in ast.builtin_type_names || p.tok.lit[0].is_capital() || (p.peek_tok.kind == .dot && p.peek_token(2).lit.len > 0 && p.peek_token(2).lit[0].is_capital()))) || p.tok.kind == .lsbr { - mut types := []table.Type{} + mut types := []ast.Type{} for { // Sum type match parsed_type := p.parse_type() ecmnts << p.eat_comments({}) types << parsed_type - exprs << ast.Type{ + exprs << ast.TypeNode{ typ: parsed_type pos: p.prev_tok.position() } diff --git a/vlib/v/parser/lock.v b/vlib/v/parser/lock.v index 0f703bbb49..b2e0bceac7 100644 --- a/vlib/v/parser/lock.v +++ b/vlib/v/parser/lock.v @@ -1,7 +1,6 @@ module parser import v.ast -import v.table fn (mut p Parser) lock_expr() ast.LockExpr { // TODO Handle aliasing sync @@ -20,7 +19,7 @@ fn (mut p Parser) lock_expr() ast.LockExpr { p.next() for p.tok.kind == .name { lockeds << ast.Ident{ - language: table.Language.v + language: ast.Language.v pos: p.tok.position() mod: p.mod name: p.tok.lit diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index d5c67d3f42..2c2efeb5d7 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -3,11 +3,10 @@ // that can be found in the LICENSE file. module parser -import v.table -import v.util import v.ast +import v.util -pub fn (mut p Parser) parse_array_type() table.Type { +pub fn (mut p Parser) parse_array_type() ast.Type { p.check(.lsbr) // fixed array if p.tok.kind in [.number, .name] { @@ -44,7 +43,7 @@ pub fn (mut p Parser) parse_array_type() table.Type { } // sym := p.table.get_type_symbol(elem_type) idx := p.table.find_or_register_array_fixed(elem_type, fixed_size) - return table.new_type(idx) + return ast.new_type(idx) } // array p.check(.rsbr) @@ -62,13 +61,13 @@ pub fn (mut p Parser) parse_array_type() table.Type { nr_dims++ } idx := p.table.find_or_register_array_with_dims(elem_type, nr_dims) - return table.new_type(idx) + return ast.new_type(idx) } -pub fn (mut p Parser) parse_map_type() table.Type { +pub fn (mut p Parser) parse_map_type() ast.Type { p.next() if p.tok.kind != .lsbr { - return table.map_type + return ast.map_type } p.check(.lsbr) key_type := p.parse_type() @@ -78,12 +77,12 @@ pub fn (mut p Parser) parse_map_type() table.Type { // error is reported in parse_type return 0 } - if is_alias && !(key_type in [table.string_type_idx, table.voidptr_type_idx] + if is_alias && !(key_type in [ast.string_type_idx, ast.voidptr_type_idx] || ((key_type.is_int() || key_type.is_float()) && !key_type.is_ptr())) { p.error('cannot use the alias type as the parent type is unsupported') return 0 } - if !(key_type in [table.string_type_idx, table.voidptr_type_idx] + if !(key_type in [ast.string_type_idx, ast.voidptr_type_idx] || key_sym.kind == .enum_ || ((key_type.is_int() || key_type.is_float() || is_alias) && !key_type.is_ptr())) { s := p.table.type_to_str(key_type) @@ -97,29 +96,29 @@ pub fn (mut p Parser) parse_map_type() table.Type { // error is reported in parse_type return 0 } - if value_type.idx() == table.void_type_idx { + if value_type.idx() == ast.void_type_idx { p.error_with_pos('map value type cannot be void', p.tok.position()) return 0 } idx := p.table.find_or_register_map(key_type, value_type) - return table.new_type(idx) + return ast.new_type(idx) } -pub fn (mut p Parser) parse_chan_type() table.Type { +pub fn (mut p Parser) parse_chan_type() ast.Type { if p.peek_tok.kind != .name && p.peek_tok.kind != .key_mut && p.peek_tok.kind != .amp && p.peek_tok.kind != .lsbr { p.next() - return table.chan_type + return ast.chan_type } p.register_auto_import('sync') p.next() is_mut := p.tok.kind == .key_mut elem_type := p.parse_type() idx := p.table.find_or_register_chan(elem_type, is_mut) - return table.new_type(idx) + return ast.new_type(idx) } -pub fn (mut p Parser) parse_thread_type() table.Type { +pub fn (mut p Parser) parse_thread_type() ast.Type { is_opt := p.peek_tok.kind == .question if is_opt { p.next() @@ -128,12 +127,12 @@ pub fn (mut p Parser) parse_thread_type() table.Type { && p.peek_tok.kind != .lsbr { p.next() if is_opt { - mut ret_type := table.void_type + mut ret_type := ast.void_type ret_type = ret_type.set_flag(.optional) idx := p.table.find_or_register_thread(ret_type) - return table.new_type(idx) + return ast.new_type(idx) } else { - return table.thread_type + return ast.thread_type } } if !is_opt { @@ -141,12 +140,12 @@ pub fn (mut p Parser) parse_thread_type() table.Type { } ret_type := p.parse_type() idx := p.table.find_or_register_thread(ret_type) - return table.new_type(idx) + return ast.new_type(idx) } -pub fn (mut p Parser) parse_multi_return_type() table.Type { +pub fn (mut p Parser) parse_multi_return_type() ast.Type { p.check(.lpar) - mut mr_types := []table.Type{} + mut mr_types := []ast.Type{} for p.tok.kind != .eof { mr_type := p.parse_type() if mr_type.idx() == 0 { @@ -165,20 +164,20 @@ pub fn (mut p Parser) parse_multi_return_type() table.Type { return mr_types[0] } idx := p.table.find_or_register_multi_return(mr_types) - return table.new_type(idx) + return ast.new_type(idx) } // given anon name based off signature when `name` is blank -pub fn (mut p Parser) parse_fn_type(name string) table.Type { +pub fn (mut p Parser) parse_fn_type(name string) ast.Type { // p.warn('parse fn') p.check(.key_fn) line_nr := p.tok.line_nr args, _, is_variadic := p.fn_args() - mut return_type := table.void_type + mut return_type := ast.void_type if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() { return_type = p.parse_type() } - func := table.Fn{ + func := ast.Fn{ name: name params: args is_variadic: is_variadic @@ -188,10 +187,10 @@ pub fn (mut p Parser) parse_fn_type(name string) table.Type { // because typedefs get generated after the map struct is generated has_decl := p.builtin_mod && name.starts_with('Map') && name.ends_with('Fn') idx := p.table.find_or_register_fn_type(p.mod, func, false, has_decl) - return table.new_type(idx) + return ast.new_type(idx) } -pub fn (mut p Parser) parse_type_with_mut(is_mut bool) table.Type { +pub fn (mut p Parser) parse_type_with_mut(is_mut bool) ast.Type { typ := p.parse_type() if is_mut { return typ.set_nr_muls(1) @@ -200,13 +199,13 @@ pub fn (mut p Parser) parse_type_with_mut(is_mut bool) table.Type { } // Parses any language indicators on a type. -pub fn (mut p Parser) parse_language() table.Language { +pub fn (mut p Parser) parse_language() ast.Language { language := if p.tok.lit == 'C' { - table.Language.c + ast.Language.c } else if p.tok.lit == 'JS' { - table.Language.js + ast.Language.js } else { - table.Language.v + ast.Language.v } if language != .v { p.next() @@ -215,7 +214,7 @@ pub fn (mut p Parser) parse_language() table.Language { return language } -pub fn (mut p Parser) parse_type() table.Type { +pub fn (mut p Parser) parse_type() ast.Type { // optional mut is_optional := false if p.tok.kind == .question { @@ -223,7 +222,7 @@ pub fn (mut p Parser) parse_type() table.Type { p.next() is_optional = true if p.tok.line_nr > line_nr { - mut typ := table.void_type + mut typ := ast.void_type if is_optional { typ = typ.set_flag(.optional) } @@ -252,7 +251,7 @@ pub fn (mut p Parser) parse_type() table.Type { p.next() } language := p.parse_language() - mut typ := table.void_type + mut typ := ast.void_type is_array := p.tok.kind == .lsbr if p.tok.kind != .lcbr { pos := p.tok.position() @@ -261,7 +260,7 @@ pub fn (mut p Parser) parse_type() table.Type { // error is set in parse_type return 0 } - if typ == table.void_type { + if typ == ast.void_type { p.error_with_pos('use `?` instead of `?void`', pos) return 0 } @@ -287,7 +286,7 @@ If you need to modify an array in a function, use a mutable argument instead: `f return typ } -pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check_dot bool) table.Type { +pub fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_dot bool) ast.Type { mut name := p.tok.lit if language == .c { name = 'C.$name' @@ -358,58 +357,58 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check } match name { 'voidptr' { - return table.voidptr_type + return ast.voidptr_type } 'byteptr' { - return table.byteptr_type + return ast.byteptr_type } 'charptr' { - return table.charptr_type + return ast.charptr_type } 'i8' { - return table.i8_type + return ast.i8_type } 'i16' { - return table.i16_type + return ast.i16_type } 'int' { - return table.int_type + return ast.int_type } 'i64' { - return table.i64_type + return ast.i64_type } 'byte' { - return table.byte_type + return ast.byte_type } 'u16' { - return table.u16_type + return ast.u16_type } 'u32' { - return table.u32_type + return ast.u32_type } 'u64' { - return table.u64_type + return ast.u64_type } 'f32' { - return table.f32_type + return ast.f32_type } 'f64' { - return table.f64_type + return ast.f64_type } 'string' { - return table.string_type + return ast.string_type } 'char' { - return table.char_type + return ast.char_type } 'bool' { - return table.bool_type + return ast.bool_type } 'float_literal' { - return table.float_literal_type + return ast.float_literal_type } 'int_literal' { - return table.int_literal_type + return ast.int_literal_type } else { if name.len == 1 && name[0].is_capital() { @@ -425,42 +424,42 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check } } -pub fn (mut p Parser) parse_enum_or_struct_type(name string, language table.Language) table.Type { +pub fn (mut p Parser) parse_enum_or_struct_type(name string, language ast.Language) ast.Type { // struct / enum / placeholder // struct / enum mut idx := p.table.find_type_idx(name) if idx > 0 { - return table.new_type(idx) + return ast.new_type(idx) } // not found - add placeholder idx = p.table.add_placeholder_type(name, language) // println('NOT FOUND: $name - adding placeholder - $idx') - return table.new_type(idx) + return ast.new_type(idx) } -pub fn (mut p Parser) parse_generic_template_type(name string) table.Type { +pub fn (mut p Parser) parse_generic_template_type(name string) ast.Type { mut idx := p.table.find_type_idx(name) if idx > 0 { - return table.new_type(idx).set_flag(.generic) + return ast.new_type(idx).set_flag(.generic) } - idx = p.table.register_type_symbol(table.TypeSymbol{ + idx = p.table.register_type_symbol(ast.TypeSymbol{ name: name cname: util.no_dots(name) mod: p.mod kind: .any is_public: true }) - return table.new_type(idx).set_flag(.generic) + return ast.new_type(idx).set_flag(.generic) } -pub fn (mut p Parser) parse_generic_struct_inst_type(name string) table.Type { +pub fn (mut p Parser) parse_generic_struct_inst_type(name string) ast.Type { mut bs_name := name mut bs_cname := name p.next() p.in_generic_params = true bs_name += '<' bs_cname += '_T_' - mut generic_types := []table.Type{} + mut generic_types := []ast.Type{} mut is_instance := false for p.tok.kind != .eof { gt := p.parse_type() @@ -484,28 +483,28 @@ pub fn (mut p Parser) parse_generic_struct_inst_type(name string) table.Type { if is_instance && generic_types.len > 0 { mut gt_idx := p.table.find_type_idx(bs_name) if gt_idx > 0 { - return table.new_type(gt_idx) + return ast.new_type(gt_idx) } gt_idx = p.table.add_placeholder_type(bs_name, .v) mut parent_idx := p.table.type_idxs[name] if parent_idx == 0 { parent_idx = p.table.add_placeholder_type(name, .v) } - idx := p.table.register_type_symbol(table.TypeSymbol{ + idx := p.table.register_type_symbol(ast.TypeSymbol{ kind: .generic_struct_inst name: bs_name cname: util.no_dots(bs_cname) mod: p.mod - info: table.GenericStructInst{ + info: ast.GenericStructInst{ parent_idx: parent_idx generic_types: generic_types } }) - return table.new_type(idx) + return ast.new_type(idx) } else { idx := p.table.find_type_idx(name) if idx != 0 { - return table.new_type(idx).set_flag(.generic) + return ast.new_type(idx).set_flag(.generic) } } return p.parse_enum_or_struct_type(name, .v) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 3982cdcb5c..7c7aff3e76 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -6,7 +6,6 @@ module parser import v.scanner import v.ast import v.token -import v.table import v.pref import v.util import v.vet @@ -20,18 +19,18 @@ const ( pub struct Parser { pref &pref.Preferences mut: - file_base string // "hello.v" - file_name string // "/home/user/hello.v" - file_name_dir string // "/home/user" - file_backend_mode table.Language // .c for .c.v|.c.vv|.c.vsh files; .js for .js.v files, .amd64/.rv32/other arches for .amd64.v/.rv32.v/etc. files, .v otherwise. + file_base string // "hello.v" + file_name string // "/home/user/hello.v" + file_name_dir string // "/home/user" + file_backend_mode ast.Language // .c for .c.v|.c.vv|.c.vsh files; .js for .js.v files, .amd64/.rv32/other arches for .amd64.v/.rv32.v/etc. files, .v otherwise. scanner &scanner.Scanner comments_mode scanner.CommentsMode = .skip_comments // see comment in parse_file tok token.Token prev_tok token.Token peek_tok token.Token - table &table.Table - language table.Language + table &ast.Table + language ast.Language inside_if bool inside_if_expr bool inside_ct_if_expr bool @@ -40,12 +39,12 @@ mut: inside_fn bool // true even with implicit main inside_unsafe_fn bool inside_str_interp bool - or_is_handled bool // ignore `or` in this expression - builtin_mod bool // are we in the `builtin` module? - mod string // current module name - is_manualfree bool // true when `[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree - attrs []table.Attr // attributes before next decl stmt - expr_mod string // for constructing full type names in parse_type() + or_is_handled bool // ignore `or` in this expression + builtin_mod bool // are we in the `builtin` module? + mod string // current module name + is_manualfree bool // true when `[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree + attrs []ast.Attr // attributes before next decl stmt + expr_mod string // for constructing full type names in parse_type() scope &ast.Scope global_scope &ast.Scope imports map[string]string // alias => mod_name @@ -77,7 +76,7 @@ mut: } // for tests -pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { +pub fn parse_stmt(text string, table &ast.Table, scope &ast.Scope) ast.Stmt { mut p := Parser{ scanner: scanner.new_scanner(text, .skip_comments, &pref.Preferences{}) table: table @@ -97,7 +96,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { return p.stmt(false) } -pub fn parse_comptime(text string, table &table.Table, pref &pref.Preferences, scope &ast.Scope, global_scope &ast.Scope) ast.File { +pub fn parse_comptime(text string, table &ast.Table, pref &pref.Preferences, scope &ast.Scope, global_scope &ast.Scope) ast.File { mut p := Parser{ scanner: scanner.new_scanner(text, .skip_comments, pref) table: table @@ -110,7 +109,7 @@ pub fn parse_comptime(text string, table &table.Table, pref &pref.Preferences, s return p.parse() } -pub fn parse_text(text string, path string, table &table.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File { +pub fn parse_text(text string, path string, table &ast.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File { mut p := Parser{ scanner: scanner.new_scanner(text, comments_mode, pref) comments_mode: comments_mode @@ -156,7 +155,7 @@ pub fn (mut p Parser) set_path(path string) { } else { arch := pref.arch_from_string(actual_language) or { pref.Arch._auto } - p.file_backend_mode = table.pref_arch_to_table_language(arch) + p.file_backend_mode = ast.pref_arch_to_table_language(arch) if arch == ._auto { p.file_backend_mode = .v } @@ -164,7 +163,7 @@ pub fn (mut p Parser) set_path(path string) { } } -pub fn parse_file(path string, table &table.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File { +pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences, global_scope &ast.Scope) ast.File { // NB: when comments_mode == .toplevel_comments, // the parser gives feedback to the scanner about toplevel statements, so that the scanner can skip // all the tricky inner comments. This is needed because we do not have a good general solution @@ -190,7 +189,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment return p.parse() } -pub fn parse_vet_file(path string, table_ &table.Table, pref &pref.Preferences) (ast.File, []vet.Error) { +pub fn parse_vet_file(path string, table_ &ast.Table, pref &pref.Preferences) (ast.File, []vet.Error) { global_scope := &ast.Scope{ parent: 0 } @@ -293,7 +292,7 @@ mut: mu &sync.Mutex mu2 &sync.Mutex paths []string - table &table.Table + table &ast.Table parsed_ast_files []ast.File pref &pref.Preferences global_scope &ast.Scope @@ -319,7 +318,7 @@ fn (mut q Queue) run() { } } */ -pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, global_scope &ast.Scope) []ast.File { +pub fn parse_files(paths []string, table &ast.Table, pref &pref.Preferences, global_scope &ast.Scope) []ast.File { mut timers := util.new_timers(false) $if time_parsing ? { timers.should_print = true @@ -585,7 +584,7 @@ pub fn (mut p Parser) top_stmt() ast.Stmt { is_main: true stmts: stmts file: p.file_name - return_type: table.void_type + return_type: ast.void_type scope: p.scope label_names: p.label_names } @@ -867,7 +866,7 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt { p.check(.name) } - p.check_for_impure_v(table.pref_arch_to_table_language(arch), p.prev_tok.position()) + p.check_for_impure_v(ast.pref_arch_to_table_language(arch), p.prev_tok.position()) p.check(.lcbr) p.scope = &ast.Scope{ @@ -1454,11 +1453,11 @@ fn (mut p Parser) attributes() { } } -fn (mut p Parser) parse_attr() table.Attr { +fn (mut p Parser) parse_attr() ast.Attr { apos := p.prev_tok.position() if p.tok.kind == .key_unsafe { p.next() - return table.Attr{ + return ast.Attr{ name: 'unsafe' pos: apos.extend(p.tok.position()) } @@ -1478,10 +1477,10 @@ fn (mut p Parser) parse_attr() table.Attr { name = p.check_name() if name == 'unsafe_fn' { p.error_with_pos('[unsafe_fn] is obsolete, use `[unsafe]` instead', apos.extend(p.tok.position())) - return table.Attr{} + return ast.Attr{} } else if name == 'trusted_fn' { p.error_with_pos('[trusted_fn] is obsolete, use `[trusted]` instead', apos.extend(p.tok.position())) - return table.Attr{} + return ast.Attr{} } else if name == 'ref_only' { p.warn_with_pos('[ref_only] is deprecated, use [heap] instead', apos.extend(p.tok.position())) name = 'heap' @@ -1498,7 +1497,7 @@ fn (mut p Parser) parse_attr() table.Attr { } } } - return table.Attr{ + return ast.Attr{ name: name is_string: is_string is_comptime_define: is_comptime_define @@ -1508,7 +1507,7 @@ fn (mut p Parser) parse_attr() table.Attr { } } -pub fn (mut p Parser) check_for_impure_v(language table.Language, pos token.Position) { +pub fn (mut p Parser) check_for_impure_v(language ast.Language, pos token.Position) { if language == .v { // pure V code is always allowed everywhere return @@ -1698,7 +1697,7 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt { } } -pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident { +pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident { // p.warn('name ') is_shared := p.tok.kind == .key_shared is_atomic := p.tok.kind == .key_atomic @@ -1748,7 +1747,7 @@ pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident { info: ast.IdentVar{ is_mut: is_mut is_static: is_static - share: table.sharetype_from_flags(is_shared, is_atomic) + share: ast.sharetype_from_flags(is_shared, is_atomic) } scope: p.scope } @@ -1817,17 +1816,17 @@ pub fn (mut p Parser) name_expr() ast.Expr { // get type position before moving to next type_pos := p.tok.position() typ := p.parse_type() - return ast.Type{ + return ast.TypeNode{ typ: typ pos: type_pos } } - mut language := table.Language.v + mut language := ast.Language.v if p.tok.lit == 'C' { - language = table.Language.c + language = ast.Language.c p.check_for_impure_v(language, p.tok.position()) } else if p.tok.lit == 'JS' { - language = table.Language.js + language = ast.Language.js p.check_for_impure_v(language, p.tok.position()) } mut mod := '' @@ -1947,7 +1946,7 @@ pub fn (mut p Parser) name_expr() ast.Expr { } name_w_mod := p.prepend_mod(name) // type cast. TODO: finish - // if name in table.builtin_type_names { + // if name in ast.builtin_type_names { if (!known_var && (name in p.table.type_idxs || name_w_mod in p.table.type_idxs) && name !in ['C.stat', 'C.sigaction']) || is_mod_cast || (language == .v && name[0].is_capital()) { @@ -1969,7 +1968,7 @@ pub fn (mut p Parser) name_expr() ast.Expr { mut has_arg := false expr = p.expr(0) // TODO, string(b, len) - if p.tok.kind == .comma && to_typ.idx() == table.string_type_idx { + if p.tok.kind == .comma && to_typ.idx() == ast.string_type_idx { p.next() arg = p.expr(0) // len has_arg = true @@ -2189,7 +2188,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr { } // Method call // TODO move to fn.v call_expr() - mut generic_types := []table.Type{} + mut generic_types := []ast.Type{} mut generic_list_pos := p.tok.position() if is_generic_call { // `g.foo(10)` @@ -2215,7 +2214,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr { p.open_scope() p.scope.register(ast.Var{ name: 'err' - typ: table.error_type + typ: ast.error_type pos: p.tok.position() is_used: true }) @@ -2281,8 +2280,8 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr { return sel_expr } -fn (mut p Parser) parse_generic_type_list() []table.Type { - mut types := []table.Type{} +fn (mut p Parser) parse_generic_type_list() []ast.Type { + mut types := []ast.Type{} if p.tok.kind != .lt { return types } @@ -2325,7 +2324,7 @@ fn (mut p Parser) string_expr() ast.Expr { node = ast.StringLiteral{ val: val is_raw: is_raw - language: if is_cstr { table.Language.c } else { table.Language.v } + language: if is_cstr { ast.Language.c } else { ast.Language.v } pos: pos } return node @@ -2443,7 +2442,7 @@ fn (mut p Parser) parse_number_literal() ast.Expr { } fn (mut p Parser) module_decl() ast.Module { - mut module_attrs := []table.Attr{} + mut module_attrs := []ast.Attr{} mut attrs_pos := p.tok.position() if p.tok.kind == .lsbr { p.attributes() @@ -2874,12 +2873,12 @@ fn (mut p Parser) enum_decl() ast.EnumDecl { // ') } - idx := p.table.register_type_symbol(table.TypeSymbol{ + idx := p.table.register_type_symbol(ast.TypeSymbol{ kind: .enum_ name: name cname: util.no_dots(name) mod: p.mod - info: table.Enum{ + info: ast.Enum{ vals: vals is_flag: is_flag is_multi_allowed: is_multi_allowed @@ -2963,12 +2962,12 @@ fn (mut p Parser) type_decl() ast.TypeDecl { } variant_types := sum_variants.map(it.typ) prepend_mod_name := p.prepend_mod(name) - typ := p.table.register_type_symbol(table.TypeSymbol{ + typ := p.table.register_type_symbol(ast.TypeSymbol{ kind: .sum_type name: prepend_mod_name cname: util.no_dots(prepend_mod_name) mod: p.mod - info: table.SumType{ + info: ast.SumType{ variants: variant_types } is_public: is_pub @@ -2989,13 +2988,13 @@ fn (mut p Parser) type_decl() ast.TypeDecl { pidx := parent_type.idx() p.check_for_impure_v(parent_sym.language, decl_pos) prepend_mod_name := p.prepend_mod(name) - idx := p.table.register_type_symbol(table.TypeSymbol{ + idx := p.table.register_type_symbol(ast.TypeSymbol{ kind: .alias name: prepend_mod_name cname: util.no_dots(prepend_mod_name) mod: p.mod parent_idx: pidx - info: table.Alias{ + info: ast.Alias{ parent_type: parent_type language: parent_sym.language } diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index 39b1fd53d1..3d77195060 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -5,7 +5,6 @@ module parser import v.ast import v.vet -import v.table import v.token pub fn (mut p Parser) expr(precedence int) ast.Expr { @@ -23,7 +22,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr { // Prefix match p.tok.kind { .key_mut, .key_shared, .key_atomic, .key_static { - node = p.parse_ident(table.Language.v) + node = p.parse_ident(ast.Language.v) p.is_stmt_ident = is_stmt_ident } .name { @@ -292,7 +291,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr { if p.expecting_type { // Anonymous function type start_pos := p.tok.position() - return ast.Type{ + return ast.TypeNode{ typ: p.parse_type() pos: start_pos.extend(p.prev_tok.position()) } @@ -460,7 +459,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr { p.open_scope() p.scope.register(ast.Var{ name: 'err' - typ: table.error_type + typ: ast.error_type pos: p.tok.position() is_used: true }) @@ -523,7 +522,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr { p.open_scope() p.scope.register(ast.Var{ name: 'err' - typ: table.error_type + typ: ast.error_type pos: p.tok.position() is_used: true }) diff --git a/vlib/v/parser/sql.v b/vlib/v/parser/sql.v index 83de05debf..f5f198b610 100644 --- a/vlib/v/parser/sql.v +++ b/vlib/v/parser/sql.v @@ -4,7 +4,6 @@ module parser import v.ast -import v.table fn (mut p Parser) sql_expr() ast.Expr { // `sql db {` @@ -15,10 +14,10 @@ fn (mut p Parser) sql_expr() ast.Expr { p.check(.key_select) n := p.check_name() is_count := n == 'count' - mut typ := table.void_type + mut typ := ast.void_type if is_count { p.check_name() // from - typ = table.int_type + typ = ast.int_type } table_pos := p.tok.position() table_type := p.parse_type() // `User` @@ -77,7 +76,7 @@ fn (mut p Parser) sql_expr() ast.Expr { } if !query_one && !is_count { // return an array - typ = table.new_type(p.table.find_or_register_array(table_type)) + typ = ast.new_type(p.table.find_or_register_array(table_type)) } else if !is_count { // return a single object // TODO optional @@ -100,7 +99,7 @@ fn (mut p Parser) sql_expr() ast.Expr { has_desc: has_desc is_array: !query_one pos: pos.extend(p.prev_tok.position()) - table_expr: ast.Type{ + table_expr: ast.TypeNode{ typ: table_type pos: table_pos } @@ -130,7 +129,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt { kind = .update } mut inserted_var_name := '' - mut table_type := table.Type(0) + mut table_type := ast.Type(0) if kind != .delete { if kind == .update { table_type = p.parse_type() @@ -189,7 +188,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt { pos.last_line = p.prev_tok.line_nr return ast.SqlStmt{ db_expr: db_expr - table_expr: ast.Type{ + table_expr: ast.TypeNode{ typ: table_type pos: table_pos } diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index ac8a921a9d..1a236ec8dc 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -4,7 +4,6 @@ module parser import v.ast -import v.table import v.token import v.util @@ -25,11 +24,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl { p.check(.key_union) } language := if p.tok.lit == 'C' && p.peek_tok.kind == .dot { - table.Language.c + ast.Language.c } else if p.tok.lit == 'JS' && p.peek_tok.kind == .dot { - table.Language.js + ast.Language.js } else { - table.Language.v + ast.Language.v } if language != .v { p.next() // C || JS @@ -48,7 +47,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { name_pos) return ast.StructDecl{} } - mut generic_types := []table.Type{} + mut generic_types := []ast.Type{} if p.tok.kind == .lt { p.next() for { @@ -85,8 +84,8 @@ fn (mut p Parser) struct_decl() ast.StructDecl { name = p.prepend_mod(name) } mut ast_fields := []ast.StructField{} - mut fields := []table.Field{} - mut embed_types := []table.Type{} + mut fields := []ast.StructField{} + mut embed_types := []ast.Type{} mut embeds := []ast.Embed{} mut embed_field_names := []string{} mut mut_pos := -1 @@ -181,7 +180,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { || p.peek_tok.kind == .dot) && language == .v && p.peek_tok.kind != .key_fn is_on_top := ast_fields.len == 0 && !(is_field_mut || is_field_mut || is_field_global) mut field_name := '' - mut typ := table.Type(0) + mut typ := ast.Type(0) mut type_pos := token.Position{} mut field_pos := token.Position{} if is_embed { @@ -254,31 +253,33 @@ fn (mut p Parser) struct_decl() ast.StructDecl { has_default_expr = true comments << p.eat_comments({}) } - // TODO merge table and ast Fields? ast_fields << ast.StructField{ name: field_name + typ: typ pos: field_pos type_pos: type_pos - typ: typ comments: comments default_expr: default_expr has_default_expr: has_default_expr attrs: p.attrs - is_public: is_field_pub + is_pub: is_embed || is_field_pub + is_mut: is_embed || is_field_mut + is_global: is_field_global } } - is_pub_field := is_embed || is_field_pub - is_mut_field := is_embed || is_field_mut // save embeds as table fields too, it will be used in generation phase - fields << table.Field{ + fields << ast.StructField{ name: field_name typ: typ - default_expr: ast.ex2fe(default_expr) + pos: field_pos + type_pos: type_pos + comments: comments + default_expr: default_expr has_default_expr: has_default_expr - is_pub: is_pub_field - is_mut: is_mut_field - is_global: is_field_global attrs: p.attrs + is_pub: is_embed || is_field_pub + is_mut: is_embed || is_field_mut + is_global: is_field_global } p.attrs = [] } @@ -286,13 +287,13 @@ fn (mut p Parser) struct_decl() ast.StructDecl { last_line = p.tok.line_nr p.check(.rcbr) } - t := table.TypeSymbol{ + t := ast.TypeSymbol{ kind: .struct_ language: language name: name cname: util.no_dots(name) mod: p.mod - info: table.Struct{ + info: ast.Struct{ embeds: embed_types fields: fields is_typedef: attrs.contains('typedef') @@ -338,7 +339,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit { first_pos := p.tok.position() - typ := if short_syntax { table.void_type } else { p.parse_type() } + typ := if short_syntax { ast.void_type } else { p.parse_type() } p.expr_mod = '' // sym := p.table.get_type_symbol(typ) // p.warn('struct init typ=$sym.name') @@ -449,7 +450,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { name: interface_name cname: util.no_dots(interface_name) mod: p.mod - info: table.Interface{ + info: ast.Interface{ types: [] } ) @@ -458,11 +459,11 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { name_pos) return ast.InterfaceDecl{} } - typ := table.new_type(reg_idx) + typ := ast.new_type(reg_idx) mut ts := p.table.get_type_symbol(typ) - mut info := ts.info as table.Interface + mut info := ts.info as ast.Interface // if methods were declared before, it's an error, ignore them - ts.methods = []table.Fn{cap: 20} + ts.methods = []ast.Fn{cap: 20} // Parse fields or methods mut fields := []ast.StructField{cap: 20} mut methods := []ast.FnDecl{cap: 20} @@ -496,8 +497,8 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { return ast.InterfaceDecl{} } // field_names << name - args2, _, is_variadic := p.fn_args() // TODO merge table.Param and ast.Arg to avoid this - mut args := [table.Param{ + args2, _, is_variadic := p.fn_args() // TODO merge ast.Param and ast.Arg to avoid this + mut args := [ast.Param{ name: 'x' is_mut: is_mut typ: typ @@ -509,7 +510,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { mod: p.mod params: args file: p.file_name - return_type: table.void_type + return_type: ast.void_type is_variadic: is_variadic is_pub: true pos: method_start_pos.extend(p.prev_tok.position()) @@ -524,7 +525,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { method.next_comments = mnext_comments methods << method // println('register method $name') - tmethod := table.Fn{ + tmethod := ast.Fn{ name: name params: args return_type: method.return_type @@ -553,9 +554,9 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { type_pos: type_pos typ: field_typ comments: comments - is_public: true + is_pub: true } - info.fields << table.Field{ + info.fields << ast.StructField{ name: field_name typ: field_typ is_pub: true diff --git a/vlib/v/parser/v_parser_test.v b/vlib/v/parser/v_parser_test.v index 85af6e2186..c3aa19f7f5 100644 --- a/vlib/v/parser/v_parser_test.v +++ b/vlib/v/parser/v_parser_test.v @@ -3,10 +3,8 @@ module parser // import v.eval import v.ast import v.gen.c -import v.table import v.checker import v.pref -import v.scanner import term fn test_eval() { @@ -35,7 +33,7 @@ fn test_eval() { '20', // ] - table := table.new_table() + table := ast.new_table() vpref := &pref.Preferences{} mut scope := &ast.Scope{ start_pos: 0 @@ -76,7 +74,7 @@ x := 10 5+7 8+4 ' - table := &table.Table{} + table := &ast.Table{} vpref := &pref.Preferences{} gscope := &ast.Scope{ parent: 0 @@ -95,7 +93,7 @@ fn test_one() { println('\n\ntest_one()') input := ['a := 10', 'b := -a', 'c := 20'] expected := 'int a = 10;int b = -a;int c = 20;' - table := table.new_table() + table := ast.new_table() vpref := &pref.Preferences{} scope := &ast.Scope{ start_pos: 0 @@ -136,7 +134,7 @@ fn test_parse_expr() { 'string s = tos3("hi");', 'x = 11;', 'a += 10;', '1.2 + 3.4;', '4 + 4;', '1 + 2 * 5;', '-a + 1;', '2 + 2;'] mut e := []ast.Stmt{} - table := table.new_table() + table := ast.new_table() vpref := &pref.Preferences{} mut checker := checker.new_checker(table, vpref) scope := &ast.Scope{ @@ -184,7 +182,7 @@ fn test_num_literals() { 'c := -12.', 'd := -a', ] - table := table.new_table() + table := ast.new_table() mut scope := &ast.Scope{ start_pos: 0 parent: 0 @@ -211,7 +209,7 @@ fn test_num_literals() { } /* -table := &table.Table{} +table := &ast.Table{} for s in text_expr { // print using str method x := parse_expr(s, table) diff --git a/vlib/v/pref/default.v b/vlib/v/pref/default.v index 09e2b6e6ca..17fcd1e6ea 100644 --- a/vlib/v/pref/default.v +++ b/vlib/v/pref/default.v @@ -76,7 +76,7 @@ pub fn (mut p Preferences) fill_with_defaults() { // executable on Windows + the precompiled V is more // optimized. println('Saving the resulting V executable in `./v2`') - println('Use `v -o v cmd/v` if you want to replace current ' + 'V executable.') + println('Use `v -o v cmd/v` if you want to replace current ' + 'V execuast.') p.out_name = 'v2' } } diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 5809914557..0e41352fff 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -561,7 +561,7 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences must_exist(res.path) if !res.path.ends_with('.v') && os.is_executable(res.path) && os.is_file(res.path) && os.is_file(res.path + '.v') { - eprintln('It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "$res.path" is an executable.') + eprintln('It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "$res.path" is an execuast.') res.path += '.v' } } diff --git a/vlib/v/preludes/live_main.v b/vlib/v/preludes/live_main.v index 131cde237a..75f6c44d95 100644 --- a/vlib/v/preludes/live_main.v +++ b/vlib/v/preludes/live_main.v @@ -1,7 +1,7 @@ module main // This prelude is loaded in every v program compiled with -live, -// but only for the main executable. +// but only for the main execuast. import v.live.executable const ( diff --git a/vlib/v/table/types_test.v b/vlib/v/table/types_test.v deleted file mode 100644 index 3c2091fa58..0000000000 --- a/vlib/v/table/types_test.v +++ /dev/null @@ -1,81 +0,0 @@ -import v.table - -fn test_idx() { - mut t := table.new_type(table.void_type_idx) - assert t.idx() == table.void_type_idx - t = table.new_type(table.i8_type_idx) - assert t.idx() == table.i8_type_idx -} - -fn test_muls() { - mut t := table.new_type(table.void_type_idx) - idx := t.idx() - assert t.nr_muls() == 0 - for i in 0 .. 32 { - t = t.set_nr_muls(i) - assert t.nr_muls() == i - } - t = t.set_nr_muls(0) - assert t.nr_muls() == 0 - assert t.is_ptr() == false - t = t.to_ptr() - assert t.nr_muls() == 1 - assert t.is_ptr() == true - t = t.to_ptr() - assert t.nr_muls() == 2 - assert t.is_ptr() == true - t = t.deref() - assert t.nr_muls() == 1 - assert t.is_ptr() == true - t = t.deref() - assert t.nr_muls() == 0 - assert t.is_ptr() == false - assert t.idx() == idx -} - -fn test_flags() { - mut t := table.new_type(table.void_type_idx) - idx := t.idx() - nr_muls := t.nr_muls() - t = t.set_flag(table.TypeFlag.optional) - assert t.has_flag(table.TypeFlag.optional) == true - assert t.has_flag(table.TypeFlag.variadic) == false - assert t.has_flag(table.TypeFlag.generic) == false - t = t.set_flag(table.TypeFlag.variadic) - assert t.has_flag(table.TypeFlag.optional) == true - assert t.has_flag(table.TypeFlag.variadic) == true - assert t.has_flag(table.TypeFlag.generic) == false - t = t.set_flag(table.TypeFlag.generic) - assert t.has_flag(table.TypeFlag.optional) == true - assert t.has_flag(table.TypeFlag.variadic) == true - assert t.has_flag(table.TypeFlag.generic) == true - assert t.idx() == idx - assert t.nr_muls() == nr_muls - t = t.clear_flag(table.TypeFlag.optional) - assert t.has_flag(table.TypeFlag.optional) == false - assert t.has_flag(table.TypeFlag.variadic) == true - assert t.has_flag(table.TypeFlag.generic) == true - t = t.clear_flag(table.TypeFlag.variadic) - assert t.has_flag(table.TypeFlag.optional) == false - assert t.has_flag(table.TypeFlag.variadic) == false - assert t.has_flag(table.TypeFlag.generic) == true - t = t.clear_flag(table.TypeFlag.generic) - assert t.has_flag(table.TypeFlag.optional) == false - assert t.has_flag(table.TypeFlag.variadic) == false - assert t.has_flag(table.TypeFlag.generic) == false - assert t.idx() == idx - assert t.nr_muls() == nr_muls -} - -fn test_derive() { - mut t := table.new_type(table.i8_type_idx) - t = t.set_flag(table.TypeFlag.generic) - t = t.set_flag(table.TypeFlag.variadic) - t = t.set_nr_muls(10) - mut t2 := table.new_type(table.i16_type_idx) - t2 = t2.derive(t) - assert t2.has_flag(table.TypeFlag.optional) == false - assert t2.has_flag(table.TypeFlag.variadic) == true - assert t2.has_flag(table.TypeFlag.generic) == true - assert t2.nr_muls() == 10 -} diff --git a/vlib/v/tests/fn_expecting_ref_but_returning_struct_test.v b/vlib/v/tests/fn_expecting_ref_but_returning_struct_test.v index 98c5c71855..93c836bd1c 100644 --- a/vlib/v/tests/fn_expecting_ref_but_returning_struct_test.v +++ b/vlib/v/tests/fn_expecting_ref_but_returning_struct_test.v @@ -16,7 +16,7 @@ fn get_foo() Foo { } /* -// TODO: Fix this. It 'works' only with tcc, but is not stable. +// TODO: Fix this. It 'works' only with tcc, but is not sast. fn test_ref_fn_arg() { process_foo(get_foo()) println(3434) diff --git a/vlib/v/tests/interface_edge_cases/i7_test.v b/vlib/v/tests/interface_edge_cases/i7_test.v index 1b70481c0b..ff6c113fba 100644 --- a/vlib/v/tests/interface_edge_cases/i7_test.v +++ b/vlib/v/tests/interface_edge_cases/i7_test.v @@ -18,7 +18,7 @@ fn (p Point) draw() string { } // Note: this helper function forced the compiler to generate an -// interface dispatch table. Now, it should not be needed anymore, +// interface dispatch ast. Now, it should not be needed anymore, // but it is better to test it too, to prevent future interface regressions. fn (x Point) tointerface() Drawable { return x diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index d1b6bc7d87..7fe27912d1 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -458,7 +458,7 @@ pub fn (kind Kind) is_infix() bool { .right_shift, .arrow] } -// Pass table.builtin_type_names +// Pass ast.builtin_type_names // Note: can't import table here due to circular module dependency pub fn (tok &Token) can_start_type(builtin_type_names []string) bool { match tok.kind {