v2: fix array index, for loop, add cast expr & other minor fixes
parent
c9f619dc72
commit
bf5ed5e451
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
|
||||
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
|
||||
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr
|
||||
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr
|
||||
|
||||
pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
|
||||
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
|
||||
|
@ -389,6 +389,12 @@ pub:
|
|||
high Expr
|
||||
}
|
||||
|
||||
pub struct CastExpr {
|
||||
pub:
|
||||
typ table.Type
|
||||
expr Expr
|
||||
}
|
||||
|
||||
// string representaiton of expr
|
||||
pub fn (x Expr) str() string {
|
||||
match x {
|
||||
|
|
|
@ -411,6 +411,9 @@ pub fn (c &Checker) expr(node ast.Expr) table.Type {
|
|||
}
|
||||
}
|
||||
}
|
||||
ast.CastExpr {
|
||||
return it.typ
|
||||
}
|
||||
else {}
|
||||
}
|
||||
return table.void_type
|
||||
|
@ -462,8 +465,6 @@ pub fn (c &Checker) index_expr(node ast.IndexExpr) table.Type {
|
|||
typ = table.int_type
|
||||
}
|
||||
return typ
|
||||
// c.expr(it.index)
|
||||
// return it.typ
|
||||
}
|
||||
|
||||
pub fn (c &Checker) error(s string, pos token.Position) {
|
||||
|
|
|
@ -11,22 +11,22 @@ pub fn (p mut Parser) parse_array_type(nr_muls int) table.Type {
|
|||
// fixed array
|
||||
if p.tok.kind == .number {
|
||||
size := p.tok.lit.int()
|
||||
elem_ti := p.parse_type()
|
||||
elem_type := p.parse_type()
|
||||
p.check(.rsbr)
|
||||
p.check_name()
|
||||
idx := p.table.find_or_register_array_fixed(elem_ti, size, 1)
|
||||
idx := p.table.find_or_register_array_fixed(elem_type, size, 1)
|
||||
return table.new_type_ptr(idx, nr_muls)
|
||||
}
|
||||
// array
|
||||
p.check(.rsbr)
|
||||
elem_ti := p.parse_type()
|
||||
elem_type := p.parse_type()
|
||||
mut nr_dims := 1
|
||||
for p.tok.kind == .lsbr {
|
||||
p.check(.lsbr)
|
||||
p.check(.rsbr)
|
||||
nr_dims++
|
||||
}
|
||||
idx := p.table.find_or_register_array(elem_ti, nr_dims)
|
||||
idx := p.table.find_or_register_array(elem_type, nr_dims)
|
||||
return table.new_type_ptr(idx, nr_muls)
|
||||
}
|
||||
|
||||
|
|
|
@ -467,24 +467,25 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
|
|||
if p.peek_tok.kind == .lpar {
|
||||
name := p.tok.lit
|
||||
// type cast. TODO: finish
|
||||
if name in table.builtin_type_names {
|
||||
// ['byte', 'string', 'int']
|
||||
// SKIP FOR NOW
|
||||
mut par_d := 0
|
||||
for {
|
||||
if p.tok.kind == .lpar {
|
||||
par_d++
|
||||
}
|
||||
if p.tok.kind == .rpar {
|
||||
par_d--
|
||||
if par_d == 0 {
|
||||
p.next()
|
||||
break
|
||||
}
|
||||
}
|
||||
p.next()
|
||||
//if name in table.builtin_type_names {
|
||||
if name in p.table.type_idxs {
|
||||
to_typ := p.parse_type()
|
||||
p.check(.lpar)
|
||||
mut expr := ast.Expr{}
|
||||
expr,_ = p.expr(0)
|
||||
// TODO, string(b, len)
|
||||
if table.type_idx(to_typ) == table.string_type_idx && p.tok.kind == .comma {
|
||||
p.check(.comma)
|
||||
p.expr(0) // len
|
||||
}
|
||||
p.check(.rpar)
|
||||
node = ast.CastExpr{
|
||||
typ: to_typ
|
||||
expr: expr
|
||||
}
|
||||
return node, to_typ
|
||||
}
|
||||
// fn call
|
||||
else {
|
||||
println('calling $p.tok.lit')
|
||||
x,ti2 := p.call_expr() // TODO `node,typ :=` should work
|
||||
|
@ -809,15 +810,31 @@ fn (p mut Parser) for_statement() ast.Stmt {
|
|||
})
|
||||
}
|
||||
p.check(.key_in)
|
||||
start := p.tok.lit.int()
|
||||
p.expr(0)
|
||||
mut elem_type := table.void_type
|
||||
/*arr_expr*/_,arr_typ := p.expr(0)
|
||||
// array / map
|
||||
arr_typ_sym := p.table.get_type_symbol(arr_typ)
|
||||
match arr_typ_sym.info {
|
||||
table.Array {
|
||||
elem_type = it.elem_type
|
||||
}
|
||||
table.Map {
|
||||
elem_type = it.value_type
|
||||
}
|
||||
else {
|
||||
//elem_type_sym := p.table.get_type_symbol(elem_type)
|
||||
//p.error('cannot loop over type: $elem_type_sym.name')
|
||||
}
|
||||
}
|
||||
// 0 .. 10
|
||||
// start := p.tok.lit.int()
|
||||
if p.tok.kind == .dotdot {
|
||||
p.check(.dotdot)
|
||||
p.expr(0)
|
||||
}
|
||||
p.table.register_var(table.Var{
|
||||
name: var_name
|
||||
typ: table.int_type
|
||||
typ: elem_type
|
||||
})
|
||||
stmts := p.parse_block()
|
||||
// println('nr stmts=$stmts.len')
|
||||
|
@ -913,27 +930,50 @@ fn (p mut Parser) array_init() (ast.Expr,table.Type) {
|
|||
p.check(.lsbr)
|
||||
mut val_type := table.void_type
|
||||
mut exprs := []ast.Expr
|
||||
for i := 0; p.tok.kind != .rsbr; i++ {
|
||||
expr,typ := p.expr(0)
|
||||
exprs << expr
|
||||
if i == 0 {
|
||||
val_type = typ
|
||||
mut is_fixed := false
|
||||
mut fixed_size := 0
|
||||
if p.tok.kind == .rsbr {
|
||||
p.check(.rsbr)
|
||||
// []string
|
||||
if p.tok.kind == .name {
|
||||
val_type = p.parse_type()
|
||||
}
|
||||
if p.tok.kind == .comma {
|
||||
p.check(.comma)
|
||||
// []
|
||||
else {
|
||||
// TODO ?
|
||||
}
|
||||
}
|
||||
line_nr := p.tok.line_nr
|
||||
p.check(.rsbr)
|
||||
// Fixed size array? (`[100]byte`)
|
||||
if exprs.len <= 1 && p.tok.kind == .name && p.tok.line_nr == line_nr {
|
||||
p.check_name()
|
||||
p.warn('fixed size array')
|
||||
// type_idx,type_name := p.table.find_or_register_array_fixed(val_type, 1)
|
||||
// node =
|
||||
else {
|
||||
// [1,2,3]
|
||||
for i := 0; p.tok.kind != .rsbr; i++ {
|
||||
expr,typ := p.expr(0)
|
||||
exprs << expr
|
||||
if i == 0 {
|
||||
val_type = typ
|
||||
}
|
||||
if p.tok.kind == .comma {
|
||||
p.check(.comma)
|
||||
}
|
||||
}
|
||||
line_nr := p.tok.line_nr
|
||||
p.check(.rsbr)
|
||||
// Fixed size array? (`[100]byte`)
|
||||
if exprs.len == 1 && p.tok.kind == .name && p.tok.line_nr == line_nr {
|
||||
is_fixed = true
|
||||
val_type = p.parse_type()
|
||||
match exprs[0] {
|
||||
ast.IntegerLiteral { fixed_size = it.val }
|
||||
else {}
|
||||
}
|
||||
p.warn('fixed size array')
|
||||
}
|
||||
}
|
||||
idx := if is_fixed {
|
||||
p.table.find_or_register_array_fixed(val_type, fixed_size, 1)
|
||||
}
|
||||
else {
|
||||
p.table.find_or_register_array(val_type, 1)
|
||||
}
|
||||
// array_type := table.new_type(.array, type_name, type_idx, 0)
|
||||
idx := p.table.find_or_register_array(val_type, 1)
|
||||
array_type := table.new_type(idx)
|
||||
node = ast.ArrayInit{
|
||||
typ: array_type
|
||||
|
|
|
@ -245,6 +245,12 @@ pub fn (t mut Table) register_builtin_type_symbols() {
|
|||
kind: .map
|
||||
name: 'map'
|
||||
})
|
||||
// TODO: remove
|
||||
t.register_type_symbol(TypeSymbol{
|
||||
parent: &t.types[map_type_idx]
|
||||
kind: .struct_
|
||||
name: 'map_string'
|
||||
})
|
||||
}
|
||||
|
||||
[inline]
|
||||
|
|
|
@ -317,8 +317,12 @@ pub fn (t mut Table) register_builtin_type_symbol(typ TypeSymbol) int {
|
|||
existing_idx := t.type_idxs[typ.name]
|
||||
if existing_idx > 0 {
|
||||
if existing_idx >= string_type_idx {
|
||||
existing_type := t.types[existing_idx]
|
||||
t.types[existing_idx] = { typ | kind: existing_type.kind }
|
||||
if existing_idx == string_type_idx {
|
||||
existing_type := &t.types[existing_idx]
|
||||
t.types[existing_idx] = { typ | kind: existing_type.kind }
|
||||
} else {
|
||||
t.types[existing_idx] = typ
|
||||
}
|
||||
}
|
||||
return existing_idx
|
||||
}
|
||||
|
@ -476,6 +480,12 @@ pub fn (t &Table) check(got, expected Type) bool {
|
|||
if got_type_sym.is_int() && exp_type_sym.is_int() {
|
||||
return true
|
||||
}
|
||||
if got_type_sym.kind == .array_fixed && exp_type_sym.kind == .byteptr {
|
||||
info := got_type_sym.info as ArrayFixed
|
||||
if type_idx(info.elem_type) == byte_type_idx {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// if expected.name == 'array' {
|
||||
// return true
|
||||
// }
|
||||
|
|
Loading…
Reference in New Issue