compiler: circuimvent the dependency cycle v.ast <-> v.table

pull/4684/head
Delyan Angelov 2020-05-02 22:51:55 +03:00
parent dbbfb04e7c
commit 7e4e3abc2c
4 changed files with 34 additions and 10 deletions

View File

@ -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
}

View File

@ -2084,7 +2084,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
field_name := c_name(field.name) field_name := c_name(field.name)
g.write('\t.$field_name = ') g.write('\t.$field_name = ')
if field.has_default_expr { if field.has_default_expr {
g.expr(field.default_expr) g.expr( ast.fe2ex(field.default_expr) )
} else { } else {
g.write(g.type_default(field.typ)) 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.Alias, table.SumType { TODO
} }
table.SumType { table.SumType {
g.definitions.writeln('// Sum type') g.definitions.writeln('')
g.definitions.writeln(' g.definitions.writeln('// Sum type $name = ')
typedef struct { for sv in it.variants {
void* obj; g.definitions.writeln('// | ${sv:4d} = ${g.typ(sv):-20s}')
int typ; }
} $name;') g.definitions.writeln('typedef struct {')
g.definitions.writeln(' void* obj;')
g.definitions.writeln(' int typ;')
g.definitions.writeln('} $name;')
g.definitions.writeln('')
} }
table.ArrayFixed { table.ArrayFixed {
// .array_fixed { // .array_fixed {

View File

@ -135,7 +135,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
fields << table.Field{ fields << table.Field{
name: field_name name: field_name
typ: typ typ: typ
default_expr: default_expr default_expr: ast.ex2fe( default_expr )
has_default_expr: has_default_expr has_default_expr: has_default_expr
is_pub: is_field_pub is_pub: is_field_pub
is_mut: is_field_mut is_mut: is_field_mut

View File

@ -12,7 +12,6 @@
module table module table
import strings import strings
import v.ast
pub type Type int pub type Type int
@ -536,12 +535,17 @@ pub:
foo string 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 struct Field {
pub: pub:
name string name string
mut: mut:
typ Type typ Type
default_expr ast.Expr default_expr FExpr
has_default_expr bool has_default_expr bool
default_val string default_val string
attr string attr string