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 |
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 {

View File

@ -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) {

View File

@ -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)
}

View File

@ -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

View File

@ -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]

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]
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
// }