cgen: enum fixes; sum type definition; const bug fix

pull/4020/head
Alexander Medvednikov 2020-03-14 05:20:12 +01:00
parent 424bd1c465
commit e8c9f609a4
4 changed files with 55 additions and 13 deletions

View File

@ -191,11 +191,16 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.writeln('// defer') g.writeln('// defer')
} }
ast.EnumDecl { ast.EnumDecl {
g.writeln('typedef enum {') g.writeln('//')
/*
name := it.name.replace('.', '__')
g.definitions.writeln('typedef enum {')
for i, val in it.vals { for i, val in it.vals {
g.writeln('\t${it.name}_$val, // $i') g.definitions.writeln('\t${name}_$val, // $i')
} }
g.writeln('} $it.name;') g.definitions.writeln('} $name;')
*/
} }
ast.ExprStmt { ast.ExprStmt {
g.expr(it.expr) g.expr(it.expr)
@ -1103,8 +1108,11 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) {
pos := g.out.len pos := g.out.len
g.expr(expr) g.expr(expr)
g.writeln('') g.writeln('')
val := string(g.out.buf[pos..]) b := g.out.buf[pos..g.out.buf.len].clone()
val := string(b)
// val += '\0'
// g.out.go_back(val.len) // g.out.go_back(val.len)
// println('pos=$pos buf.len=$g.out.buf.len len=$g.out.len val.len=$val.len val="$val"\n')
g.definitions.write(val) g.definitions.write(val)
} }
else { else {
@ -1159,6 +1167,18 @@ fn (g mut Gen) write_builtin_types() {
builtin_types << g.table.types[g.table.type_idxs[builtin_name]] builtin_types << g.table.types[g.table.type_idxs[builtin_name]]
} }
g.write_types(builtin_types) g.write_types(builtin_types)
// TODO remove this
g.definitions.writeln('
typedef struct {
int len;
string args[100];
} variadic_string;
typedef struct {
int len;
int args[100];
} variadic_int;
')
} }
// C struct definitions, ordered // C struct definitions, ordered
@ -1186,10 +1206,10 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
continue continue
} }
// sym := g.table.get_type_symbol(typ) // sym := g.table.get_type_symbol(typ)
name := typ.name.replace('.', '__')
match typ.info { match typ.info {
table.Struct { table.Struct {
info := typ.info as table.Struct info := typ.info as table.Struct
name := typ.name.replace('.', '__')
// g.definitions.writeln('typedef struct {') // g.definitions.writeln('typedef struct {')
g.definitions.writeln('struct $name {') g.definitions.writeln('struct $name {')
for field in info.fields { for field in info.fields {
@ -1200,6 +1220,21 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
// //
g.definitions.writeln('};\n') g.definitions.writeln('};\n')
} }
table.Enum {
g.definitions.writeln('typedef enum {')
for i, val in it.vals {
g.definitions.writeln('\t${name}_$val, // $i')
}
g.definitions.writeln('} $name;\n')
}
table.SumType {
g.definitions.writeln('// Sum type')
g.definitions.writeln('
typedef struct {
void* obj;
int typ;
} $name;')
}
else {} else {}
} }
} }

View File

@ -38,12 +38,18 @@ fn compare_texts(a, b, path string) bool {
lines_b_ := b.trim_space().split_into_lines() lines_b_ := b.trim_space().split_into_lines()
lines_a := lines_a_.filter(it != '') lines_a := lines_a_.filter(it != '')
lines_b := lines_b_.filter(it != '') lines_b := lines_b_.filter(it != '')
/*
if lines_a.len != lines_b.len { if lines_a.len != lines_b.len {
println(term.red('different len')) println(term.red('different len'))
println('${path}: got\n$a') println('${path}: got\n$a')
return false return false
} }
*/
for i, line_a in lines_a { for i, line_a in lines_a {
if i >= lines_b.len {
return false
}
line_b := lines_b[i] line_b := lines_b[i]
if line_a.trim_space() != line_b.trim_space() { if line_a.trim_space() != line_b.trim_space() {
println('${path}: got\n$a') println('${path}: got\n$a')

View File

@ -1,3 +1,9 @@
typedef enum {
Color_red, // 0
Color_green, // 1
Color_blue, // 2
} Color;
struct Two { struct Two {
}; };
@ -36,12 +42,7 @@ int localmod__get_int_10();
//3 //3
//
typedef enum {
Color_red, // 0
Color_green, // 1
Color_blue, // 2
} Color;
int main() { int main() {
int a = 10; int a = 10;

View File

@ -1662,7 +1662,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
p.next() p.next()
} }
p.check(.key_enum) p.check(.key_enum)
name := p.check_name() name := p.prepend_mod(p.check_name())
p.check(.lcbr) p.check(.lcbr)
mut vals := []string mut vals := []string
for p.tok.kind != .eof && p.tok.kind != .rcbr { for p.tok.kind != .eof && p.tok.kind != .rcbr {
@ -1677,7 +1677,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
p.check(.rcbr) p.check(.rcbr)
p.table.register_type_symbol(table.TypeSymbol{ p.table.register_type_symbol(table.TypeSymbol{
kind: .enum_ kind: .enum_
name: p.prepend_mod(name) name: name
info: table.Enum{ info: table.Enum{
vals: vals vals: vals
} }