cgen/parser: fix unions

pull/4290/head
Alexander Medvednikov 2020-04-08 01:20:55 +02:00
parent cdcb8b6c06
commit 7ff0c3aaa9
5 changed files with 26 additions and 12 deletions

View File

@ -74,5 +74,5 @@ fn test_atof() {
// DOUBLE_MINUS_ZERO // DOUBLE_MINUS_ZERO
f1=-0.0 f1=-0.0
assert *ptr == u64(0x8000000000000000) assert *ptr == u64(0x8000000000000000)
//println("DONE!") println("DONE!")
} }

View File

@ -150,6 +150,7 @@ pub:
pub_pos int // pub: pub_pos int // pub:
pub_mut_pos int // pub mut: pub_mut_pos int // pub mut:
is_c bool is_c bool
is_union bool
} }
pub struct InterfaceDecl { pub struct InterfaceDecl {

View File

@ -86,7 +86,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
indent: -1 indent: -1
} }
g.init() g.init()
// //
mut autofree_used := false mut autofree_used := false
for file in files { for file in files {
g.file = file g.file = file
@ -115,7 +115,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
if g.is_test { if g.is_test {
g.write_tests_main() g.write_tests_main()
} }
// //
g.finish() g.finish()
return g.hashes() + g.includes.str() + g.typedefs.str() + g.typedefs2.str() + g.definitions.str() + return g.hashes() + g.includes.str() + g.typedefs.str() + g.typedefs2.str() + g.definitions.str() +
g.gowrappers.str() + g.stringliterals.str() + g.out.str() g.gowrappers.str() + g.stringliterals.str() + g.out.str()
@ -141,7 +141,7 @@ pub fn (g mut Gen) init() {
g.write_sorted_types() g.write_sorted_types()
g.write_multi_return_types() g.write_multi_return_types()
g.definitions.writeln('// end of definitions #endif') g.definitions.writeln('// end of definitions #endif')
// //
g.stringliterals.writeln('') g.stringliterals.writeln('')
g.stringliterals.writeln('// >> string literal consts') g.stringliterals.writeln('// >> string literal consts')
g.stringliterals.writeln('void vinit_string_literals(){') g.stringliterals.writeln('void vinit_string_literals(){')
@ -205,7 +205,7 @@ pub fn (g mut Gen) typ(t table.Type) string {
return styp return styp
} }
// //
pub fn (g mut Gen) write_typedef_types() { pub fn (g mut Gen) write_typedef_types() {
for typ in g.table.types { for typ in g.table.types {
match typ.kind { match typ.kind {
@ -460,7 +460,12 @@ fn (g mut Gen) stmt(node ast.Stmt) {
// g.writeln('\t$field_type_sym.name $field.name;') // g.writeln('\t$field_type_sym.name $field.name;')
// } // }
// g.writeln('} $name;') // g.writeln('} $name;')
if !it.is_c { if it.is_c {
return
}
if it.is_union {
g.typedefs.writeln('typedef union $name $name;')
} else {
g.typedefs.writeln('typedef struct $name $name;') g.typedefs.writeln('typedef struct $name $name;')
} }
} }
@ -817,7 +822,7 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
} }
} }
*/ */
// //
g.fn_args(it.args, it.is_variadic) g.fn_args(it.args, it.is_variadic)
if it.no_body { if it.no_body {
// Just a function header. // Just a function header.
@ -1452,7 +1457,7 @@ fn (g mut Gen) match_expr(node ast.MatchExpr) {
// sum_type_str // sum_type_str
} else if type_sym.kind == .string { } else if type_sym.kind == .string {
g.write('string_eq(') g.write('string_eq(')
// //
g.expr(node.cond) g.expr(node.cond)
g.write(', ') g.write(', ')
// g.write('string_eq($tmp, ') // g.write('string_eq($tmp, ')
@ -2121,7 +2126,11 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
table.Struct { table.Struct {
info := typ.info as table.Struct info := typ.info as table.Struct
// g.definitions.writeln('typedef struct {') // g.definitions.writeln('typedef struct {')
g.definitions.writeln('struct $name {') if info.is_union {
g.definitions.writeln('union $name {')
} else {
g.definitions.writeln('struct $name {')
}
if info.fields.len > 0 { if info.fields.len > 0 {
for field in info.fields { for field in info.fields {
type_name := g.typ(field.typ) type_name := g.typ(field.typ)
@ -2132,7 +2141,7 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
g.definitions.writeln('EMPTY_STRUCT_DECLARATION;') g.definitions.writeln('EMPTY_STRUCT_DECLARATION;')
} }
// g.definitions.writeln('} $name;\n') // g.definitions.writeln('} $name;\n')
// //
g.definitions.writeln('};\n') g.definitions.writeln('};\n')
} }
table.Alias { table.Alias {

View File

@ -661,8 +661,8 @@ pub fn (p mut Parser) name_expr() ast.Expr {
x := p.call_expr(is_c, mod) // TODO `node,typ :=` should work x := p.call_expr(is_c, mod) // TODO `node,typ :=` should work
node = x node = x
} }
} else if p.peek_tok.kind == .lcbr && !p.inside_match_case && (is_c || p.tok.lit[0].is_capital() || } else if p.peek_tok.kind == .lcbr && !p.inside_match_case && (is_c || p.tok.lit[0].is_capital() ||
(p.builtin_mod && p.tok.lit in table.builtin_type_names)) && (p.tok.lit.len in [1, 2, 3] || (p.builtin_mod && p.tok.lit in table.builtin_type_names)) && (p.tok.lit.len in [1, 2, 3] ||
!p.tok.lit[p.tok.lit.len - 1].is_capital() || p.table.known_type(p.tok.lit)) { !p.tok.lit[p.tok.lit.len - 1].is_capital() || p.table.known_type(p.tok.lit)) {
// short_syntax: false // short_syntax: false
return p.struct_init(false) return p.struct_init(false)
@ -1447,6 +1447,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
if is_pub { if is_pub {
p.next() p.next()
} }
is_union := p.tok.kind == .key_union
if p.tok.kind == .key_struct { if p.tok.kind == .key_struct {
p.check(.key_struct) p.check(.key_struct)
} else { } else {
@ -1535,6 +1536,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
info: table.Struct{ info: table.Struct{
fields: fields fields: fields
is_typedef: is_typedef is_typedef: is_typedef
is_union: is_union
} }
} }
mut ret := 0 mut ret := 0
@ -1558,6 +1560,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
pub_pos: pub_pos pub_pos: pub_pos
pub_mut_pos: pub_mut_pos pub_mut_pos: pub_mut_pos
is_c: is_c is_c: is_c
is_union: is_union
} }
} }

View File

@ -540,6 +540,7 @@ pub struct Struct {
pub mut: pub mut:
fields []Field fields []Field
is_typedef bool // C. [typedef] is_typedef bool // C. [typedef]
is_union bool
} }
pub struct Enum { pub struct Enum {