diff --git a/vlib/builtin/map.v b/vlib/builtin/map.v index 52ff115696..e50ca0f982 100644 --- a/vlib/builtin/map.v +++ b/vlib/builtin/map.v @@ -148,7 +148,9 @@ fn (m map) get(key string, out voidptr) bool { mut node := m.root for { mut i := node.size - 1 - for i >= 0 && key < node.keys[i] { i-- } + for i >= 0 && key < node.keys[i] { + i-- + } if i != -1 && key == node.keys[i] { C.memcpy(out, node.values[i], m.value_bytes) return true diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 08cb640fb3..4c8769560d 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -11,7 +11,7 @@ import ( pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | -CastExpr | EnumVal | Assoc | SizeOf +CastExpr | EnumVal | Assoc | SizeOf | None pub type Stmt = VarDecl | GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | @@ -473,6 +473,10 @@ pub: text string } +pub struct None { +pub: + foo int // todo +} // 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 71c6859f9e..181c4d3a75 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -11,11 +11,16 @@ import ( filepath ) +const ( + max_nr_errors = 10 +) + pub struct Checker { table &table.Table mut: file_name string scope &ast.Scope + nr_errors int } pub fn new_checker(table &table.Table) Checker { @@ -86,11 +91,16 @@ pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type { left_type := c.expr(infix_expr.left) right_type := c.expr(infix_expr.right) if !c.table.check(right_type, left_type) { - left_type_sym := c.table.get_type_symbol(left_type) - right_type_sym := c.table.get_type_symbol(right_type) + left := c.table.get_type_symbol(left_type) + right := c.table.get_type_symbol(right_type) + // array << elm + // the expressions have different types (array_x and x) + if left.kind == .array && infix_expr.op == .left_shift { + return table.void_type + } // if !c.table.check(&infix_expr.right_type, &infix_expr.right_type) { // c.error('infix expr: cannot use `$infix_expr.right_type.name` as `$infix_expr.left_type.name`', infix_expr.pos) - c.error('infix expr: cannot use `$right_type_sym.name` as `$left_type_sym.name`', infix_expr.pos) + c.error('infix expr: cannot use `$right.name` (right) as `$left.name`', infix_expr.pos) } if infix_expr.op.is_relational() { return table.bool_type @@ -367,6 +377,9 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { ast.CastExpr { return it.typ } + ast.None { + return table.none_type + } else {} } return table.void_type @@ -570,14 +583,15 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type { else if typ_sym.kind in [.byteptr, .string] { return table.byte_type } - //else { - // return table.int_type - //} + // else { + // return table.int_type + // } } return typ } -pub fn (c &Checker) error(s string, pos token.Position) { +pub fn (c mut Checker) error(s string, pos token.Position) { + c.nr_errors++ print_backtrace() mut path := c.file_name // Get relative path @@ -585,7 +599,7 @@ pub fn (c &Checker) error(s string, pos token.Position) { if path.starts_with(workdir) { path = path.replace(workdir, '') } - final_msg_line := '$path:$pos.line_nr: checker error: $s' + final_msg_line := '$path:$pos.line_nr: checker error #$c.nr_errors: $s' eprintln(final_msg_line) /* if colored_output { @@ -595,5 +609,8 @@ pub fn (c &Checker) error(s string, pos token.Position) { } */ - exit(1) + println('\n\n') + if c.nr_errors >= max_nr_errors { + exit(1) + } } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 68c8c53c0f..0fba675b4a 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -128,31 +128,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) { f.writeln('') } ast.FnDecl { - mut receiver := '' - if it.is_method { - sym := f.table.get_type_symbol(it.receiver.typ) - name := sym.name.after('.') - m := if it.rec_mut { 'mut ' } else { '' } - receiver = '($it.receiver.name ${m}$name) ' - } - f.write('fn ${receiver}${it.name}(') - for i, arg in it.args { - is_last_arg := i == it.args.len - 1 - should_add_type := is_last_arg || it.args[i + 1].typ != arg.typ - f.write(arg.name) - if should_add_type { - arg_typ_sym := f.table.get_type_symbol(arg.typ) - f.write(' ${arg_typ_sym.name}') - } - if !is_last_arg { - f.write(', ') - } - } - f.write(')') - if it.typ != table.void_type { - sym := f.table.get_type_symbol(it.typ) - f.write(' ' + sym.name) - } + f.write(it.str(f.table)) f.writeln(' {') f.stmts(it.stmts) f.writeln('}\n') diff --git a/vlib/v/fmt/tests/simple_expected.vv b/vlib/v/fmt/tests/simple_expected.vv index dd710b6b6d..b2aa0e67ed 100644 --- a/vlib/v/fmt/tests/simple_expected.vv +++ b/vlib/v/fmt/tests/simple_expected.vv @@ -68,3 +68,7 @@ fn fn_with_3_args(arg1 string, arg2 int, arg3 User) int { fn (this User) fn_with_receiver() { println('') } + +//fn get_user() ?User { + +//} diff --git a/vlib/v/fmt/tests/simple_input.vv b/vlib/v/fmt/tests/simple_input.vv index f4cf6c1bd7..228f634983 100644 --- a/vlib/v/fmt/tests/simple_input.vv +++ b/vlib/v/fmt/tests/simple_input.vv @@ -72,3 +72,7 @@ return 0 fn (this User) fn_with_receiver() { println('') } + +//fn get_user() ? User { + +//} diff --git a/vlib/v/gen/tests/1.vv b/vlib/v/gen/tests/1.vv index 9206b545f7..bed91ec537 100644 --- a/vlib/v/gen/tests/1.vv +++ b/vlib/v/gen/tests/1.vv @@ -134,6 +134,8 @@ const ( ) fn end() { + //mut a := [1,2,3] + //(a << 4) + 2 } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ac52f42152..fe020b4b58 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -56,7 +56,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { pref: &pref.Preferences{} scope: scope // scope: &ast.Scope{start_pos: 0, parent: 0} - + } p.init_parse_fns() p.read_first_token() @@ -320,7 +320,7 @@ pub fn (p mut Parser) stmt() ast.Stmt { return ast.ExprStmt{ expr: expr // typ: typ - + } } } @@ -638,6 +638,8 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) { } .key_none { p.next() + typ = table.none_type + node = ast.None {} } .key_sizeof { p.next() // sizeof @@ -1072,10 +1074,10 @@ fn (p mut Parser) if_expr() ast.Expr { stmts: stmts else_stmts: else_stmts // typ: typ - + pos: pos // left: left - + } return node } @@ -1463,10 +1465,10 @@ fn (p mut Parser) var_decl() ast.VarDecl { node := ast.VarDecl{ name: name expr: expr // p.expr(token.lowest_prec) - + is_mut: is_mut // typ: typ - + pos: p.tok.position() } p.scope.register_var(node) @@ -1585,7 +1587,7 @@ fn (p mut Parser) match_expr() ast.Expr { blocks: blocks match_exprs: match_exprs // typ: typ - + cond: cond } return node diff --git a/vlib/v/table/atype_symbols.v b/vlib/v/table/atype_symbols.v index db67f87328..9abb0d5820 100644 --- a/vlib/v/table/atype_symbols.v +++ b/vlib/v/table/atype_symbols.v @@ -39,6 +39,7 @@ pub const ( string_type_idx = 17 array_type_idx = 18 map_type_idx = 19 + none_type_idx = 20 ) pub const ( @@ -81,6 +82,7 @@ pub enum Kind { sum_type alias unresolved + none_ } [inline] @@ -236,6 +238,10 @@ pub fn (t mut Table) register_builtin_type_symbols() { kind: .map name: 'map' }) + t.register_type_symbol(TypeSymbol{ + kind: .none_ + name: 'none' + }) // TODO: remove t.register_type_symbol(TypeSymbol{ parent_idx: map_type_idx diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 85afd149ae..267cdcd581 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -2,9 +2,12 @@ // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. module table -// import ( -// v.ast -// ) + +import ( + v.token + // v.ast +) + pub struct Table { // struct_fields map[string][]string pub mut: @@ -361,6 +364,10 @@ pub fn (t &Table) check(got, expected Type) bool { got_idx := type_idx(got) exp_idx := type_idx(expected) // println('check: $got_type_sym.name, $exp_type_sym.name') + if got_type_sym.kind == .none_ { + // TODO + return true + } if exp_type_sym.kind == .voidptr { return true } diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 1a47adceac..546a01f8ea 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -1,87 +1,87 @@ module table pub type Type int - // return underlying TypeSymbol idx [inline] pub fn type_idx(t Type) int { - return i16(int(t) >> 16) & 0xffffffff + return i16(int(t)>>16) & 0xffffffff } // return nr_muls [inline] pub fn type_nr_muls(t Type) int { - return i16(int(t) & 0xffffffff) + return i16(int(t) & 0xffffffff) } // return true if pointer (nr_muls>0) [inline] pub fn type_is_ptr(t Type) bool { - return type_nr_muls(t) > 0 + return type_nr_muls(t) > 0 } // increments nr_nuls on Type and return it [inline] pub fn type_to_ptr(t Type) Type { - return type_idx(t) << i16(16) | (type_nr_muls(t)+1) + return type_idx(t)< 32767 || idx < -32767 { - panic('new_type_id: idx must be between -32767 & 32767') - } - return idx << i16(16) + if idx > 32767 || idx < -32767 { + panic('new_type_id: idx must be between -32767 & 32767') + } + return idx< 32767 || idx < -32767 { - panic('typ_ptr: idx must be between -32767 & 32767') - } - if nr_muls > 32767 || nr_muls < -0 { - panic('typ_ptr: nr_muls must be between 0 & 32767') - } - return idx << i16(16) | nr_muls + if idx > 32767 || idx < -32767 { + panic('typ_ptr: idx must be between -32767 & 32767') + } + if nr_muls > 32767 || nr_muls < -0 { + panic('typ_ptr: nr_muls must be between 0 & 32767') + } + return idx<