From bf5ed5e451ff413faedf3cdd927952051614d255 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Tue, 11 Feb 2020 00:43:17 +1100 Subject: [PATCH] v2: fix array index, for loop, add cast expr & other minor fixes --- vlib/v/ast/ast.v | 8 ++- vlib/v/checker/checker.v | 5 +- vlib/v/parser/parse_type.v | 8 +-- vlib/v/parser/parser.v | 112 ++++++++++++++++++++++++----------- vlib/v/table/atype_symbols.v | 6 ++ vlib/v/table/table.v | 14 ++++- 6 files changed, 108 insertions(+), 45 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 04b8795118..b49db7eb5b 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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 { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 698acda685..0ef0343357 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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) { diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 35b496b419..2bce463e6e 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -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) } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 3ad90b2b7c..ce5ab7e887 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -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 diff --git a/vlib/v/table/atype_symbols.v b/vlib/v/table/atype_symbols.v index b794866b7c..30fe31024d 100644 --- a/vlib/v/table/atype_symbols.v +++ b/vlib/v/table/atype_symbols.v @@ -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] diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 41d71d97a1..d7e6088eed 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -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 // }