1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: comptime if expr/stmts & type check fixes

This commit is contained in:
Joe Conigliaro 2020-03-22 23:36:27 +11:00
parent cf8776ac71
commit 043ea80fa9
5 changed files with 33 additions and 31 deletions

View File

@ -69,7 +69,7 @@ fn print_backtrace_skipping_top_frames_nix(xskipframes int) bool {
fn print_backtrace_skipping_top_frames_mac(skipframes int) bool { fn print_backtrace_skipping_top_frames_mac(skipframes int) bool {
$if macos { $if macos {
buffer := [100]byteptr buffer := [100]byteptr
nr_ptrs := C.backtrace(buffer, 100) nr_ptrs := backtrace(buffer, 100)
backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 1) backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 1)
} }
return true 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 { fn print_backtrace_skipping_top_frames_freebsd(skipframes int) bool {
$if freebsd { $if freebsd {
buffer := [100]byteptr buffer := [100]byteptr
nr_ptrs := C.backtrace(buffer, 100) nr_ptrs := backtrace(buffer, 100)
C.backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 1) backtrace_symbols_fd(&buffer[skipframes], nr_ptrs - skipframes, 1)
} }
return true return true
} }
@ -93,11 +93,11 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
// backtrace is not available on Android. // backtrace is not available on Android.
$if glibc { $if glibc {
buffer := [100]byteptr buffer := [100]byteptr
nr_ptrs := C.backtrace(buffer, 100) nr_ptrs := backtrace(buffer, 100)
nr_actual_frames := nr_ptrs - skipframes nr_actual_frames := nr_ptrs - skipframes
mut sframes := []string mut sframes := []string
//////csymbols := C.backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames) //////csymbols := backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames)
csymbols := C.backtrace_symbols(&buffer[skipframes], nr_actual_frames) csymbols := backtrace_symbols(&buffer[skipframes], nr_actual_frames)
for i in 0 .. nr_actual_frames { for i in 0 .. nr_actual_frames {
sframes << tos2(csymbols[i]) sframes << tos2(csymbols[i])
} }
@ -131,7 +131,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
output = output.replace(' (discriminator', ': (d.') output = output.replace(' (discriminator', ': (d.')
println('${output:-46s} | ${addr:14s} | $beforeaddr') 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 return true
} $else { } $else {
println('backtrace_symbols_fd is missing, so printing backtraces is not available.\n') println('backtrace_symbols_fd is missing, so printing backtraces is not available.\n')

View File

@ -529,7 +529,10 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.expected_type = table.void_type c.expected_type = table.void_type
} }
// ast.Attr {} // ast.Attr {}
// ast.CompIf {} ast.CompIf {
c.expr(it.cond)
c.stmts(it.stmts)
}
ast.ConstDecl { ast.ConstDecl {
for i, expr in it.exprs { for i, expr in it.exprs {
mut field := it.fields[i] 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 := c.expr(node.index)
index_type_sym := c.table.get_type_symbol(index_type) index_type_sym := c.table.get_type_symbol(index_type)
// println('index expr left=$typ_sym.name $node.pos.line_nr') // 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) 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 { else if typ_sym.kind == .map && table.type_idx(index_type) != table.string_type_idx {

View File

@ -269,9 +269,9 @@ fn (g mut Gen) stmt(node ast.Stmt) {
} }
ast.CompIf { ast.CompIf {
g.writeln('//#ifdef ') g.writeln('//#ifdef ')
// g.expr(it.cond) g.expr(it.cond)
// println('comp if stmts $g.file.path:$it.pos.line_nr') // println('comp if stmts $g.file.path:$it.pos.line_nr')
// g.stmts(it.stmts) g.stmts(it.stmts)
// println('done') // println('done')
g.writeln('//#endif') g.writeln('//#endif')
} }

View File

@ -175,7 +175,8 @@ pub const (
) )
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 ( 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] [inline]
pub fn (t &TypeSymbol) is_int() bool { pub fn (t &TypeSymbol) is_int() bool {
return t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64] return t.kind in [.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64]

View File

@ -449,39 +449,32 @@ pub fn (t &Table) value_type(typ Type) Type {
} }
pub fn (t &Table) check(got, expected Type) bool { 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) got_idx := type_idx(got)
exp_idx := type_idx(expected) exp_idx := type_idx(expected)
// got_is_ptr := type_is_ptr(got) // got_is_ptr := type_is_ptr(got)
exp_is_ptr := type_is_ptr(expected) exp_is_ptr := type_is_ptr(expected)
// println('check: $got_type_sym.name, $exp_type_sym.name') // 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 // TODO
return true 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 // allow pointers to be initialized with 0. TODO: use none instead
if exp_is_ptr && got_idx == int_type_idx { if exp_is_ptr && got_idx == int_type_idx {
return true return true
} }
// allow enum value to be used as int if exp_idx == voidptr_type_idx || got_idx == voidptr_type_idx {
if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() && got_type_sym.kind == .enum_) {
return true return true
} }
// TODO if (exp_idx in pointer_type_idxs || exp_idx in number_type_idxs) //
if got_type_sym.is_number() && exp_type_sym.is_number() { && (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 return true
} }
// TODO: actually check for & handle pointers with name_expr // TODO: actually check for & handle pointers with name_expr