cgen: filter + expected_type fix
parent
0fbb056ac7
commit
216c7a16d8
|
@ -526,6 +526,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
match mut node {
|
match mut node {
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
c.assign_stmt(mut it)
|
c.assign_stmt(mut it)
|
||||||
|
c.expected_type = table.void_type
|
||||||
}
|
}
|
||||||
// ast.Attr {}
|
// ast.Attr {}
|
||||||
// ast.CompIf {}
|
// ast.CompIf {}
|
||||||
|
@ -544,6 +545,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.ExprStmt {
|
ast.ExprStmt {
|
||||||
c.expr(it.expr)
|
c.expr(it.expr)
|
||||||
|
c.expected_type = table.void_type
|
||||||
}
|
}
|
||||||
ast.FnDecl {
|
ast.FnDecl {
|
||||||
c.expected_type = table.void_type
|
c.expected_type = table.void_type
|
||||||
|
|
|
@ -23,6 +23,7 @@ mut:
|
||||||
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc
|
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc
|
||||||
optionals []string // to avoid duplicates TODO perf, use map
|
optionals []string // to avoid duplicates TODO perf, use map
|
||||||
inside_ternary bool // ?: comma separated statements on a single line
|
inside_ternary bool // ?: comma separated statements on a single line
|
||||||
|
stmt_start_pos int
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cgen(files []ast.File, table &table.Table) string {
|
pub fn cgen(files []ast.File, table &table.Table) string {
|
||||||
|
@ -199,6 +200,7 @@ fn (g mut Gen) stmts(stmts []ast.Stmt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) stmt(node ast.Stmt) {
|
fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
|
g.stmt_start_pos = g.out.len
|
||||||
// println('cgen.stmt()')
|
// println('cgen.stmt()')
|
||||||
// g.writeln('//// stmt start')
|
// g.writeln('//// stmt start')
|
||||||
match node {
|
match node {
|
||||||
|
@ -747,6 +749,10 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
typ_sym := g.table.get_type_symbol(it.receiver_type)
|
typ_sym := g.table.get_type_symbol(it.receiver_type)
|
||||||
// rec_sym := g.table.get_type_symbol(it.receiver_type)
|
// rec_sym := g.table.get_type_symbol(it.receiver_type)
|
||||||
mut receiver_name := typ_sym.name
|
mut receiver_name := typ_sym.name
|
||||||
|
if typ_sym.kind == .array && it.name == 'filter' {
|
||||||
|
g.gen_filter(it)
|
||||||
|
return
|
||||||
|
}
|
||||||
if typ_sym.kind == .array && it.name in
|
if typ_sym.kind == .array && it.name in
|
||||||
// TODO performance, detect `array` method differently
|
// TODO performance, detect `array` method differently
|
||||||
['repeat', 'sort_with_compare', 'free', 'push_many', 'trim',
|
['repeat', 'sort_with_compare', 'free', 'push_many', 'trim',
|
||||||
|
@ -1599,6 +1605,35 @@ fn (g &Gen) sort_structs(types []table.TypeSymbol) []table.TypeSymbol {
|
||||||
return types_sorted
|
return types_sorted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (g mut Gen) gen_filter(node ast.MethodCallExpr) {
|
||||||
|
tmp := g.new_tmp_var()
|
||||||
|
buf := g.out.buf[g.stmt_start_pos..]
|
||||||
|
s := string(buf.clone()) // the already generated part of current statement
|
||||||
|
g.out.go_back(s.len)
|
||||||
|
// println('filter s="$s"')
|
||||||
|
sym := g.table.get_type_symbol(node.return_type)
|
||||||
|
if sym.kind != .array {
|
||||||
|
verror('filter() requires an array')
|
||||||
|
}
|
||||||
|
info := sym.info as table.Array
|
||||||
|
styp := g.typ(node.return_type)
|
||||||
|
elem_type_str := g.typ(info.elem_type)
|
||||||
|
g.write('\nint ${tmp}_len = ')
|
||||||
|
g.expr(node.expr)
|
||||||
|
g.writeln('.len;')
|
||||||
|
g.writeln('$styp $tmp = new_array(0, ${tmp}_len, sizeof($elem_type_str));')
|
||||||
|
g.writeln('for (int i = 0; i < ${tmp}_len; i++) {')
|
||||||
|
g.write(' $elem_type_str it = (($elem_type_str*) ')
|
||||||
|
g.expr(node.expr)
|
||||||
|
g.writeln('.data)[i];')
|
||||||
|
g.write('if (')
|
||||||
|
g.expr(node.args[0].expr) // the first arg is the filter condition
|
||||||
|
g.writeln(') array_push(&$tmp, &it); \n }')
|
||||||
|
g.write(s)
|
||||||
|
g.write(' ')
|
||||||
|
g.write(tmp)
|
||||||
|
}
|
||||||
|
|
||||||
fn op_to_fn_name(name string) string {
|
fn op_to_fn_name(name string) string {
|
||||||
return match name {
|
return match name {
|
||||||
'+'{
|
'+'{
|
||||||
|
|
Loading…
Reference in New Issue