cgen: fix optional pointers
parent
54c382f6f1
commit
fecf4ddf65
|
@ -18,7 +18,6 @@ const (
|
|||
'vlib/v/tests/enum_bitfield_test.v',
|
||||
'vlib/v/tests/fixed_array_test.v',
|
||||
'vlib/v/tests/num_lit_call_method_test.v',
|
||||
'vlib/v/tests/option_test.v',
|
||||
'vlib/v/tests/pointers_test.v',
|
||||
'vlib/v/tests/string_interpolation_variadic_test.v',
|
||||
'vlib/v/tests/type_test.v',
|
||||
|
|
|
@ -363,7 +363,7 @@ pub fn sys_munmap(addr voidptr, len u64) errno {
|
|||
}
|
||||
|
||||
// 22 sys_pipe int *filedes
|
||||
pub fn sys_pipe(filedes intptr) errno {
|
||||
pub fn sys_pipe(filedes &int) errno {
|
||||
return errno(sys_call1(22, u64(filedes)))
|
||||
}
|
||||
|
||||
|
@ -415,7 +415,7 @@ pub fn sys_getuid() int {
|
|||
}
|
||||
|
||||
// 247 sys_waitid int which pid_t upid struct siginfo *infop int options struct rusage *ru
|
||||
pub fn sys_waitid (which wi_which, pid int, infop intptr, options wp_sys, ru voidptr) errno {
|
||||
pub fn sys_waitid (which wi_which, pid int, infop &int, options wp_sys, ru voidptr) errno {
|
||||
return errno(sys_call5(247, u64(which), u64(pid), u64(infop), u64(options), u64(ru)))
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ pub fn mm_alloc(size u64) (byteptr, errno) {
|
|||
|
||||
a, e := sys_mmap(0, n_bytes, mem_prot, mem_flags, -1, 0)
|
||||
if e == .enoerror {
|
||||
mut ap := intptr(a)
|
||||
mut ap := &int(a)
|
||||
*ap = pages
|
||||
return byteptr(a+4), e
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ pub fn mm_alloc(size u64) (byteptr, errno) {
|
|||
}
|
||||
|
||||
pub fn mm_free(addr byteptr) errno {
|
||||
ap := intptr(addr-4)
|
||||
ap := &int(addr-4)
|
||||
size := u64(*ap) * u64(linux_mem.page_size)
|
||||
|
||||
return sys_munmap(ap, size)
|
||||
|
|
|
@ -228,6 +228,24 @@ pub fn (mut g Gen) write_typeof_functions() {
|
|||
|
||||
// V type to C type
|
||||
pub fn (mut g Gen) typ(t table.Type) string {
|
||||
mut styp := g.base_typ(t)
|
||||
if table.type_is(t, .optional) {
|
||||
// Register an optional
|
||||
styp = 'Option_' + styp
|
||||
if table.type_is_ptr(t) {
|
||||
styp = styp.replace('*', '_ptr')
|
||||
}
|
||||
if !(styp in g.optionals) {
|
||||
// println(styp)
|
||||
x := styp // .replace('*', '_ptr') // handle option ptrs
|
||||
g.typedefs2.writeln('typedef Option $x;')
|
||||
g.optionals << styp
|
||||
}
|
||||
}
|
||||
return styp
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) base_typ(t table.Type) string {
|
||||
nr_muls := table.type_nr_muls(t)
|
||||
sym := g.table.get_type_symbol(t)
|
||||
mut styp := sym.name.replace('.', '__')
|
||||
|
@ -243,19 +261,6 @@ pub fn (mut g Gen) typ(t table.Type) string {
|
|||
}
|
||||
}
|
||||
}
|
||||
if table.type_is(t, .optional) {
|
||||
// Register an optional
|
||||
styp = 'Option_' + styp
|
||||
if table.type_is_ptr(t) {
|
||||
styp = styp.replace('*', '_ptr')
|
||||
}
|
||||
if !(styp in g.optionals) {
|
||||
// println(styp)
|
||||
x := styp // .replace('*', '_ptr') // handle option ptrs
|
||||
g.typedefs2.writeln('typedef Option $x;')
|
||||
g.optionals << styp
|
||||
}
|
||||
}
|
||||
return styp
|
||||
}
|
||||
|
||||
|
@ -733,13 +738,11 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
// multi return
|
||||
mut or_stmts := []ast.Stmt
|
||||
mut return_type := table.void_type
|
||||
match assign_stmt.right[0] {
|
||||
ast.CallExpr {
|
||||
if assign_stmt.right[0] is ast.CallExpr {
|
||||
it := assign_stmt.right[0] as ast.CallExpr
|
||||
or_stmts = it.or_block.stmts
|
||||
return_type = it.return_type
|
||||
}
|
||||
else {}
|
||||
}
|
||||
is_optional := table.type_is(return_type, .optional)
|
||||
mr_var_name := 'mr_$assign_stmt.pos.pos'
|
||||
mr_styp := g.typ(return_type)
|
||||
|
@ -762,8 +765,8 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
}
|
||||
g.expr(ident)
|
||||
if is_optional {
|
||||
mr_styp2 := mr_styp[7..] // remove Option_
|
||||
g.writeln(' = (*(${mr_styp2}*)${mr_var_name}.data).arg$i;')
|
||||
mr_base_styp := g.base_typ(return_type)
|
||||
g.writeln(' = (*(${mr_base_styp}*)${mr_var_name}.data).arg$i;')
|
||||
} else {
|
||||
g.writeln(' = ${mr_var_name}.arg$i;')
|
||||
}
|
||||
|
@ -819,7 +822,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
if is_decl {
|
||||
g.write('$styp ')
|
||||
}
|
||||
g.expr(ident)
|
||||
g.ident(ident)
|
||||
if g.autofree && right_sym.kind in [.array, .string] {
|
||||
if g.gen_clone_assignment(val, right_sym, true) {
|
||||
g.writeln(';')
|
||||
|
@ -1554,22 +1557,19 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||
g.write('_const_')
|
||||
}
|
||||
name := c_name(node.name)
|
||||
// TODO `is`
|
||||
match node.info {
|
||||
ast.IdentVar {
|
||||
if node.info is ast.IdentVar {
|
||||
ident_var := node.info as ast.IdentVar
|
||||
// x ?int
|
||||
// `x = 10` => `x.data = 10` (g.right_is_opt == false)
|
||||
// `x = new_opt()` => `x = new_opt()` (g.right_is_opt == true)
|
||||
// `println(x)` => `println(*(int*)x.data)`
|
||||
if it.is_optional && !(g.is_assign_lhs && g.right_is_opt) {
|
||||
if ident_var.is_optional && !(g.is_assign_lhs && g.right_is_opt) {
|
||||
g.write('/*opt*/')
|
||||
styp := g.typ(it.typ)[7..] // Option_int => int TODO perf?
|
||||
styp := g.base_typ(ident_var.typ)
|
||||
g.write('(*($styp*)${name}.data)')
|
||||
return
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
g.write(name)
|
||||
}
|
||||
|
||||
|
@ -1821,14 +1821,12 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
|||
g.write(' ')
|
||||
// typ_sym := g.table.get_type_symbol(g.fn_decl.return_type)
|
||||
// mr_info := typ_sym.info as table.MultiReturn
|
||||
mut styp := g.typ(g.fn_decl.return_type)
|
||||
mut styp := ''
|
||||
if fn_return_is_optional { // && !table.type_is(node.types[0], .optional) && node.types[0] !=
|
||||
styp = styp[7..] // remove 'Option_'
|
||||
mut x := styp
|
||||
if x.ends_with('_ptr') {
|
||||
x = x.replace('_ptr', '*')
|
||||
}
|
||||
g.write('opt_ok(&($x/*X*/[]) { ')
|
||||
styp = g.base_typ(g.fn_decl.return_type)
|
||||
g.write('opt_ok(&($styp/*X*/[]) { ')
|
||||
} else {
|
||||
styp = g.typ(g.fn_decl.return_type)
|
||||
}
|
||||
g.write('($styp){')
|
||||
for i, expr in node.exprs {
|
||||
|
@ -1864,14 +1862,10 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
|||
else {}
|
||||
}
|
||||
if !is_none && !is_error {
|
||||
styp := g.typ(g.fn_decl.return_type)[7..] // remove 'Option_'
|
||||
mut x := styp
|
||||
if x.ends_with('_ptr') {
|
||||
x = x.replace('_ptr', '*')
|
||||
}
|
||||
g.write('/*:)$return_sym.name*/opt_ok(&($x[]) { ')
|
||||
styp := g.base_typ(g.fn_decl.return_type)
|
||||
g.write('/*:)$return_sym.name*/opt_ok(&($styp[]) { ')
|
||||
g.expr(node.exprs[0])
|
||||
g.writeln(' }, sizeof($x));')
|
||||
g.writeln(' }, sizeof($styp));')
|
||||
return
|
||||
}
|
||||
// g.write('/*OPTIONAL*/')
|
||||
|
@ -2454,8 +2448,7 @@ fn (mut g Gen) insert_before(s string) {
|
|||
// to access its fields (`.ok`, `.error` etc)
|
||||
// `os.cp(...)` => `Option bool tmp = os__cp(...); if (!tmp.ok) { ... }`
|
||||
fn (mut g Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Type) {
|
||||
mr_styp := g.typ(return_type)
|
||||
mr_styp2 := mr_styp[7..] // remove Option_
|
||||
mr_styp := g.base_typ(return_type)
|
||||
g.writeln(';') // or')
|
||||
g.writeln('if (!${var_name}.ok) {')
|
||||
g.writeln('\tstring err = ${var_name}.v_error;')
|
||||
|
@ -2466,7 +2459,7 @@ fn (mut g Gen) or_block(var_name string, stmts []ast.Stmt, return_type table.Typ
|
|||
for i, stmt in stmts {
|
||||
if i == stmts.len - 1 {
|
||||
g.indent--
|
||||
g.write('\t*(${mr_styp2}*) ${var_name}.data = ')
|
||||
g.write('\t*(${mr_styp}*) ${var_name}.data = ')
|
||||
}
|
||||
g.stmt(stmt)
|
||||
}
|
||||
|
|
|
@ -335,7 +335,6 @@ typedef uint32_t rune;
|
|||
typedef float f32;
|
||||
typedef double f64;
|
||||
typedef unsigned char* byteptr;
|
||||
typedef int* intptr;
|
||||
typedef void* voidptr;
|
||||
typedef char* charptr;
|
||||
typedef struct array array;
|
||||
|
|
|
@ -184,7 +184,8 @@ fn (g mut JsGen) to_js_typ(typ string) string {
|
|||
}
|
||||
'charptr' {
|
||||
styp = 'string'
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if typ.starts_with('array_') {
|
||||
styp = g.to_js_typ(typ.replace('array_', '')) + '[]'
|
||||
} else if typ.starts_with('map_') {
|
||||
|
|
|
@ -38,16 +38,14 @@ fn ret_none() ?int {
|
|||
}
|
||||
|
||||
fn test_option_for_base_type_without_variable() {
|
||||
val := err_call(true) or {
|
||||
panic(err)
|
||||
mut val := err_call(true) or {
|
||||
assert false
|
||||
0
|
||||
}
|
||||
assert val == 42
|
||||
println('hm')
|
||||
val2 := ret_none() or {
|
||||
println('yep')
|
||||
val = ret_none() or {
|
||||
return
|
||||
}
|
||||
println('$val2 should have been `none`')
|
||||
assert false
|
||||
// This is invalid:
|
||||
// x := 5 or {
|
||||
|
@ -60,7 +58,6 @@ fn test_if_opt() {
|
|||
assert val == 42
|
||||
}
|
||||
assert 1 == 1
|
||||
println('nice')
|
||||
}
|
||||
|
||||
fn for_opt_default() ?string {
|
||||
|
@ -135,24 +132,19 @@ fn test_opt_field() {
|
|||
fn opt_ptr(a &int) ?&int {
|
||||
if isnil(a) {
|
||||
return none
|
||||
}
|
||||
//
|
||||
else {
|
||||
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
fn test_opt_ptr() {
|
||||
a := 3
|
||||
r1 := opt_ptr(&a) or {
|
||||
mut r := opt_ptr(&a) or {
|
||||
&int(0)
|
||||
}
|
||||
assert r1 == &a
|
||||
r2 := opt_ptr(&int(0)) or {
|
||||
assert r == &a
|
||||
r = opt_ptr(&int(0)) or {
|
||||
return
|
||||
}
|
||||
println('`$r2` should be none')
|
||||
assert false
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue