mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: struct str() generation; go() fixes
This commit is contained in:
parent
31c4b1cda6
commit
c32ed8af51
@ -557,20 +557,16 @@ fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) {
|
|||||||
g.writeln('// assert')
|
g.writeln('// assert')
|
||||||
g.write('if( ')
|
g.write('if( ')
|
||||||
g.expr(a.expr)
|
g.expr(a.expr)
|
||||||
g.write(' )')
|
|
||||||
s_assertion := a.expr.str().replace('"', "\'")
|
s_assertion := a.expr.str().replace('"', "\'")
|
||||||
mut mod_path := g.file.path
|
g.write(' )')
|
||||||
$if windows {
|
|
||||||
mod_path = g.file.path.replace('\\', '\\\\')
|
|
||||||
}
|
|
||||||
if g.is_test {
|
if g.is_test {
|
||||||
g.writeln('{')
|
g.writeln('{')
|
||||||
g.writeln(' g_test_oks++;')
|
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(' println(_STR("OK ${g.file.path}:${a.pos.line_nr}: fn ${g.fn_decl.name}(): assert $s_assertion"));')
|
||||||
g.writeln('}else{')
|
g.writeln('}else{')
|
||||||
g.writeln(' g_test_fails++;')
|
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(' exit(1);')
|
||||||
g.writeln(' // TODO')
|
g.writeln(' // TODO')
|
||||||
g.writeln(' // Maybe print all vars in a test function if it fails?')
|
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
|
return
|
||||||
}
|
}
|
||||||
g.writeln('{}else{')
|
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(' exit(1);')
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
@ -2027,7 +2023,6 @@ fn verror(s string) {
|
|||||||
|
|
||||||
fn (g mut Gen) write_init_function() {
|
fn (g mut Gen) write_init_function() {
|
||||||
g.writeln('void _vinit() {')
|
g.writeln('void _vinit() {')
|
||||||
g.writeln('init(); // builtin.init')
|
|
||||||
g.writeln(g.inits.str())
|
g.writeln(g.inits.str())
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
if g.autofree {
|
if g.autofree {
|
||||||
@ -2432,7 +2427,7 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
|
|||||||
styp = styp.replace('*', '')
|
styp = styp.replace('*', '')
|
||||||
}
|
}
|
||||||
g.str_types << typ
|
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) {
|
if g.autofree && !table.type_is_optional(typ) {
|
||||||
// Create a temporary variable so that the value can be freed
|
// 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
|
// x := node.call_expr as ast.CallEpxr // TODO
|
||||||
match node.call_expr {
|
match node.call_expr {
|
||||||
ast.CallExpr{
|
ast.CallExpr{
|
||||||
mut name := it.name
|
mut name := it.name.replace('.', '__')
|
||||||
if it.is_method {
|
if it.is_method {
|
||||||
receiver_sym := g.table.get_type_symbol(it.receiver_type)
|
receiver_sym := g.table.get_type_symbol(it.receiver_type)
|
||||||
name = receiver_sym.name + '_' + name
|
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 {')
|
g.definitions.writeln('\ntypedef struct $wrapper_struct_name {')
|
||||||
if it.is_method {
|
if it.is_method {
|
||||||
sym := g.table.get_type_symbol(it.receiver_type)
|
styp := g.typ(it.receiver_type)
|
||||||
g.definitions.writeln('\t$sym.name arg0;')
|
g.definitions.writeln('\t$styp arg0;')
|
||||||
}
|
}
|
||||||
for i, arg in it.args {
|
for i, arg in it.args {
|
||||||
sym := g.table.get_type_symbol(arg.typ)
|
styp := g.typ(arg.typ)
|
||||||
g.definitions.writeln('\t$sym.name arg${i+1};')
|
g.definitions.writeln('\t$styp arg${i+1};')
|
||||||
}
|
}
|
||||||
g.definitions.writeln('} $wrapper_struct_name;')
|
g.definitions.writeln('} $wrapper_struct_name;')
|
||||||
g.definitions.writeln('void* ${wrapper_fn_name}($wrapper_struct_name *arg) {')
|
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
|
ast_imports []ast.Import
|
||||||
is_amp bool
|
is_amp bool
|
||||||
returns bool
|
returns bool
|
||||||
|
inside_match_case bool // to separate `match_expr { }` from `Struct{}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// for tests
|
// 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.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)) {
|
// || p.table.known_type(p.tok.lit)) {
|
||||||
return p.struct_init(false) // short_syntax: false
|
return p.struct_init(false) // short_syntax: false
|
||||||
@ -1779,7 +1781,8 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
|||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
// Sum type match
|
// 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 {
|
// if sym.kind == .sum_type {
|
||||||
// p.warn('is sum')
|
// p.warn('is sum')
|
||||||
// TODO `exprs << ast.Type{...}`
|
// TODO `exprs << ast.Type{...}`
|
||||||
@ -1804,7 +1807,9 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
|||||||
else {
|
else {
|
||||||
// Expression match
|
// Expression match
|
||||||
for {
|
for {
|
||||||
|
p.inside_match_case = true
|
||||||
expr := p.expr(0)
|
expr := p.expr(0)
|
||||||
|
p.inside_match_case = false
|
||||||
exprs << expr
|
exprs << expr
|
||||||
if p.tok.kind != .comma {
|
if p.tok.kind != .comma {
|
||||||
break
|
break
|
||||||
|
Loading…
Reference in New Issue
Block a user