cgen: struct str() generation; go() fixes
parent
31c4b1cda6
commit
c32ed8af51
|
@ -557,20 +557,16 @@ fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) {
|
|||
g.writeln('// assert')
|
||||
g.write('if( ')
|
||||
g.expr(a.expr)
|
||||
g.write(' )')
|
||||
s_assertion := a.expr.str().replace('"', "\'")
|
||||
mut mod_path := g.file.path
|
||||
$if windows {
|
||||
mod_path = g.file.path.replace('\\', '\\\\')
|
||||
}
|
||||
g.write(' )')
|
||||
if g.is_test {
|
||||
g.writeln('{')
|
||||
g.writeln(' g_test_oks++;')
|
||||
g.writeln(' cb_assertion_ok( _STR("${mod_path}"), ${a.pos.line_nr}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );')
|
||||
g.writeln(' cb_assertion_ok( _STR("${g.file.path}"), ${a.pos.line_nr}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );')
|
||||
// g.writeln(' println(_STR("OK ${g.file.path}:${a.pos.line_nr}: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||
g.writeln('}else{')
|
||||
g.writeln(' g_test_fails++;')
|
||||
g.writeln(' cb_assertion_failed( _STR("${mod_path}"), ${a.pos.line_nr}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );')
|
||||
g.writeln(' cb_assertion_failed( _STR("${g.file.path}"), ${a.pos.line_nr}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );')
|
||||
g.writeln(' exit(1);')
|
||||
g.writeln(' // TODO')
|
||||
g.writeln(' // Maybe print all vars in a test function if it fails?')
|
||||
|
@ -578,7 +574,7 @@ fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) {
|
|||
return
|
||||
}
|
||||
g.writeln('{}else{')
|
||||
g.writeln(' println(_STR("${mod_path}:${a.pos.line_nr}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||
g.writeln(' eprintln(_STR("${g.file.path}:${a.pos.line_nr}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||
g.writeln(' exit(1);')
|
||||
g.writeln('}')
|
||||
}
|
||||
|
@ -2027,7 +2023,6 @@ fn verror(s string) {
|
|||
|
||||
fn (g mut Gen) write_init_function() {
|
||||
g.writeln('void _vinit() {')
|
||||
g.writeln('init(); // builtin.init')
|
||||
g.writeln(g.inits.str())
|
||||
g.writeln('}')
|
||||
if g.autofree {
|
||||
|
@ -2432,7 +2427,7 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
|
|||
styp = styp.replace('*', '')
|
||||
}
|
||||
g.str_types << typ
|
||||
g.definitions.writeln('string ${styp}_str($styp x) { return tos3("TODO_str"); }')
|
||||
g.gen_str_for_type(sym, styp)
|
||||
}
|
||||
if g.autofree && !table.type_is_optional(typ) {
|
||||
// Create a temporary variable so that the value can be freed
|
||||
|
@ -2808,7 +2803,7 @@ fn (g mut Gen) go_stmt(node ast.GoStmt) {
|
|||
// x := node.call_expr as ast.CallEpxr // TODO
|
||||
match node.call_expr {
|
||||
ast.CallExpr{
|
||||
mut name := it.name
|
||||
mut name := it.name.replace('.', '__')
|
||||
if it.is_method {
|
||||
receiver_sym := g.table.get_type_symbol(it.receiver_type)
|
||||
name = receiver_sym.name + '_' + name
|
||||
|
@ -2836,12 +2831,12 @@ fn (g mut Gen) go_stmt(node ast.GoStmt) {
|
|||
}
|
||||
g.definitions.writeln('\ntypedef struct $wrapper_struct_name {')
|
||||
if it.is_method {
|
||||
sym := g.table.get_type_symbol(it.receiver_type)
|
||||
g.definitions.writeln('\t$sym.name arg0;')
|
||||
styp := g.typ(it.receiver_type)
|
||||
g.definitions.writeln('\t$styp arg0;')
|
||||
}
|
||||
for i, arg in it.args {
|
||||
sym := g.table.get_type_symbol(arg.typ)
|
||||
g.definitions.writeln('\t$sym.name arg${i+1};')
|
||||
styp := g.typ(arg.typ)
|
||||
g.definitions.writeln('\t$styp arg${i+1};')
|
||||
}
|
||||
g.definitions.writeln('} $wrapper_struct_name;')
|
||||
g.definitions.writeln('void* ${wrapper_fn_name}($wrapper_struct_name *arg) {')
|
||||
|
@ -2866,3 +2861,41 @@ fn (g mut Gen) go_stmt(node ast.GoStmt) {
|
|||
}
|
||||
}
|
||||
|
||||
// already generated styp, reuse it
|
||||
fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
||||
s := styp.replace('.', '__')
|
||||
match sym.info {
|
||||
table.Struct{}
|
||||
else {
|
||||
println('str() not a struct $sym.name')
|
||||
return
|
||||
}
|
||||
}
|
||||
info := sym.info as table.Struct
|
||||
g.definitions.write('string ${s}_str($styp a) { return _STR("$styp {\\n')
|
||||
for field in info.fields {
|
||||
fmt := type_to_fmt(field.typ)
|
||||
g.definitions.write('\t$field.name: $fmt\\n')
|
||||
|
||||
}
|
||||
g.definitions.write('\\n}", ')
|
||||
for i, field in info.fields {
|
||||
g.definitions.write('a.' + field.name)
|
||||
if field.typ == table.string_type {
|
||||
g.definitions.write('.len, a.${field.name}.str')
|
||||
}
|
||||
if i < info.fields.len - 1 {
|
||||
g.definitions.write(', ')
|
||||
}
|
||||
}
|
||||
g.definitions.writeln('); }')
|
||||
}
|
||||
|
||||
fn type_to_fmt(typ table.Type) string {
|
||||
n := int(typ)
|
||||
if n == table.string_type {
|
||||
return '%.*s'
|
||||
}
|
||||
return '%d'
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ mut:
|
|||
ast_imports []ast.Import
|
||||
is_amp bool
|
||||
returns bool
|
||||
inside_match_case bool // to separate `match_expr { }` from `Struct{}`
|
||||
}
|
||||
|
||||
// for tests
|
||||
|
@ -668,8 +669,9 @@ pub fn (p mut Parser) name_expr() ast.Expr {
|
|||
//
|
||||
(p.builtin_mod && p.tok.lit in table.builtin_type_names)) &&
|
||||
//
|
||||
(p.tok.lit.len == 1 || !p.tok.lit[p.tok.lit.len - 1].is_capital())
|
||||
(p.tok.lit.len == 1 || !p.tok.lit[p.tok.lit.len - 1].is_capital()) &&
|
||||
//
|
||||
!p.inside_match_case
|
||||
{
|
||||
// || p.table.known_type(p.tok.lit)) {
|
||||
return p.struct_init(false) // short_syntax: false
|
||||
|
@ -1779,7 +1781,8 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
|||
p.next()
|
||||
}
|
||||
// Sum type match
|
||||
else if p.tok.kind == .name && (p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() || p.peek_tok.kind == .dot) {
|
||||
else if p.tok.kind == .name &&
|
||||
(p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() || p.peek_tok.kind == .dot) {
|
||||
// if sym.kind == .sum_type {
|
||||
// p.warn('is sum')
|
||||
// TODO `exprs << ast.Type{...}`
|
||||
|
@ -1804,7 +1807,9 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
|||
else {
|
||||
// Expression match
|
||||
for {
|
||||
p.inside_match_case = true
|
||||
expr := p.expr(0)
|
||||
p.inside_match_case = false
|
||||
exprs << expr
|
||||
if p.tok.kind != .comma {
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue