v2: fix array index, for loop, add cast expr & other minor fixes

pull/3715/head
joe-conigliaro 2020-02-11 00:43:17 +11:00 committed by GitHub
parent c9f619dc72
commit bf5ed5e451
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 45 deletions

View File

@ -10,7 +10,7 @@ import (
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | 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 | pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
@ -389,6 +389,12 @@ pub:
high Expr high Expr
} }
pub struct CastExpr {
pub:
typ table.Type
expr Expr
}
// string representaiton of expr // string representaiton of expr
pub fn (x Expr) str() string { pub fn (x Expr) str() string {
match x { match x {

View File

@ -411,6 +411,9 @@ pub fn (c &Checker) expr(node ast.Expr) table.Type {
} }
} }
} }
ast.CastExpr {
return it.typ
}
else {} else {}
} }
return table.void_type return table.void_type
@ -462,8 +465,6 @@ pub fn (c &Checker) index_expr(node ast.IndexExpr) table.Type {
typ = table.int_type typ = table.int_type
} }
return typ return typ
// c.expr(it.index)
// return it.typ
} }
pub fn (c &Checker) error(s string, pos token.Position) { pub fn (c &Checker) error(s string, pos token.Position) {

View File

@ -11,22 +11,22 @@ pub fn (p mut Parser) parse_array_type(nr_muls int) table.Type {
// fixed array // fixed array
if p.tok.kind == .number { if p.tok.kind == .number {
size := p.tok.lit.int() size := p.tok.lit.int()
elem_ti := p.parse_type() elem_type := p.parse_type()
p.check(.rsbr) p.check(.rsbr)
p.check_name() 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) return table.new_type_ptr(idx, nr_muls)
} }
// array // array
p.check(.rsbr) p.check(.rsbr)
elem_ti := p.parse_type() elem_type := p.parse_type()
mut nr_dims := 1 mut nr_dims := 1
for p.tok.kind == .lsbr { for p.tok.kind == .lsbr {
p.check(.lsbr) p.check(.lsbr)
p.check(.rsbr) p.check(.rsbr)
nr_dims++ 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) return table.new_type_ptr(idx, nr_muls)
} }

View File

@ -467,24 +467,25 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
if p.peek_tok.kind == .lpar { if p.peek_tok.kind == .lpar {
name := p.tok.lit name := p.tok.lit
// type cast. TODO: finish // type cast. TODO: finish
if name in table.builtin_type_names { //if name in table.builtin_type_names {
// ['byte', 'string', 'int'] if name in p.table.type_idxs {
// SKIP FOR NOW to_typ := p.parse_type()
mut par_d := 0 p.check(.lpar)
for { mut expr := ast.Expr{}
if p.tok.kind == .lpar { expr,_ = p.expr(0)
par_d++ // TODO, string(b, len)
} if table.type_idx(to_typ) == table.string_type_idx && p.tok.kind == .comma {
if p.tok.kind == .rpar { p.check(.comma)
par_d-- p.expr(0) // len
if par_d == 0 {
p.next()
break
}
}
p.next()
} }
p.check(.rpar)
node = ast.CastExpr{
typ: to_typ
expr: expr
}
return node, to_typ
} }
// fn call
else { else {
println('calling $p.tok.lit') println('calling $p.tok.lit')
x,ti2 := p.call_expr() // TODO `node,typ :=` should work 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) p.check(.key_in)
start := p.tok.lit.int() mut elem_type := table.void_type
p.expr(0) /*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 { if p.tok.kind == .dotdot {
p.check(.dotdot) p.check(.dotdot)
p.expr(0) p.expr(0)
} }
p.table.register_var(table.Var{ p.table.register_var(table.Var{
name: var_name name: var_name
typ: table.int_type typ: elem_type
}) })
stmts := p.parse_block() stmts := p.parse_block()
// println('nr stmts=$stmts.len') // println('nr stmts=$stmts.len')
@ -913,27 +930,50 @@ fn (p mut Parser) array_init() (ast.Expr,table.Type) {
p.check(.lsbr) p.check(.lsbr)
mut val_type := table.void_type mut val_type := table.void_type
mut exprs := []ast.Expr mut exprs := []ast.Expr
for i := 0; p.tok.kind != .rsbr; i++ { mut is_fixed := false
expr,typ := p.expr(0) mut fixed_size := 0
exprs << expr if p.tok.kind == .rsbr {
if i == 0 { p.check(.rsbr)
val_type = typ // []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 else {
p.check(.rsbr) // [1,2,3]
// Fixed size array? (`[100]byte`) for i := 0; p.tok.kind != .rsbr; i++ {
if exprs.len <= 1 && p.tok.kind == .name && p.tok.line_nr == line_nr { expr,typ := p.expr(0)
p.check_name() exprs << expr
p.warn('fixed size array') if i == 0 {
// type_idx,type_name := p.table.find_or_register_array_fixed(val_type, 1) val_type = typ
// node = }
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) array_type := table.new_type(idx)
node = ast.ArrayInit{ node = ast.ArrayInit{
typ: array_type typ: array_type

View File

@ -245,6 +245,12 @@ pub fn (t mut Table) register_builtin_type_symbols() {
kind: .map kind: .map
name: 'map' name: 'map'
}) })
// TODO: remove
t.register_type_symbol(TypeSymbol{
parent: &t.types[map_type_idx]
kind: .struct_
name: 'map_string'
})
} }
[inline] [inline]

View File

@ -317,8 +317,12 @@ pub fn (t mut Table) register_builtin_type_symbol(typ TypeSymbol) int {
existing_idx := t.type_idxs[typ.name] existing_idx := t.type_idxs[typ.name]
if existing_idx > 0 { if existing_idx > 0 {
if existing_idx >= string_type_idx { if existing_idx >= string_type_idx {
existing_type := t.types[existing_idx] if existing_idx == string_type_idx {
t.types[existing_idx] = { typ | kind: existing_type.kind } existing_type := &t.types[existing_idx]
t.types[existing_idx] = { typ | kind: existing_type.kind }
} else {
t.types[existing_idx] = typ
}
} }
return existing_idx 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() { if got_type_sym.is_int() && exp_type_sym.is_int() {
return true 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' { // if expected.name == 'array' {
// return true // return true
// } // }