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
|
typ: typ
|
||||||
is_optional: table.type_is_optional(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
|
return typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// second use, already resovled in unresovled branch
|
// second use, already resovled in unresolved branch
|
||||||
else if ident.kind == .constant {
|
else if ident.kind == .constant {
|
||||||
info := ident.info as ast.IdentVar
|
info := ident.info as ast.IdentVar
|
||||||
return info.typ
|
return info.typ
|
||||||
|
|
|
@ -21,6 +21,7 @@ mut:
|
||||||
is_assign_expr bool // inside left part of assign expr (for array_set(), etc)
|
is_assign_expr bool // inside left part of assign expr (for array_set(), etc)
|
||||||
is_array_set bool
|
is_array_set bool
|
||||||
is_amp bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&byte(0)` etc
|
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 {
|
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) {
|
if table.type_is_optional(t) {
|
||||||
styp = 'Option_' + styp
|
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
|
return styp
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,14 @@ struct User {
|
||||||
|
|
||||||
// multi return structs
|
// multi return structs
|
||||||
// end of definitions #endif
|
// end of definitions #endif
|
||||||
|
typedef Option Option_int;
|
||||||
|
Option_int get_opt();
|
||||||
void User_foo(User* u);
|
void User_foo(User* u);
|
||||||
|
|
||||||
|
Option_int get_opt() {
|
||||||
|
return opt_ok(& (int []) { 0 }, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
void User_foo(User* u) {
|
void User_foo(User* u) {
|
||||||
int age = u->age;
|
int age = u->age;
|
||||||
array_string zzz = array_repeat(new_array_from_c_array(1, 1, sizeof(string), (string[]){
|
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 = 10;
|
||||||
user.age++;
|
user.age++;
|
||||||
user.name = tos3("bob");
|
user.name = tos3("bob");
|
||||||
|
Option_int n = get_opt();
|
||||||
|
int a = /*opt*/(*(int*)n.data) + 3;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@ struct User {
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_opt() ?int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
fn (u &User) foo() {
|
fn (u &User) foo() {
|
||||||
age := u.age
|
age := u.age
|
||||||
zzz := [''].repeat(u.age)
|
zzz := [''].repeat(u.age)
|
||||||
|
@ -13,4 +17,8 @@ fn main() {
|
||||||
user.age = 10
|
user.age = 10
|
||||||
user.age++
|
user.age++
|
||||||
user.name = 'bob'
|
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))
|
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
|
// return extra info
|
||||||
[inline]
|
[inline]
|
||||||
pub fn type_extra(t Type) TypeExtra {
|
pub fn type_extra(t Type) TypeExtra {
|
||||||
|
|
Loading…
Reference in New Issue