cgen: unwrapped optionals

pull/4033/head
Alexander Medvednikov 2020-03-15 08:18:42 +01:00
parent 8d19ba9195
commit 8a8f50a6a0
5 changed files with 31 additions and 3 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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;
}

View File

@ -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
}

View File

@ -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 {