From 1b3cd7abe041b4df6e8c46d15e9af9d09bed2c03 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Mon, 11 May 2020 16:59:55 +1000 Subject: [PATCH] cgen: fix sum type assign/push from in match branch & type mod --- vlib/v/ast/ast.v | 4 ++-- vlib/v/checker/checker.v | 2 +- vlib/v/gen/cgen.v | 6 +++--- vlib/v/parser/fn.v | 2 +- vlib/v/parser/parse_type.v | 2 +- vlib/v/parser/parser.v | 3 +++ vlib/v/parser/struct.v | 1 + vlib/v/table/atypes.v | 25 +++++++++++++++++++++++++ vlib/v/table/table.v | 9 ++++++--- vlib/v/tests/sum_type_test.v | 18 ++++++++++++++++++ 10 files changed, 61 insertions(+), 11 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 0196afb5b7..86735a74d1 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -773,7 +773,7 @@ pub fn expr_is_call(expr Expr) bool { } } -fn (expr Expr) position() token.Position { +pub fn (expr Expr) position() token.Position { // all uncommented have to be implemented match mut expr { ArrayInit { @@ -867,7 +867,7 @@ fn (expr Expr) position() token.Position { } } -fn (stmt Stmt) position() token.Position { +pub fn (stmt Stmt) position() token.Position { match mut stmt { AssertStmt { return it.pos diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 034ef53130..516bb00157 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1821,7 +1821,7 @@ pub fn (mut c Checker) ident(ident mut 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(func, false, true)) + fn_type := table.new_type(c.table.find_or_register_fn_type(ident.mod, func, false, true)) ident.name = name ident.kind = .function ident.info = ast.IdentFn{ diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 59ad7df00a..6616a25315 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -979,10 +979,10 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { } } else { g.write(' = ') - if !is_decl { - g.expr_with_cast(val, assign_stmt.left_types[i], ident_var_info.typ) - } else { + if is_decl { g.expr(val) + } else { + g.expr_with_cast(val, assign_stmt.left_types[i], ident_var_info.typ) } } if gen_or { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index d436eee174..e95b108b95 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -307,7 +307,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn { } name := 'anon_${p.tok.pos}_$func.signature()' func.name = name - idx := p.table.find_or_register_fn_type(func, true, false) + idx := p.table.find_or_register_fn_type(p.mod, func, true, false) typ := table.new_type(idx) // name := p.table.get_type_name(typ) return ast.AnonFn{ diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index fceeccca0a..931ce51180 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -84,7 +84,7 @@ pub fn (mut p Parser) parse_fn_type(name string) table.Type { is_variadic: is_variadic return_type: return_type } - idx := p.table.find_or_register_fn_type(func, false, false) + idx := p.table.find_or_register_fn_type(p.mod, func, false, false) return table.new_type(idx) } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index dbe7521461..808d3345b8 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1211,6 +1211,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl { p.table.register_type_symbol(table.TypeSymbol{ kind: .enum_ name: name + mod: p.mod info: table.Enum{ vals: vals } @@ -1264,6 +1265,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl { p.table.register_type_symbol(table.TypeSymbol{ kind: .sum_type name: p.prepend_mod(name) + mod: p.mod info: table.SumType{ variants: sum_variants } @@ -1283,6 +1285,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl { kind: .alias name: p.prepend_mod(name) parent_idx: pid + mod: p.mod info: table.Alias{ foo: '' } diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 6e3521cb04..456eccfb85 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -275,6 +275,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { t := table.TypeSymbol{ kind: .interface_ name: interface_name + mod: p.mod info: table.Interface{ types: [] } diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 230dfea698..6b5fe633e4 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -357,94 +357,117 @@ pub fn (mut t Table) register_builtin_type_symbols() { t.register_type_symbol(TypeSymbol{ kind: .void name: 'void' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .voidptr name: 'voidptr' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .byteptr name: 'byteptr' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .charptr name: 'charptr' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .i8 name: 'i8' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .i16 name: 'i16' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .int name: 'int' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .i64 name: 'i64' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .byte name: 'byte' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .u16 name: 'u16' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .u32 name: 'u32' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .u64 name: 'u64' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .f32 name: 'f32' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .f64 name: 'f64' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .char name: 'char' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .bool name: 'bool' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .none_ name: 'none' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .string name: 'string' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .ustring name: 'ustring' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .array name: 'array' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .map name: 'map' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .any name: 'any' + mod: 'builtin' }) t.register_type_symbol(TypeSymbol{ kind: .size_t name: 'size_t' + mod: 'builtin' }) // TODO: remove. for v1 map compatibility map_string_string_idx := t.find_or_register_map(string_type, string_type) @@ -452,11 +475,13 @@ pub fn (mut t Table) register_builtin_type_symbols() { t.register_type_symbol(TypeSymbol{ kind: .alias name: 'map_string' + mod: 'builtin' parent_idx: map_string_string_idx }) t.register_type_symbol(TypeSymbol{ kind: .alias name: 'map_int' + mod: 'builtin' parent_idx: map_string_int_idx }) } diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 55c26bc603..50599d4e35 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -374,12 +374,13 @@ pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int { return t.register_type_symbol(mr_type) } -pub fn (mut t Table) find_or_register_fn_type(f Fn, is_anon, has_decl bool) int { +pub fn (mut t Table) find_or_register_fn_type(mod string, f Fn, is_anon, has_decl bool) int { name := if f.name.len == 0 { 'anon_fn_$f.signature()' } else { f.name } anon := f.name.len == 0 || is_anon return t.register_type_symbol(TypeSymbol{ kind: .function name: name + mod: mod info: FnType{ is_anon: anon has_decl: has_decl @@ -516,13 +517,15 @@ pub fn (t &Table) check(got, expected Type) bool { // sum type if got_type_sym.kind == .sum_type { sum_info := got_type_sym.info as SumType - if expected in sum_info.variants { + // TODO: handle `match SumType { &PtrVariant {} }` currently just checking base + if expected.set_nr_muls(0) in sum_info.variants { return true } } if exp_type_sym.kind == .sum_type { sum_info := exp_type_sym.info as SumType - if got in sum_info.variants { + // TODO: handle `match SumType { &PtrVariant {} }` currently just checking base + if got.set_nr_muls(0) in sum_info.variants { return true } } diff --git a/vlib/v/tests/sum_type_test.v b/vlib/v/tests/sum_type_test.v index e4230a3172..da856b2a64 100644 --- a/vlib/v/tests/sum_type_test.v +++ b/vlib/v/tests/sum_type_test.v @@ -33,3 +33,21 @@ fn test_expr() { assert handle(expr) == 'int' // assert expr is IntegerLiteral // TODO } + +fn test_assignment_and_push() { + mut expr1 := Expr{} + mut arr1 := []Expr{} + expr := IntegerLiteral{ + val: '111' + } + arr1 << expr + match arr1[0] { + IntegerLiteral { + arr1 << it + // should ref/dereference on assignent be made automatic? + // currently it is done for return stmt and fn args + expr1 = *it + } + else {} + } +}