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)
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 {

View File

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

View File

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