checker: set expected_type in several places
parent
27ce38937c
commit
a15dcbfb2d
|
@ -16,12 +16,13 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
pub struct Checker {
|
pub struct Checker {
|
||||||
table &table.Table
|
table &table.Table
|
||||||
mut:
|
mut:
|
||||||
file ast.File
|
file ast.File
|
||||||
nr_errors int
|
nr_errors int
|
||||||
errors []string
|
errors []string
|
||||||
expected_type table.Type
|
expected_type table.Type
|
||||||
|
fn_return_type table.Type // current function's return type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_checker(table &table.Table) Checker {
|
pub fn new_checker(table &table.Table) Checker {
|
||||||
|
@ -108,6 +109,7 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
|
||||||
if !found_field {
|
if !found_field {
|
||||||
c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos)
|
c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos)
|
||||||
}
|
}
|
||||||
|
c.expected_type = field.typ
|
||||||
expr_type := c.expr(expr)
|
expr_type := c.expr(expr)
|
||||||
expr_type_sym := c.table.get_type_symbol(expr_type)
|
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||||
field_type_sym := c.table.get_type_symbol(field.typ)
|
field_type_sym := c.table.get_type_symbol(field.typ)
|
||||||
|
@ -124,6 +126,7 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
|
||||||
pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type {
|
pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type {
|
||||||
// println('checker: infix expr(op $infix_expr.op.str())')
|
// println('checker: infix expr(op $infix_expr.op.str())')
|
||||||
left_type := c.expr(infix_expr.left)
|
left_type := c.expr(infix_expr.left)
|
||||||
|
c.expected_type = left_type
|
||||||
right_type := c.expr(infix_expr.right)
|
right_type := c.expr(infix_expr.right)
|
||||||
if !c.table.check(right_type, left_type) {
|
if !c.table.check(right_type, left_type) {
|
||||||
left := c.table.get_type_symbol(left_type)
|
left := c.table.get_type_symbol(left_type)
|
||||||
|
@ -279,6 +282,7 @@ pub fn (c mut Checker) selector_expr(selector_expr ast.SelectorExpr) table.Type
|
||||||
// TODO: non deferred
|
// TODO: non deferred
|
||||||
pub fn (c mut Checker) return_stmt(return_stmt ast.Return) {
|
pub fn (c mut Checker) return_stmt(return_stmt ast.Return) {
|
||||||
mut got_types := []table.Type
|
mut got_types := []table.Type
|
||||||
|
c.expected_type = c.fn_return_type
|
||||||
if return_stmt.exprs.len == 0 {
|
if return_stmt.exprs.len == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -367,6 +371,7 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
// c.expected_type = table.void_type
|
// c.expected_type = table.void_type
|
||||||
match mut node {
|
match mut node {
|
||||||
ast.FnDecl {
|
ast.FnDecl {
|
||||||
|
c.fn_return_type = it.typ
|
||||||
for stmt in it.stmts {
|
for stmt in it.stmts {
|
||||||
c.stmt(stmt)
|
c.stmt(stmt)
|
||||||
}
|
}
|
||||||
|
@ -605,6 +610,7 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
|
||||||
for i, block in node.blocks {
|
for i, block in node.blocks {
|
||||||
if i < node.match_exprs.len {
|
if i < node.match_exprs.len {
|
||||||
match_expr := node.match_exprs[i]
|
match_expr := node.match_exprs[i]
|
||||||
|
c.expected_type = node.typ
|
||||||
c.expr(match_expr)
|
c.expr(match_expr)
|
||||||
}
|
}
|
||||||
for stmt in block.stmts {
|
for stmt in block.stmts {
|
||||||
|
@ -738,10 +744,13 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type {
|
||||||
// If a short form is used, `expected_type` needs to be an enum
|
// If a short form is used, `expected_type` needs to be an enum
|
||||||
// with this value.
|
// with this value.
|
||||||
pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type {
|
pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type {
|
||||||
// println('checker: enum: $node.enum_name')
|
|
||||||
typ_idx := if node.enum_name == '' { c.expected_type } else { //
|
typ_idx := if node.enum_name == '' { c.expected_type } else { //
|
||||||
c.table.find_type_idx(node.enum_name) }
|
c.table.find_type_idx(node.enum_name) }
|
||||||
typ := c.table.get_type_symbol(table.Type(typ_idx))
|
typ := c.table.get_type_symbol(table.Type(typ_idx))
|
||||||
|
// println('checker: enum_val: $node.enum_name typeidx=$typ_idx tname=$typ.name')
|
||||||
|
if typ.kind != .enum_ {
|
||||||
|
c.error('not an enum', node.pos)
|
||||||
|
}
|
||||||
// info := typ.info as table.Enum
|
// info := typ.info as table.Enum
|
||||||
info := typ.enum_info()
|
info := typ.enum_info()
|
||||||
// rintln('checker: x = $info.x enum val $c.expected_type $typ.name')
|
// rintln('checker: x = $info.x enum val $c.expected_type $typ.name')
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
fn test_scan() {
|
fn test_scan() {
|
||||||
text := 'println(2 + 3)'
|
text := 'println(2 + 3)'
|
||||||
mut scanner := new_scanner(text)
|
mut scanner := new_scanner(text, .skip_comments)
|
||||||
mut token_kinds := []token.Kind
|
mut token_kinds := []token.Kind
|
||||||
for {
|
for {
|
||||||
tok := scanner.scan()
|
tok := scanner.scan()
|
||||||
|
@ -25,17 +25,15 @@ fn test_scan() {
|
||||||
assert token_kinds[3] == .plus
|
assert token_kinds[3] == .plus
|
||||||
assert token_kinds[4] == .number
|
assert token_kinds[4] == .number
|
||||||
assert token_kinds[5] == .rpar
|
assert token_kinds[5] == .rpar
|
||||||
|
|
||||||
// test number costants input format
|
// test number costants input format
|
||||||
mut c := 0xa_0
|
mut c := 0xa0
|
||||||
assert c == 0xa0
|
assert c == 0xa0
|
||||||
c = 0b10_01
|
c = 0b1001
|
||||||
assert c == 9
|
assert c == 9
|
||||||
c = 1_000_000
|
c = 1000000
|
||||||
assert c == 1000000
|
assert c == 1000000
|
||||||
|
|
||||||
// test float conversion and reading
|
// test float conversion and reading
|
||||||
d := f64(23_000_000e-3)
|
d := f64(23000000e-3)
|
||||||
assert int(d) == 23000
|
assert int(d) == 23000
|
||||||
mut e := f64(1.2E3) * f64(-1e-1)
|
mut e := f64(1.2E3) * f64(-1e-1)
|
||||||
assert e == -120.0
|
assert e == -120.0
|
||||||
|
@ -43,6 +41,5 @@ fn test_scan() {
|
||||||
assert e == 120.0
|
assert e == 120.0
|
||||||
assert 1.23e+10 == 1.23e10
|
assert 1.23e+10 == 1.23e10
|
||||||
assert 1.23e+10 == 1.23e0010
|
assert 1.23e+10 == 1.23e0010
|
||||||
assert -1.23e+10 == 1.23e0010*-1.0
|
assert -1.23e+10 == 1.23e0010 * -1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue