cgen: unwrapped optionals
parent
8d19ba9195
commit
8a8f50a6a0
|
@ -727,10 +727,14 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
|
|||
typ: typ
|
||||
is_optional: table.type_is_optional(typ)
|
||||
}
|
||||
// unwrap optional (`println(x)`)
|
||||
if table.type_is_optional(typ) {
|
||||
return table.type_clear_extra(typ)
|
||||
}
|
||||
return typ
|
||||
}
|
||||
}
|
||||
// second use, already resovled in unresovled branch
|
||||
// second use, already resovled in unresolved branch
|
||||
else if ident.kind == .constant {
|
||||
info := ident.info as ast.IdentVar
|
||||
return info.typ
|
||||
|
|
|
@ -21,6 +21,7 @@ mut:
|
|||
is_assign_expr bool // inside left part of assign expr (for array_set(), etc)
|
||||
is_array_set bool
|
||||
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc
|
||||
optionals []string // to avoid duplicates TODO perf, use map
|
||||
}
|
||||
|
||||
pub fn cgen(files []ast.File, table &table.Table) string {
|
||||
|
@ -69,7 +70,10 @@ pub fn (g mut Gen) typ(t table.Type) string {
|
|||
}
|
||||
if table.type_is_optional(t) {
|
||||
styp = 'Option_' + styp
|
||||
g.definitions.writeln('typedef Option $styp;')
|
||||
if !(styp in g.optionals) {
|
||||
g.definitions.writeln('typedef Option $styp;')
|
||||
g.optionals << styp
|
||||
}
|
||||
}
|
||||
return styp
|
||||
}
|
||||
|
|
|
@ -5,9 +5,14 @@ struct User {
|
|||
|
||||
// multi return structs
|
||||
// end of definitions #endif
|
||||
|
||||
typedef Option Option_int;
|
||||
Option_int get_opt();
|
||||
void User_foo(User* u);
|
||||
|
||||
Option_int get_opt() {
|
||||
return opt_ok(& (int []) { 0 }, sizeof(int));
|
||||
}
|
||||
|
||||
void User_foo(User* u) {
|
||||
int age = u->age;
|
||||
array_string zzz = array_repeat(new_array_from_c_array(1, 1, sizeof(string), (string[]){
|
||||
|
@ -21,5 +26,7 @@ int main() {
|
|||
user.age = 10;
|
||||
user.age++;
|
||||
user.name = tos3("bob");
|
||||
Option_int n = get_opt();
|
||||
int a = /*opt*/(*(int*)n.data) + 3;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ struct User {
|
|||
name string
|
||||
}
|
||||
|
||||
fn get_opt() ?int {
|
||||
return 0
|
||||
}
|
||||
|
||||
fn (u &User) foo() {
|
||||
age := u.age
|
||||
zzz := [''].repeat(u.age)
|
||||
|
@ -13,4 +17,8 @@ fn main() {
|
|||
user.age = 10
|
||||
user.age++
|
||||
user.name = 'bob'
|
||||
n := get_opt() or {
|
||||
return
|
||||
}
|
||||
a := n + 3
|
||||
}
|
||||
|
|
|
@ -81,6 +81,11 @@ pub fn type_deref(t Type) Type {
|
|||
return (int(type_extra(t))<<24) | ((nr_muls - 1)<<16) | u16(type_idx(t))
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn type_clear_extra(t Type) Type {
|
||||
return type_set_extra(t, .unset)
|
||||
}
|
||||
|
||||
// return extra info
|
||||
[inline]
|
||||
pub fn type_extra(t Type) TypeExtra {
|
||||
|
|
Loading…
Reference in New Issue