mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: cast to sum type
This commit is contained in:
parent
66adf7a6b9
commit
c947e6ebe6
@ -189,6 +189,8 @@ pub struct Return {
|
||||
pub:
|
||||
pos token.Position
|
||||
exprs []Expr
|
||||
mut:
|
||||
types []table.Type
|
||||
}
|
||||
|
||||
/*
|
||||
@ -416,10 +418,13 @@ pub:
|
||||
|
||||
pub struct AssignStmt {
|
||||
pub:
|
||||
left []Ident
|
||||
right []Expr
|
||||
op token.Kind
|
||||
pos token.Position
|
||||
left []Ident
|
||||
right []Expr
|
||||
op token.Kind
|
||||
pos token.Position
|
||||
mut:
|
||||
left_types []table.Type
|
||||
right_types []table.Type
|
||||
}
|
||||
|
||||
pub struct AsCast {
|
||||
@ -490,12 +495,13 @@ pub:
|
||||
|
||||
pub struct AssignExpr {
|
||||
pub:
|
||||
op token.Kind
|
||||
pos token.Position
|
||||
left Expr
|
||||
val Expr
|
||||
op token.Kind
|
||||
pos token.Position
|
||||
left Expr
|
||||
val Expr
|
||||
mut:
|
||||
left_type table.Type
|
||||
left_type table.Type
|
||||
right_type table.Type
|
||||
}
|
||||
|
||||
pub struct GotoLabel {
|
||||
|
@ -169,6 +169,7 @@ fn (c mut Checker) assign_expr(assign_expr mut ast.AssignExpr) {
|
||||
// t := c.table.get_type_symbol(left_type)
|
||||
// println('setting exp type to $c.expected_type $t.name')
|
||||
right_type := c.expr(assign_expr.val)
|
||||
assign_expr.right_type = right_type
|
||||
if !c.table.check(right_type, left_type) {
|
||||
left_type_sym := c.table.get_type_symbol(left_type)
|
||||
right_type_sym := c.table.get_type_symbol(right_type)
|
||||
@ -352,7 +353,7 @@ pub fn (c mut Checker) selector_expr(selector_expr mut ast.SelectorExpr) table.T
|
||||
}
|
||||
|
||||
// TODO: non deferred
|
||||
pub fn (c mut Checker) return_stmt(return_stmt ast.Return) {
|
||||
pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) {
|
||||
c.expected_type = c.fn_return_type
|
||||
if return_stmt.exprs.len == 0 {
|
||||
return
|
||||
@ -370,6 +371,7 @@ pub fn (c mut Checker) return_stmt(return_stmt ast.Return) {
|
||||
typ := c.expr(expr)
|
||||
got_types << typ
|
||||
}
|
||||
return_stmt.types = got_types
|
||||
// allow `none` & `error (Option)` return types for function that returns optional
|
||||
if exp_is_optional && table.type_idx(got_types[0]) in [table.none_type_idx, c.table.type_idxs['Option']] {
|
||||
return
|
||||
@ -406,12 +408,14 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) {
|
||||
assign_stmt.left[i] = ident
|
||||
if assign_stmt.op == .assign {
|
||||
var_type := c.expr(ident)
|
||||
assign_stmt.left_types << var_type
|
||||
if !c.table.check(val_type, var_type) {
|
||||
val_type_sym := c.table.get_type_symbol(val_type)
|
||||
var_type_sym := c.table.get_type_symbol(var_type)
|
||||
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`', assign_stmt.pos)
|
||||
}
|
||||
}
|
||||
assign_stmt.right_types << val_type
|
||||
scope.override_var(ast.Var{
|
||||
name: ident.name
|
||||
typ: mr_info.types[i]
|
||||
@ -426,16 +430,18 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) {
|
||||
mut scope := c.file.scope.innermost(assign_stmt.pos.pos)
|
||||
for i, _ in assign_stmt.left {
|
||||
mut ident := assign_stmt.left[i]
|
||||
mut ident_var_info := ident.var_info()
|
||||
val_type := c.expr(assign_stmt.right[i])
|
||||
if assign_stmt.op == .assign {
|
||||
var_type := c.expr(ident)
|
||||
assign_stmt.left_types << var_type
|
||||
if !c.table.check(val_type, var_type) {
|
||||
val_type_sym := c.table.get_type_symbol(val_type)
|
||||
var_type_sym := c.table.get_type_symbol(var_type)
|
||||
c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`', assign_stmt.pos)
|
||||
}
|
||||
}
|
||||
mut ident_var_info := ident.var_info()
|
||||
assign_stmt.right_types << val_type
|
||||
ident_var_info.typ = val_type
|
||||
ident.info = ident_var_info
|
||||
assign_stmt.left[i] = ident
|
||||
@ -556,7 +562,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||
// ast.HashStmt {}
|
||||
ast.Import {}
|
||||
ast.Return {
|
||||
c.return_stmt(it)
|
||||
c.return_stmt(mut it)
|
||||
}
|
||||
// ast.StructDecl {}
|
||||
ast.UnsafeStmt {
|
||||
|
@ -326,6 +326,29 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (g &Gen) is_sum_cast(got_type table.Type, exp_type table.Type) bool {
|
||||
if exp_type != table.void_type && exp_type != 0 && got_type != 0{
|
||||
exp_sym := g.table.get_type_symbol(exp_type)
|
||||
// got_sym := g.table.get_type_symbol(got_type)
|
||||
if exp_sym.kind == .sum_type {
|
||||
sum_info := exp_sym.info as table.SumType
|
||||
if got_type in sum_info.variants {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fn (g mut Gen) sum_cast(got_type table.Type, exp_type table.Type, expr ast.Expr) {
|
||||
got_styp := g.typ(got_type)
|
||||
exp_styp := g.typ(exp_type)
|
||||
got_idx := table.type_idx(got_type)
|
||||
g.write('/* SUM TYPE CAST */ ($exp_styp) {.obj = memdup(&(${got_styp}[]) {')
|
||||
g.expr(expr)
|
||||
g.writeln('}, sizeof($got_styp)), .typ = $got_idx};')
|
||||
}
|
||||
|
||||
fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
// multi return
|
||||
// g.write('/*assign*/')
|
||||
@ -394,13 +417,20 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
}
|
||||
else {}
|
||||
}
|
||||
mut is_sum_cast := false
|
||||
if assign_stmt.op == .decl_assign {
|
||||
g.write('$styp ')
|
||||
} else {
|
||||
is_sum_cast = g.is_sum_cast(assign_stmt.right_types[i], assign_stmt.left_types[i])
|
||||
}
|
||||
g.expr(ident)
|
||||
if !is_fixed_array_init {
|
||||
g.write(' = ')
|
||||
g.expr(val)
|
||||
if is_sum_cast {
|
||||
g.sum_cast(ident_var_info.typ, assign_stmt.left_types[i], val)
|
||||
} else {
|
||||
g.expr(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
g.writeln(';')
|
||||
@ -549,7 +579,11 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||
g.write(', ')
|
||||
}
|
||||
g.is_assign_expr = false
|
||||
g.expr(it.val)
|
||||
if g.is_sum_cast(it.left_type, it.right_type) {
|
||||
g.sum_cast(it.left_type, it.right_type, it.val)
|
||||
} else {
|
||||
g.expr(it.val)
|
||||
}
|
||||
if g.is_array_set {
|
||||
g.write(' })')
|
||||
g.is_array_set = false
|
||||
@ -1135,6 +1169,8 @@ fn (g mut Gen) return_statement(it ast.Return) {
|
||||
g.write('return')
|
||||
// multiple returns
|
||||
if it.exprs.len > 1 {
|
||||
typ_sym := g.table.get_type_symbol(g.fn_decl.return_type)
|
||||
mr_info := typ_sym.info as table.MultiReturn
|
||||
styp := g.typ(g.fn_decl.return_type)
|
||||
g.write(' ($styp){')
|
||||
for i, expr in it.exprs {
|
||||
@ -1171,7 +1207,12 @@ fn (g mut Gen) return_statement(it ast.Return) {
|
||||
}
|
||||
// g.write('/*OPTIONAL*/')
|
||||
}
|
||||
g.expr(it.exprs[0])
|
||||
if g.is_sum_cast(it.types[0], g.fn_decl.return_type) {
|
||||
g.sum_cast(it.types[0], g.fn_decl.return_type, it.exprs[0])
|
||||
}
|
||||
else {
|
||||
g.expr(it.exprs[0])
|
||||
}
|
||||
}
|
||||
g.writeln(';')
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user