char name_buf[256];
fori (i, 0, 256) name_buf[i] = 0;
+
+ // Special case for `? T`
+ if (cs_type->Struct.constructed_from == builtin_optional_type) {
+ strncat(name_buf, "? ", 255);
+ strncat(name_buf, type_get_name(cs_type->Struct.poly_sln[0].type), 255);
+
+ return bh_aprintf(global_heap_allocator, "%s", name_buf);
+ }
+
+
strncat(name_buf, ps_type->name, 255);
strncat(name_buf, "(", 255);
bh_arr_each(AstPolySolution, ptype, cs_type->Struct.poly_sln) {
Type* cs_type = type_build_from_ast(context.ast_alloc, (AstType *) concrete_struct);
if (!cs_type) return NULL;
+ cs_type->Struct.constructed_from = (AstType *) ps_type;
+
if (cs_type->Struct.poly_sln == NULL) cs_type->Struct.poly_sln = bh_arr_copy(global_heap_allocator, slns);
if (cs_type->Struct.name == NULL) cs_type->Struct.name = build_poly_struct_name(ps_type, cs_type);
the type will be inferred from the parameter type.
"""
make :: #match #locked {
- ((x: $T) => Optional(T).{ has_value = true, value = x }),
- ($T: type_expr, x: T) => (Optional(T).{ has_value = true, value = x })
+ ((x: $T) => (?T).{ has_value = true, value = x }),
+ ($T: type_expr, x: T) => ((?T).{ has_value = true, value = x })
}
#doc """
is mostly useless, because you can use `.{}` in type inferred
places to avoid having to specify the type.
"""
- empty :: macro (T: type_expr) => Optional(T).{};
+ empty :: macro (T: type_expr) => (?T).{};
#doc """
Extracts the value from the Optional, or uses a default if
no value is present.
"""
- value_or :: (o: Optional, default: o.Value_Type) -> o.Value_Type {
+ value_or :: (o: ?$T, default: T) -> T {
if !o.has_value do return default;
return o.value;
}
#doc "Clears the value in the Optional, zeroing the memory of the value."
- reset :: (o: ^Optional) {
+ reset :: (o: ^?$T) {
o.has_value = false;
- core.memory.set(^o.value, 0, sizeof o.Value_Type);
+ core.memory.set(^o.value, 0, sizeof T);
}
#doc "Sets the value in the Optional."
- set :: (o: ^Optional, value: o.Value_Type) {
+ set :: (o: ^?$T, value: T) {
o.has_value = true;
o.value = value;
}
#doc "Monadic chaining operation."
- and_then :: (o: Optional($T), transform: (T) -> Optional($R)) -> Optional(R) {
- if !o.has_value do return .{ false };
+ and_then :: (o: ?$T, transform: (T) -> ?$R) -> ?R {
+ if !o.has_value do return .{};
return transform(o.value);
}
#doc "Changes the value inside the optional, if present."
- transform :: (o: Optional($T), transform: (T) -> $R) -> Optional(R) {
- if !o.has_value do return .{ false };
+ transform :: (o: ?$T, transform: (T) -> $R) -> ?R {
+ if !o.has_value do return .{};
return Optional.make(transform(o.value));
}
Like `value_or`, but instead of providing a value, you
provide a function to generate a value.
"""
- or_else :: (o: Optional($T), generate: () -> Optional(T)) -> Optional(T) {
+ or_else :: (o: ?$T, generate: () -> ?T) -> ?T {
if o.has_value do return o;
return generate();
}
If not, an assertion is thrown and the context's assert
handler must take care of it.
"""
- unwrap :: (o: Optional) -> o.Value_Type {
+ unwrap :: (o: ?$T) -> T {
if o.has_value do return o.value;
assert(false, "Unwrapping empty Optional.");
}
- or_return :: macro (o: Optional($T)) -> T {
+ or_return :: macro (o: ?$T) -> T {
value := o;
if value.has_value do return value.value;
return #from_enclosing .{};
}
- hash :: (o: Optional($T/core.hash.Hashable)) -> u32 {
+ hash :: (o: ?$T/core.hash.Hashable) -> u32 {
if !o.has_value do return 0;
return core.hash.to_u32(o.value);
}
}
-#operator == (o1, o2: Optional($T)) -> bool {
+#operator == (o1, o2: ?$T) -> bool {
if o1.has_value != o2.has_value do return false;
if !o1.has_value do return true;
return o1.value == o2.value;
}
#overload
-__implicit_bool_cast :: macro (o: Optional) => o.has_value;
+__implicit_bool_cast :: macro (o: ?$T) => o.has_value;