v2: ArrayInit + all errs & unhandled + arrange nodes + type fix
parent
cbffbf3438
commit
00dcaf0e04
|
@ -23,6 +23,9 @@ mut:
|
||||||
errors []string
|
errors []string
|
||||||
expected_type table.Type
|
expected_type table.Type
|
||||||
fn_return_type table.Type // current function's return type
|
fn_return_type table.Type // current function's return type
|
||||||
|
// TODO: remove once all exprs/stmts are handled
|
||||||
|
unhandled_exprs []string
|
||||||
|
unhandled_stmts []string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_checker(table &table.Table) Checker {
|
pub fn new_checker(table &table.Table) Checker {
|
||||||
|
@ -42,10 +45,6 @@ pub fn (c mut Checker) check(ast_file ast.File) {
|
||||||
println(t.name + ' - ' + t.kind.str())
|
println(t.name + ' - ' + t.kind.str())
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if c.nr_errors > 0 {
|
|
||||||
exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c mut Checker) check2(ast_file ast.File) []string {
|
pub fn (c mut Checker) check2(ast_file ast.File) []string {
|
||||||
|
@ -72,6 +71,8 @@ pub fn (c mut Checker) check_files(ast_files []ast.File) {
|
||||||
for file in ast_files {
|
for file in ast_files {
|
||||||
c.check(file)
|
c.check(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.print_unhandled_nodes()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type {
|
pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type {
|
||||||
|
@ -370,18 +371,11 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
|
||||||
fn (c mut Checker) stmt(node ast.Stmt) {
|
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 {
|
|
||||||
c.fn_return_type = it.typ
|
|
||||||
for stmt in it.stmts {
|
|
||||||
c.stmt(stmt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast.Return {
|
|
||||||
c.return_stmt(it)
|
|
||||||
}
|
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
c.assign_stmt(it)
|
c.assign_stmt(it)
|
||||||
}
|
}
|
||||||
|
// ast.Attr {}
|
||||||
|
// ast.CompIf {}
|
||||||
ast.ConstDecl {
|
ast.ConstDecl {
|
||||||
for i, expr in it.exprs {
|
for i, expr in it.exprs {
|
||||||
mut field := it.fields[i]
|
mut field := it.fields[i]
|
||||||
|
@ -395,14 +389,14 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
it.fields[i] = field
|
it.fields[i] = field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.VarDecl {
|
ast.ExprStmt {
|
||||||
typ := c.expr(it.expr)
|
c.expr(it.expr)
|
||||||
// typ_sym := c.table.get_type_symbol(typ)
|
}
|
||||||
// println('var $it.name - $typ - $it.typ - $typ_sym.name')
|
ast.FnDecl {
|
||||||
// if it.typ == 0 {
|
c.fn_return_type = it.typ
|
||||||
// it.typ = typ
|
for stmt in it.stmts {
|
||||||
// }
|
c.stmt(stmt)
|
||||||
it.typ = typ
|
}
|
||||||
}
|
}
|
||||||
ast.ForStmt {
|
ast.ForStmt {
|
||||||
typ := c.expr(it.cond)
|
typ := c.expr(it.cond)
|
||||||
|
@ -423,11 +417,27 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
c.stmt(stmt)
|
c.stmt(stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ast.StructDecl {}
|
// ast.ForInStmt {}
|
||||||
ast.ExprStmt {
|
// ast.GlobalDecl {}
|
||||||
c.expr(it.expr)
|
// ast.HashStmt {}
|
||||||
|
ast.Import {}
|
||||||
|
ast.Return {
|
||||||
|
c.return_stmt(it)
|
||||||
|
}
|
||||||
|
// ast.StructDecl {}
|
||||||
|
ast.VarDecl {
|
||||||
|
typ := c.expr(it.expr)
|
||||||
|
// typ_sym := c.table.get_type_symbol(typ)
|
||||||
|
// println('var $it.name - $typ - $it.typ - $typ_sym.name')
|
||||||
|
// if it.typ == 0 {
|
||||||
|
// it.typ = typ
|
||||||
|
// }
|
||||||
|
it.typ = typ
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node_name := typeof(node)
|
||||||
|
if !(node_name) in c.unhandled_stmts { c.unhandled_stmts << node_name }
|
||||||
}
|
}
|
||||||
else {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,6 +449,9 @@ fn (c mut Checker) stmts(stmts []ast.Stmt) {
|
||||||
|
|
||||||
pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
||||||
match mut node {
|
match mut node {
|
||||||
|
ast.ArrayInit {
|
||||||
|
return c.array_init(mut it)
|
||||||
|
}
|
||||||
ast.AssignExpr {
|
ast.AssignExpr {
|
||||||
c.check_assign_expr(it)
|
c.check_assign_expr(it)
|
||||||
}
|
}
|
||||||
|
@ -451,82 +464,85 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
|
||||||
}
|
}
|
||||||
return var.typ
|
return var.typ
|
||||||
}
|
}
|
||||||
|
ast.BoolLiteral {
|
||||||
|
return table.bool_type
|
||||||
|
}
|
||||||
|
ast.CastExpr {
|
||||||
|
return it.typ
|
||||||
|
}
|
||||||
|
ast.CallExpr {
|
||||||
|
return c.call_expr(it)
|
||||||
|
}
|
||||||
|
ast.CharLiteral {
|
||||||
|
return table.byte_type
|
||||||
|
}
|
||||||
ast.EnumVal {
|
ast.EnumVal {
|
||||||
return c.enum_val(it)
|
return c.enum_val(it)
|
||||||
}
|
}
|
||||||
ast.FloatLiteral {
|
ast.FloatLiteral {
|
||||||
return table.f64_type
|
return table.f64_type
|
||||||
}
|
}
|
||||||
|
ast.Ident {
|
||||||
|
return c.ident(mut it)
|
||||||
|
}
|
||||||
|
ast.IfExpr {
|
||||||
|
return c.if_expr(mut it)
|
||||||
|
}
|
||||||
|
ast.IfGuardExpr {
|
||||||
|
return table.bool_type
|
||||||
|
}
|
||||||
|
ast.IndexExpr {
|
||||||
|
return c.index_expr(it)
|
||||||
|
}
|
||||||
|
ast.InfixExpr {
|
||||||
|
return c.infix_expr(it)
|
||||||
|
}
|
||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
return table.int_type
|
return table.int_type
|
||||||
}
|
}
|
||||||
|
ast.MapInit {
|
||||||
|
return c.map_init(it)
|
||||||
|
}
|
||||||
|
ast.MatchExpr {
|
||||||
|
return c.match_expr(mut it)
|
||||||
|
}
|
||||||
|
ast.MethodCallExpr {
|
||||||
|
return c.check_method_call_expr(it)
|
||||||
|
}
|
||||||
ast.PostfixExpr {
|
ast.PostfixExpr {
|
||||||
return c.postfix_expr(it)
|
return c.postfix_expr(it)
|
||||||
}
|
}
|
||||||
/*
|
ast.PrefixExpr {
|
||||||
ast.UnaryExpr {
|
return c.expr(it.right)
|
||||||
c.expr(it.left)
|
}
|
||||||
|
ast.None {
|
||||||
|
return table.none_type
|
||||||
|
}
|
||||||
|
ast.ParExpr {
|
||||||
|
return c.expr(it.expr)
|
||||||
|
}
|
||||||
|
ast.SelectorExpr {
|
||||||
|
return c.selector_expr(it)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
ast.SizeOf {
|
ast.SizeOf {
|
||||||
return table.int_type
|
return table.int_type
|
||||||
}
|
}
|
||||||
ast.StringLiteral {
|
ast.StringLiteral {
|
||||||
return table.string_type
|
return table.string_type
|
||||||
}
|
}
|
||||||
ast.CharLiteral {
|
|
||||||
return table.byte_type
|
|
||||||
}
|
|
||||||
ast.PrefixExpr {
|
|
||||||
return c.expr(it.right)
|
|
||||||
}
|
|
||||||
ast.InfixExpr {
|
|
||||||
return c.infix_expr(it)
|
|
||||||
}
|
|
||||||
ast.StructInit {
|
ast.StructInit {
|
||||||
return c.check_struct_init(it)
|
return c.check_struct_init(it)
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
/*
|
||||||
return c.call_expr(it)
|
ast.UnaryExpr {
|
||||||
|
c.expr(it.left)
|
||||||
}
|
}
|
||||||
ast.MethodCallExpr {
|
*/
|
||||||
return c.check_method_call_expr(it)
|
else {
|
||||||
|
// TODO: find nil string bug triggered with typeof
|
||||||
|
// node_name := typeof(node)
|
||||||
|
// if !(node_name) in c.unhandled_exprs { c.unhandled_exprs << node_name }
|
||||||
}
|
}
|
||||||
ast.ArrayInit {
|
|
||||||
return c.array_init(mut it)
|
|
||||||
}
|
|
||||||
ast.Ident {
|
|
||||||
return c.ident(mut it)
|
|
||||||
}
|
|
||||||
ast.BoolLiteral {
|
|
||||||
return table.bool_type
|
|
||||||
}
|
|
||||||
ast.SelectorExpr {
|
|
||||||
return c.selector_expr(it)
|
|
||||||
}
|
|
||||||
ast.IndexExpr {
|
|
||||||
return c.index_expr(it)
|
|
||||||
}
|
|
||||||
ast.IfExpr {
|
|
||||||
return c.if_expr(mut it)
|
|
||||||
}
|
|
||||||
ast.MatchExpr {
|
|
||||||
return c.match_expr(mut it)
|
|
||||||
}
|
|
||||||
ast.CastExpr {
|
|
||||||
return it.typ
|
|
||||||
}
|
|
||||||
ast.ParExpr {
|
|
||||||
return c.expr(it.expr)
|
|
||||||
}
|
|
||||||
ast.None {
|
|
||||||
return table.none_type
|
|
||||||
}
|
|
||||||
ast.IfGuardExpr {
|
|
||||||
return table.bool_type
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
}
|
}
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
|
@ -775,6 +791,40 @@ pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type {
|
||||||
return typ_idx
|
return typ_idx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (c mut Checker) map_init(node ast.MapInit) table.Type {
|
||||||
|
key0_type := c.expr(node.keys[0])
|
||||||
|
val0_type := c.expr(node.vals[0])
|
||||||
|
for i, key in node.keys {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val := node.vals[i]
|
||||||
|
key_type := c.expr(key)
|
||||||
|
val_type := c.expr(val)
|
||||||
|
if !c.table.check(key_type, key0_type) {
|
||||||
|
key0_type_sym := c.table.get_type_symbol(key0_type)
|
||||||
|
key_type_sym := c.table.get_type_symbol(key_type)
|
||||||
|
c.error('map init: cannot use `$key_type_sym.name` as `$key0_type_sym` for map key', node.pos)
|
||||||
|
}
|
||||||
|
if !c.table.check(val_type, val0_type) {
|
||||||
|
val0_type_sym := c.table.get_type_symbol(val0_type)
|
||||||
|
val_type_sym := c.table.get_type_symbol(val_type)
|
||||||
|
c.error('map init: cannot use `$val_type_sym.name` as `$val0_type_sym` for map value', node.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c.table.find_or_register_map(key0_type, val0_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove once all exprs/stmts are handled
|
||||||
|
pub fn (c &Checker) print_unhandled_nodes() {
|
||||||
|
if c.unhandled_exprs.len > 0 {
|
||||||
|
eprintln(' # unhandled Expr nodes:\n\t * ' + c.unhandled_exprs.join(', ') + '\n')
|
||||||
|
}
|
||||||
|
if c.unhandled_stmts.len > 0 {
|
||||||
|
eprintln(' # unhandled Stmt nodes:\n\t * ' + c.unhandled_stmts.join(', ') + '\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (c mut Checker) error(s string, pos token.Position) {
|
pub fn (c mut Checker) error(s string, pos token.Position) {
|
||||||
c.nr_errors++
|
c.nr_errors++
|
||||||
print_backtrace()
|
print_backtrace()
|
||||||
|
@ -797,6 +847,7 @@ pub fn (c mut Checker) error(s string, pos token.Position) {
|
||||||
|
|
||||||
println('\n\n')
|
println('\n\n')
|
||||||
if c.nr_errors >= max_nr_errors {
|
if c.nr_errors >= max_nr_errors {
|
||||||
|
c.print_unhandled_nodes()
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ pub fn (t &TypeSymbol) enum_info() Enum {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('TypeSymbol.enum_info(): no enum info')
|
panic('TypeSymbol.enum_info(): no enum info for type: $t.name')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ pub fn (t &TypeSymbol) mr_info() MultiReturn {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('TypeSymbol.mr_info(): no multi return info')
|
panic('TypeSymbol.mr_info(): no multi return info for type: $t.name')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ pub fn (t &TypeSymbol) array_info() Array {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('TypeSymbol.array_info(): no array info')
|
panic('TypeSymbol.array_info(): no array info for type: $t.name')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ pub fn (t &TypeSymbol) array_fixed_info() ArrayFixed {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('TypeSymbol.array_fixed(): no array fixed info')
|
panic('TypeSymbol.array_fixed(): no array fixed info for type: $t.name')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ pub fn (t &TypeSymbol) map_info() Map {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('TypeSymbol.map_info(): no map info')
|
panic('TypeSymbol.map_info(): no map info for type: $t.name')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,22 +155,6 @@ pub fn (t TypeSymbol) str() string {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn array_name(elem_type &TypeSymbol, nr_dims int) string {
|
|
||||||
return 'array_${elem_type.name}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn array_fixed_name(elem_type &TypeSymbol, size int, nr_dims int) string {
|
|
||||||
return 'array_fixed_${elem_type.name}_${size}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
|
||||||
pub fn map_name(key_type &TypeSymbol, value_type &TypeSymbol) string {
|
|
||||||
return 'map_${key_type.name}_${value_type.name}'
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (t mut Table) register_builtin_type_symbols() {
|
pub fn (t mut Table) register_builtin_type_symbols() {
|
||||||
// reserve index 0 so nothing can go there
|
// reserve index 0 so nothing can go there
|
||||||
// save index check, 0 will mean not found
|
// save index check, 0 will mean not found
|
||||||
|
|
|
@ -252,10 +252,32 @@ pub fn (t &Table) known_type(name string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (t mut Table) find_or_register_map(key_type, value_type Type) int {
|
[inline]
|
||||||
|
pub fn (t &Table) array_name(elem_type Type, nr_dims int) string {
|
||||||
|
elem_type_sym := t.get_type_symbol(elem_type)
|
||||||
|
return 'array_${elem_type_sym.name}'
|
||||||
|
+ if type_is_ptr(elem_type) { '_ptr' } else { '' }
|
||||||
|
+ if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
pub fn (t &Table) array_fixed_name(elem_type Type, size int, nr_dims int) string {
|
||||||
|
elem_type_sym := t.get_type_symbol(elem_type)
|
||||||
|
return 'array_fixed_${elem_type_sym.name}_${size}'
|
||||||
|
+ if type_is_ptr(elem_type) { '_ptr' } else { '' }
|
||||||
|
+ if nr_dims > 1 { '_${nr_dims}d' } else { '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
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)
|
||||||
val_type_sym := t.get_type_symbol(value_type)
|
value_type_sym := t.get_type_symbol(value_type)
|
||||||
name := map_name(key_type_sym, val_type_sym)
|
return 'map_${key_type_sym.name}_${value_type_sym.name}'
|
||||||
|
+ if type_is_ptr(value_type) { '_ptr' } else { '' }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (t mut Table) find_or_register_map(key_type, value_type Type) int {
|
||||||
|
name := t.map_name(key_type, value_type)
|
||||||
// existing
|
// existing
|
||||||
existing_idx := t.type_idxs[name]
|
existing_idx := t.type_idxs[name]
|
||||||
if existing_idx > 0 {
|
if existing_idx > 0 {
|
||||||
|
@ -275,8 +297,7 @@ pub fn (t mut Table) find_or_register_map(key_type, value_type Type) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (t mut Table) find_or_register_array(elem_type Type, nr_dims int) int {
|
pub fn (t mut Table) find_or_register_array(elem_type Type, nr_dims int) int {
|
||||||
elem_type_sym := t.get_type_symbol(elem_type)
|
name := t.array_name(elem_type, nr_dims)
|
||||||
name := array_name(elem_type_sym, nr_dims)
|
|
||||||
// existing
|
// existing
|
||||||
existing_idx := t.type_idxs[name]
|
existing_idx := t.type_idxs[name]
|
||||||
if existing_idx > 0 {
|
if existing_idx > 0 {
|
||||||
|
@ -296,8 +317,7 @@ pub fn (t mut Table) find_or_register_array(elem_type Type, nr_dims int) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (t mut Table) find_or_register_array_fixed(elem_type Type, size int, nr_dims int) int {
|
pub fn (t mut Table) find_or_register_array_fixed(elem_type Type, size int, nr_dims int) int {
|
||||||
elem_type_sym := t.get_type_symbol(elem_type)
|
name := t.array_fixed_name(elem_type, size, nr_dims)
|
||||||
name := array_fixed_name(elem_type_sym, size, nr_dims)
|
|
||||||
// existing
|
// existing
|
||||||
existing_idx := t.type_idxs[name]
|
existing_idx := t.type_idxs[name]
|
||||||
if existing_idx > 0 {
|
if existing_idx > 0 {
|
||||||
|
|
Loading…
Reference in New Issue