checker: print multiple errors; none
parent
d91945cc99
commit
ec3d67c19f
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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 {
|
||||
|
||||
//}
|
||||
|
|
|
@ -72,3 +72,7 @@ return 0
|
|||
fn (this User) fn_with_receiver() {
|
||||
println('')
|
||||
}
|
||||
|
||||
//fn get_user() ? User {
|
||||
|
||||
//}
|
||||
|
|
|
@ -134,6 +134,8 @@ const (
|
|||
)
|
||||
|
||||
fn end() {
|
||||
//mut a := [1,2,3]
|
||||
//(a << 4) + 2
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)<<i16(16) | (type_nr_muls(t) + 1)
|
||||
}
|
||||
|
||||
// decrement nr_muls on Type and return it
|
||||
[inline]
|
||||
pub fn type_deref(t Type) Type {
|
||||
idx := type_idx(t)
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls == 0 {
|
||||
panic('deref: $idx is not a pointer')
|
||||
}
|
||||
return idx << i16(16) | (nr_muls+-1)
|
||||
idx := type_idx(t)
|
||||
nr_muls := type_nr_muls(t)
|
||||
if nr_muls == 0 {
|
||||
panic('deref: $idx is not a pointer')
|
||||
}
|
||||
return idx<<i16(16) | (nr_muls + -1)
|
||||
}
|
||||
|
||||
// new type with idx of TypeSymbol, not pointer (nr_muls=0)
|
||||
[inline]
|
||||
pub fn new_type(idx int) Type {
|
||||
if idx > 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<<i16(16)
|
||||
}
|
||||
|
||||
// return Type idx of TypeSymbol & specify if ptr (nr_muls)
|
||||
[inline]
|
||||
pub fn new_type_ptr(idx, nr_muls int) Type {
|
||||
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 << 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<<i16(16) | nr_muls
|
||||
}
|
||||
|
||||
// true if the type of unresolved expression
|
||||
[inline]
|
||||
pub fn type_is_unresolved(t Type) bool {
|
||||
return type_idx(t) < 0
|
||||
return type_idx(t) < 0
|
||||
}
|
||||
|
||||
pub const (
|
||||
void_type = new_type(void_type_idx)
|
||||
voidptr_type = new_type(voidptr_type_idx)
|
||||
byteptr_type = new_type(byteptr_type_idx)
|
||||
charptr_type = new_type(charptr_type_idx)
|
||||
i8_type = new_type(i8_type_idx)
|
||||
int_type = new_type(int_type_idx)
|
||||
i16_type = new_type(i16_type_idx)
|
||||
i64_type = new_type(i64_type_idx)
|
||||
byte_type = new_type(byte_type_idx)
|
||||
u16_type = new_type(u16_type_idx)
|
||||
u32_type = new_type(u32_type_idx)
|
||||
u64_type = new_type(u64_type_idx)
|
||||
f32_type = new_type(f32_type_idx)
|
||||
f64_type = new_type(f64_type_idx)
|
||||
char_type = new_type(char_type_idx)
|
||||
bool_type = new_type(bool_type_idx)
|
||||
string_type = new_type(string_type_idx)
|
||||
array_type = new_type(array_type_idx)
|
||||
map_type = new_type(map_type_idx)
|
||||
void_type = new_type(void_type_idx)
|
||||
voidptr_type = new_type(voidptr_type_idx)
|
||||
byteptr_type = new_type(byteptr_type_idx)
|
||||
charptr_type = new_type(charptr_type_idx)
|
||||
i8_type = new_type(i8_type_idx)
|
||||
int_type = new_type(int_type_idx)
|
||||
i16_type = new_type(i16_type_idx)
|
||||
i64_type = new_type(i64_type_idx)
|
||||
byte_type = new_type(byte_type_idx)
|
||||
u16_type = new_type(u16_type_idx)
|
||||
u32_type = new_type(u32_type_idx)
|
||||
u64_type = new_type(u64_type_idx)
|
||||
f32_type = new_type(f32_type_idx)
|
||||
f64_type = new_type(f64_type_idx)
|
||||
char_type = new_type(char_type_idx)
|
||||
bool_type = new_type(bool_type_idx)
|
||||
string_type = new_type(string_type_idx)
|
||||
array_type = new_type(array_type_idx)
|
||||
map_type = new_type(map_type_idx)
|
||||
none_type = new_type(none_type_idx)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue