gen: cgen sum cast in struct init

pull/4072/head
Joe Conigliaro 2020-03-19 19:40:21 +11:00
parent 6e5b58413a
commit a456c21249
3 changed files with 18 additions and 13 deletions

View File

@ -112,10 +112,13 @@ pub:
pub struct StructInit {
pub:
pos token.Position
typ table.Type
fields []string
exprs []Expr
pos token.Position
typ table.Type
fields []string
exprs []Expr
mut:
expr_types []table.Type
expected_types []table.Type
}
// import statement

View File

@ -71,7 +71,7 @@ pub fn (c mut Checker) check_files(ast_files []ast.File) {
}
}
pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type {
pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
// typ := c.table.find_type(struct_init.typ.typ.name) or {
// c.error('unknown struct: $struct_init.typ.typ.name', struct_init.pos)
// panic('')
@ -117,6 +117,8 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
if !c.table.check(expr_type, field.typ) {
c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$field.name`', struct_init.pos)
}
struct_init.expr_types << expr_type
struct_init.expected_types << field.typ
}
}
else {}
@ -726,7 +728,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
return table.string_type
}
ast.StructInit {
return c.check_struct_init(it)
return c.struct_init(mut it)
}
ast.Type {
return it.typ

View File

@ -345,7 +345,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
}
// use instead of expr() when you need to cast to sum type (can add other casts also)
fn (g mut Gen) expr_with_cast(got_type table.Type, exp_type table.Type, expr ast.Expr) {
fn (g mut Gen) expr_with_cast(expr ast.Expr, got_type table.Type, exp_type table.Type) {
// cast to sum type
if exp_type != table.void_type && exp_type != 0 && got_type != 0 {
exp_sym := g.table.get_type_symbol(exp_type)
@ -432,7 +432,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
if !is_fixed_array_init {
g.write(' = ')
if !is_decl {
g.expr_with_cast(assign_stmt.left_types[i], ident_var_info.typ, val)
g.expr_with_cast(val, assign_stmt.left_types[i], ident_var_info.typ)
}
else {
g.expr(val)
@ -603,7 +603,7 @@ fn (g mut Gen) expr(node ast.Expr) {
g.write(', ')
}
g.is_assign_expr = false
g.expr_with_cast(it.right_type, it.left_type, it.val)
g.expr_with_cast(it.val, it.right_type, it.left_type)
if g.is_array_set {
g.write(' })')
g.is_array_set = false
@ -854,7 +854,7 @@ fn (g mut Gen) expr(node ast.Expr) {
}
for i, field in it.fields {
g.write('\t.$field = ')
g.expr(it.exprs[i])
g.expr_with_cast(it.exprs[i], it.expr_types[i], it.expected_types[i])
g.writeln(', ')
}
if it.fields.len == 0 {
@ -964,7 +964,7 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
if right_sym.kind == .array {
// push an array => PUSH_MANY
g.write('_PUSH_MANY(&')
g.expr_with_cast(node.right_type, node.left_type, node.left)
g.expr_with_cast(node.left, node.right_type, node.left_type)
g.write(', (')
g.expr(node.right)
styp := g.typ(node.left_type)
@ -976,7 +976,7 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) {
elem_type_str := g.typ(info.elem_type)
// g.write('array_push(&')
g.write('_PUSH(&')
g.expr_with_cast(node.right_type, info.elem_type, node.left)
g.expr_with_cast(node.left, node.right_type, info.elem_type)
g.write(', (')
g.expr(node.right)
g.write('), $tmp, $elem_type_str)')
@ -1328,7 +1328,7 @@ fn (g mut Gen) return_statement(it ast.Return) {
// Automatic Dereference
g.write('*')
}
g.expr_with_cast(it.types[0], g.fn_decl.return_type, it.exprs[0])
g.expr_with_cast(it.exprs[0], it.types[0], g.fn_decl.return_type)
}
g.writeln(';')
}