cgen: fix [] => string casts and for in

pull/3994/head
Alexander Medvednikov 2020-03-11 19:00:51 +01:00
parent 4470252913
commit aada19f574
5 changed files with 34 additions and 29 deletions

View File

@ -128,7 +128,6 @@ pub:
pub struct Arg { pub struct Arg {
pub: pub:
name string name string
is_mut bool is_mut bool
typ table.Type typ table.Type
@ -463,9 +462,9 @@ pub:
pub struct FnTypeDecl { pub struct FnTypeDecl {
pub: pub:
name string name string
is_pub bool is_pub bool
typ table.Type typ table.Type
} }
pub struct DeferStmt { pub struct DeferStmt {
@ -535,10 +534,12 @@ pub:
pub struct CastExpr { pub struct CastExpr {
pub: pub:
typ table.Type expr Expr // `buf`
expr Expr // `buf` arg Expr // `n` in `string(buf, n)`
arg Expr // `n` in `string(buf, n)` typ table.Type // `string`
has_arg bool mut:
expr_type table.Type // `byteptr`
has_arg bool
} }
pub struct AssertStmt { pub struct AssertStmt {

View File

@ -290,17 +290,17 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
return info.elem_type return info.elem_type
} }
if method := c.table.type_find_method(typ_sym, name) { if method := c.table.type_find_method(typ_sym, name) {
if method_call_expr.args.len < method.args.len-1 { if method_call_expr.args.len < method.args.len - 1 {
c.error('too few arguments in call to `${typ_sym.name}.$name`', method_call_expr.pos) c.error('too few arguments in call to `${typ_sym.name}.$name`', method_call_expr.pos)
} }
else if !method.is_variadic && method_call_expr.args.len > method.args.len+1 { else if !method.is_variadic && method_call_expr.args.len > method.args.len + 1 {
c.error('too many arguments in call to `${typ_sym.name}.$name` ($method_call_expr.args.len instead of $method.args.len)', method_call_expr.pos) c.error('too many arguments in call to `${typ_sym.name}.$name` ($method_call_expr.args.len instead of $method.args.len)', method_call_expr.pos)
} }
// if name == 'clone' { // if name == 'clone' {
// println('CLONE nr args=$method.args.len') // println('CLONE nr args=$method.args.len')
// } // }
for i, arg_expr in method_call_expr.args { for i, arg_expr in method_call_expr.args {
c.expected_type = method.args[i+1].typ c.expected_type = method.args[i + 1].typ
c.expr(arg_expr) c.expr(arg_expr)
} }
method_call_expr.receiver_type = method.args[0].typ method_call_expr.receiver_type = method.args[0].typ
@ -536,7 +536,10 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.stmt(stmt) c.stmt(stmt)
} }
} }
// ast.ForInStmt {} ast.ForInStmt {
c.expr(it.cond)
c.expr(it.high)
}
// ast.GlobalDecl {} // ast.GlobalDecl {}
// ast.HashStmt {} // ast.HashStmt {}
ast.Import {} ast.Import {}
@ -584,7 +587,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
return table.bool_type return table.bool_type
} }
ast.CastExpr { ast.CastExpr {
c.expr(it.expr) it.expr_type = c.expr(it.expr)
if it.has_arg { if it.has_arg {
c.expr(it.arg) c.expr(it.arg)
} }
@ -739,7 +742,7 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
// Function object (not a call), e.g. `onclick(my_click)` // Function object (not a call), e.g. `onclick(my_click)`
if func := c.table.find_fn(name) { if func := c.table.find_fn(name) {
fn_type := c.table.find_or_register_fn_type(func) fn_type := c.table.find_or_register_fn_type(func)
ident.name = name ident.name = name
ident.kind = .function ident.kind = .function
ident.info = ast.IdentFn{ ident.info = ast.IdentFn{
typ: fn_type typ: fn_type

View File

@ -494,7 +494,7 @@ fn (g mut Gen) expr(node ast.Expr) {
g.out.go_back(1) g.out.go_back(1)
} }
if it.typ == table.string_type_idx { if it.typ == table.string_type_idx {
// tos(str, len), tos2(str) // `tos(str, len)`, `tos2(str)`
if it.has_arg { if it.has_arg {
g.write('tos(') g.write('tos(')
} }
@ -502,8 +502,14 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write('tos2(') g.write('tos2(')
} }
g.expr(it.expr) g.expr(it.expr)
sym := g.table.get_type_symbol(it.expr_type)
if sym.kind == .array {
// if we are casting an array, we need to add `.data`
g.write('.data')
}
if it.has_arg { if it.has_arg {
g.write(',') // len argument
g.write(', ')
g.expr(it.arg) g.expr(it.arg)
} }
g.write(')') g.write(')')

View File

@ -7,7 +7,7 @@ import (
strings strings
) )
pub type TypeInfo = Array | ArrayFixed | Map | Struct | pub type TypeInfo = Array | ArrayFixed | Map | Struct |
MultiReturn | Alias | Enum | SumType | Fn MultiReturn | Alias | Enum | SumType | Fn
pub struct TypeSymbol { pub struct TypeSymbol {
@ -355,8 +355,7 @@ pub fn (k Kind) str() string {
'enum' 'enum'
} }
else { else {
'unknown' 'unknown'}
}
} }
return k_str return k_str
} }
@ -434,7 +433,6 @@ pub fn (table &Table) type_to_str(t Type) string {
res += ')' res += ')'
return res return res
} }
mut res := sym.name mut res := sym.name
if sym.kind == .array { if sym.kind == .array {
res = res.replace('array_', '[]') res = res.replace('array_', '[]')

View File

@ -67,11 +67,11 @@ pub fn (f &Fn) signature() string {
// TODO: for now ignore mut/pts in sig for now // TODO: for now ignore mut/pts in sig for now
typ := type_set_nr_muls(arg.typ, 0) typ := type_set_nr_muls(arg.typ, 0)
// if arg.is_mut { // if arg.is_mut {
// sig += 'mut_' // sig += 'mut_'
// } // }
// sig += '$arg.typ' // sig += '$arg.typ'
sig += '$typ' sig += '$typ'
if i < f.args.len-1 { if i < f.args.len - 1 {
sig += '_' sig += '_'
} }
} }
@ -294,7 +294,9 @@ pub fn (t &Table) array_fixed_name(elem_type Type, size int, nr_dims int) string
pub fn (t &Table) map_name(key_type Type, value_type Type) string { pub fn (t &Table) map_name(key_type Type, value_type Type) string {
key_type_sym := t.get_type_symbol(key_type) key_type_sym := t.get_type_symbol(key_type)
value_type_sym := t.get_type_symbol(value_type) value_type_sym := t.get_type_symbol(value_type)
return 'map_${key_type_sym.name}_${value_type_sym.name}' + if type_is_ptr(value_type) { '_ptr' } else { '' } suffix := if type_is_ptr(value_type) { '_ptr' } else { '' }
return 'map_${key_type_sym.name}_${value_type_sym.name}' + suffix
// return 'map_${value_type_sym.name}' + suffix
} }
pub fn (t mut Table) find_or_register_map(key_type, value_type Type) int { pub fn (t mut Table) find_or_register_map(key_type, value_type Type) int {
@ -380,12 +382,7 @@ pub fn (t mut Table) find_or_register_multi_return(mr_typs []Type) int {
} }
pub fn (t mut Table) find_or_register_fn_type(f Fn) int { pub fn (t mut Table) find_or_register_fn_type(f Fn) int {
name := if f.name.len > 0 { name := if f.name.len > 0 { f.name } else { 'anon_$f.signature()' }
f.name
}
else {
'anon_$f.signature()'
}
return t.register_type_symbol(TypeSymbol{ return t.register_type_symbol(TypeSymbol{
kind: .function kind: .function
name: name name: name