sum types: allow modification in `match`

pull/3635/head
Alexander Medvednikov 2020-02-03 09:11:10 +01:00
parent d918903252
commit 34e9eb32bb
5 changed files with 47 additions and 21 deletions

View File

@ -447,6 +447,7 @@ pub fn (a []char) index(v char) int {
return -1
}
/*
// []int.reduce executes a given reducer function on each element of the array,
// resulting in a single output value.
pub fn (a []int) reduce(iter fn(accum, curr int)int, accum_start int) int {
@ -457,6 +458,7 @@ pub fn (a []int) reduce(iter fn(accum, curr int)int, accum_start int) int {
}
return _accum
}
*/
// array_eq<T> checks if two arrays contain all the same elements in the same order.
// []int == []int (also for: i64, f32, f64, byte, string)

View File

@ -139,7 +139,9 @@ fn (p mut Parser) match_statement(is_expr bool) string {
// println('got child $sum_child_type')
p.register_var(Var{
name: 'it'
typ: sum_child_type
typ: sum_child_type+'*'
is_mut: true
ptr: true
})
}
else {
@ -189,7 +191,8 @@ fn (p mut Parser) match_statement(is_expr bool) string {
p.check(.lcbr)
p.genln('{ ')
if is_sum_type {
p.genln(' $sum_child_type it = *($sum_child_type*)$tmp_var .obj ;')
//p.genln(' $sum_child_type it = *($sum_child_type*)$tmp_var .obj ;')
p.genln(' $sum_child_type* it = ($sum_child_type*)${tmp_var}.obj ;')
}
p.statements()
all_cases_return = all_cases_return && p.returns

View File

@ -197,7 +197,12 @@ fn (c &Checker) stmt(node ast.Stmt) {
}
ast.VarDecl {
typ := c.expr(it.expr)
// println('var decl $typ.name it.typ=$it.typ.name $it.pos.line_nr')
// println('checker: var decl $typ.name it.typ=$it.typ.name $it.pos.line_nr')
/*
if typ.kind != .void {
it.typ = typ
}
*/
// if it.typ.kind == .unresolved {
// it.ti = typ
// println('unresolved var')
@ -284,22 +289,7 @@ pub fn (c &Checker) expr(node ast.Expr) table.Type {
return c.selector_expr(it)
}
ast.IndexExpr {
mut typ := c.expr(it.left)
if typ.name.starts_with('array_') {
elm_typ := typ.name[6..]
// TODO `typ = ... or ...`
x := c.table.find_type(elm_typ) or {
c.error(elm_typ, it.pos)
exit(0)
}
typ = x
}
else {
typ = table.int_type
}
return typ
// c.expr(it.index)
//return it.typ
return c.index_expr(it)
}
ast.IfExpr {
typ := c.expr(it.cond)
@ -320,6 +310,25 @@ pub fn (c &Checker) expr(node ast.Expr) table.Type {
return table.void_type
}
pub fn (c &Checker) index_expr(node ast.IndexExpr) table.Type {
mut typ := c.expr(node.left)
if typ.name.starts_with('array_') {
elm_typ := typ.name[6..]
// TODO `typ = ... or ...`
x := c.table.find_type(elm_typ) or {
c.error(elm_typ, node.pos)
exit(0)
}
typ = x
}
else {
typ = table.int_type
}
return typ
// c.expr(it.index)
// return it.typ
}
pub fn (c &Checker) error(s string, pos token.Position) {
print_backtrace()
final_msg_line := '$c.file_name:$pos.line_nr: error: $s'

View File

@ -11,6 +11,17 @@ struct User {
age int
}
/*
struct One {
two Two
}
struct Two {
}
*/
fn main() {
a := 10
//bb := 2 + 'hi'

View File

@ -904,6 +904,7 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
ti: ti
}
// println('struct field $ti.name $field_name')
}
p.check(.rcbr)
p.table.register_type(table.Type{