mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v2: fix array index, for loop, add cast expr & other minor fixes
This commit is contained in:
parent
c9f619dc72
commit
bf5ed5e451
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
// }
|
// }
|
||||||
|
Loading…
Reference in New Issue
Block a user