From 043ea80fa9cc7479cdbd6e5461b1d01fdefb8afe Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Sun, 22 Mar 2020 23:36:27 +1100 Subject: [PATCH] checker: comptime if expr/stmts & type check fixes --- vlib/builtin/builtin_nix.v | 14 +++++++------- vlib/v/checker/checker.v | 7 +++++-- vlib/v/gen/cgen.v | 4 ++-- vlib/v/table/atypes.v | 8 +++++++- vlib/v/table/table.v | 31 ++++++++++++------------------- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/vlib/builtin/builtin_nix.v b/vlib/builtin/builtin_nix.v index d040234be4..42dd54b970 100644 --- a/vlib/builtin/builtin_nix.v +++ b/vlib/builtin/builtin_nix.v @@ -69,7 +69,7 @@ fn print_backtrace_skipping_top_frames_nix(xskipframes int) bool { fn print_backtrace_skipping_top_frames_mac(skipframes int) bool { $if macos { buffer := [100]byteptr - nr_ptrs := C.backtrace(buffer, 100) + nr_ptrs := backtrace(buffer, 100) backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 1) } return true @@ -78,8 +78,8 @@ fn print_backtrace_skipping_top_frames_mac(skipframes int) bool { fn print_backtrace_skipping_top_frames_freebsd(skipframes int) bool { $if freebsd { buffer := [100]byteptr - nr_ptrs := C.backtrace(buffer, 100) - C.backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 1) + nr_ptrs := backtrace(buffer, 100) + backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 1) } return true } @@ -93,11 +93,11 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { // backtrace is not available on Android. $if glibc { buffer := [100]byteptr - nr_ptrs := C.backtrace(buffer, 100) + nr_ptrs := backtrace(buffer, 100) nr_actual_frames := nr_ptrs - skipframes mut sframes := []string - //////csymbols := C.backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames) - csymbols := C.backtrace_symbols(&buffer[skipframes], nr_actual_frames) + //////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames) + csymbols := backtrace_symbols(&buffer[skipframes], nr_actual_frames) for i in 0 .. nr_actual_frames { sframes << tos2(csymbols[i]) } @@ -131,7 +131,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { output = output.replace(' (discriminator', ': (d.') println('${output:-46s} | ${addr:14s} | $beforeaddr') } - // C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_actual_frames, 1) + // backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_actual_frames, 1) return true } $else { println('backtrace_symbols_fd is missing, so printing backtraces is not available.\n') diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 4b1d0d0687..954d08476c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -529,7 +529,10 @@ fn (c mut Checker) stmt(node ast.Stmt) { c.expected_type = table.void_type } // ast.Attr {} - // ast.CompIf {} + ast.CompIf { + c.expr(it.cond) + c.stmts(it.stmts) + } ast.ConstDecl { for i, expr in it.exprs { mut field := it.fields[i] @@ -990,7 +993,7 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { index_type := c.expr(node.index) index_type_sym := c.table.get_type_symbol(index_type) // println('index expr left=$typ_sym.name $node.pos.line_nr') - if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_idxs) && index_type_sym.kind != .enum_) { + if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) && index_type_sym.kind != .enum_) { c.error('non-integer index `$index_type_sym.name` (array type `$typ_sym.name`)', node.pos) } else if typ_sym.kind == .map && table.type_idx(index_type) != table.string_type_idx { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 324accc04c..409e7699b8 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -269,9 +269,9 @@ fn (g mut Gen) stmt(node ast.Stmt) { } ast.CompIf { g.writeln('//#ifdef ') - // g.expr(it.cond) + g.expr(it.cond) // println('comp if stmts $g.file.path:$it.pos.line_nr') - // g.stmts(it.stmts) + g.stmts(it.stmts) // println('done') g.writeln('//#endif') } diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 3c58c73873..5940e8c594 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -175,7 +175,8 @@ pub const ( ) pub const ( - number_idxs = [int_type_idx, byte_type_idx, u16_type_idx, i16_type_idx, i64_type_idx, u32_type_idx, u64_type_idx] + number_type_idxs = [int_type_idx, byte_type_idx, u16_type_idx, i16_type_idx, i64_type_idx, u32_type_idx, u64_type_idx, f32_type_idx, f64_type_idx] + pointer_type_idxs = [voidptr_type_idx, byteptr_type_idx, charptr_type_idx] ) pub const ( @@ -425,6 +426,11 @@ pub fn (t mut Table) register_builtin_type_symbols() { }) } +[inline] +pub fn (t &TypeSymbol) is_pointer() bool { + return t.kind in [.byteptr, .charptr, .voidptr] +} + [inline] pub fn (t &TypeSymbol) is_int() bool { return t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64] diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 732a5719ad..51aa6e44cd 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -449,39 +449,32 @@ pub fn (t &Table) value_type(typ Type) Type { } pub fn (t &Table) check(got, expected Type) bool { - got_type_sym := t.get_type_symbol(got) - exp_type_sym := t.get_type_symbol(expected) got_idx := type_idx(got) exp_idx := type_idx(expected) // got_is_ptr := type_is_ptr(got) exp_is_ptr := type_is_ptr(expected) // println('check: $got_type_sym.name, $exp_type_sym.name') - if got_type_sym.kind == .none_ { + // # NOTE: use idxs here, and symbols below for perf + if got_idx == none_type_idx { // TODO return true } - if exp_type_sym.kind == .voidptr { - return true - } - // if got_type_sym.kind == .array_fixed { - // return true - // } - if got_type_sym.kind in [.voidptr, .byteptr, .charptr, .int] && exp_type_sym.kind in [.voidptr, .byteptr, .charptr] { - return true - } - if got_type_sym.is_int() && exp_type_sym.is_int() { - return true - } // allow pointers to be initialized with 0. TODO: use none instead if exp_is_ptr && got_idx == int_type_idx { return true } - // allow enum value to be used as int - if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() && got_type_sym.kind == .enum_) { + if exp_idx == voidptr_type_idx || got_idx == voidptr_type_idx { return true } - // TODO - if got_type_sym.is_number() && exp_type_sym.is_number() { + if (exp_idx in pointer_type_idxs || exp_idx in number_type_idxs) // + && (got_idx in pointer_type_idxs || got_idx in number_type_idxs) { + return true + } + // # NOTE: use symbols from this point on for perf + got_type_sym := t.get_type_symbol(got) + exp_type_sym := t.get_type_symbol(expected) + // allow enum value to be used as int + if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() && got_type_sym.kind == .enum_) { return true } // TODO: actually check for & handle pointers with name_expr