diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index bdc434ac24..13cd8f510b 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -928,3 +928,19 @@ fn (stmt Stmt) position() token.Position { } } } + +// 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 { + res := Expr{} + C.memcpy(&res, &x, sizeof(Expr)) + return res +} +pub fn ex2fe(x Expr) table.FExpr { + res := table.FExpr{} + C.memcpy(&res, &x, sizeof(table.FExpr)) + return res +} diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 10690cf5a6..bd1147fa85 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2084,7 +2084,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) { field_name := c_name(field.name) g.write('\t.$field_name = ') if field.has_default_expr { - g.expr(field.default_expr) + g.expr( ast.fe2ex(field.default_expr) ) } else { g.write(g.type_default(field.typ)) } @@ -2249,12 +2249,16 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { // table.Alias, table.SumType { TODO } table.SumType { - g.definitions.writeln('// Sum type') - g.definitions.writeln(' - typedef struct { -void* obj; -int typ; -} $name;') + g.definitions.writeln('') + g.definitions.writeln('// Sum type $name = ') + for sv in it.variants { + g.definitions.writeln('// | ${sv:4d} = ${g.typ(sv):-20s}') + } + g.definitions.writeln('typedef struct {') + g.definitions.writeln(' void* obj;') + g.definitions.writeln(' int typ;') + g.definitions.writeln('} $name;') + g.definitions.writeln('') } table.ArrayFixed { // .array_fixed { diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index dedef9353a..90529a7d9e 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -135,7 +135,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { fields << table.Field{ name: field_name typ: typ - default_expr: default_expr + default_expr: ast.ex2fe( default_expr ) has_default_expr: has_default_expr is_pub: is_field_pub is_mut: is_field_mut diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 3285ce2e61..b252f254a9 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -12,7 +12,6 @@ module table import strings -import v.ast pub type Type int @@ -536,12 +535,17 @@ pub: foo string } +// 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 . +type FExpr = voidptr | byteptr + pub struct Field { pub: name string mut: typ Type - default_expr ast.Expr + default_expr FExpr has_default_expr bool default_val string attr string