aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-02-10 14:59:18 +0000
committerGinger Bill <bill@gingerbill.org>2017-02-10 14:59:18 +0000
commitf18ae89931526df578956e63dfab288920b59873 (patch)
tree2cf3bc1afa048b879d974f983c1015580684e084 /src
parent454d0b5cf5b109fda01b3380b1fab0434d7ff51d (diff)
Remove Maybe type; Enum `names`
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c172
-rw-r--r--src/checker.c99
-rw-r--r--src/entity.c1
-rw-r--r--src/ir.c160
-rw-r--r--src/ir_print.c21
-rw-r--r--src/parser.c31
-rw-r--r--src/tokenizer.c16
-rw-r--r--src/types.c91
8 files changed, 237 insertions, 354 deletions
diff --git a/src/check_expr.c b/src/check_expr.c
index 04f246532..3a4f57ea8 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -167,14 +167,6 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) {
return 1;
}
- if (is_type_maybe(dst)) {
- Type *elem = base_type(dst)->Maybe.elem;
- if (are_types_identical(elem, s)) {
- return 1;
- }
- return -1;
- }
-
if (check_is_assignable_to_using_subtype(operand->type, type)) {
return 4;
}
@@ -743,7 +735,13 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
} else if (str_eq(name, str_lit("max_value"))) {
error_node(field, "`max_value` is a reserved identifier for enumerations");
continue;
- }
+ } else if (str_eq(name, str_lit("names"))) {
+ error_node(field, "`names` is a reserved identifier for enumerations");
+ continue;
+ }/* else if (str_eq(name, str_lit("base_type"))) {
+ error_node(field, "`base_type` is a reserved identifier for enumerations");
+ continue;
+ } */
if (compare_exact_values(Token_Gt, min_value, iota)) {
min_value = iota;
@@ -779,6 +777,11 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
enum_type->Record.enum_max_value = make_entity_constant(c->allocator, c->context.scope,
make_token_ident(str_lit("max_value")), constant_type, max_value);
+ enum_type->Record.enum_names = make_entity_field(c->allocator, c->context.scope,
+ make_token_ident(str_lit("names")), t_string_slice, false, 0);
+ enum_type->Record.enum_names->Variable.is_immutable = true;
+ enum_type->Record.enum_names->flags |= EntityFlag_EnumField;
+
gb_temp_arena_memory_end(tmp);
}
@@ -909,7 +912,7 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
}
-void check_ident (Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint) {
+void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint) {
GB_ASSERT(n->kind == AstNode_Ident);
o->mode = Addressing_Invalid;
o->expr = n;
@@ -1285,12 +1288,6 @@ Type *check_type_extra(Checker *c, AstNode *e, Type *named_type) {
goto end;
case_end;
- case_ast_node(mt, MaybeType, e);
- Type *elem = check_type(c, mt->type);
- type = make_type_maybe(c->allocator, elem);
- goto end;
- case_end;
-
case_ast_node(at, ArrayType, e);
if (at->count != NULL) {
Type *elem = check_type_extra(c, at->elem, NULL);
@@ -1689,29 +1686,6 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
o->type = make_type_pointer(c->allocator, o->type);
return;
}
-
- case Token_Maybe: { // Make maybe
- Type *t = default_type(o->type);
-
- if (o->mode == Addressing_Type) {
- o->type = make_type_pointer(c->allocator, t);
- return;
- }
-
- if (!is_operand_value(*o) || is_type_untyped(t)) {
- if (ast_node_expect(node, AstNode_UnaryExpr)) {
- ast_node(ue, UnaryExpr, node);
- gbString str = expr_to_string(ue->expr);
- error(op, "Cannot convert `%s` to a maybe", str);
- gb_string_free(str);
- }
- o->mode = Addressing_Invalid;
- return;
- }
- o->mode = Addressing_Value;
- o->type = make_type_maybe(c->allocator, t);
- return;
- }
}
if (!check_unary_op(c, o, op)) {
@@ -2436,13 +2410,6 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
}
break;
- case Type_Maybe:
- if (is_type_untyped_nil(operand->type)) {
- // Okay
- } else if (level == 0) {
- goto error;
- }
-
default:
if (!is_type_untyped_nil(operand->type) || !type_has_nil(target_type)) {
goto error;
@@ -2545,7 +2512,14 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
check_op_expr = false;
entity = scope_lookup_entity(e->ImportName.scope, sel_name);
- if (entity == NULL) {
+ bool is_declared = entity != NULL;
+ if (entity->kind == Entity_Builtin) {
+ is_declared = false;
+ }
+ if (entity->scope->is_global && !e->ImportName.scope->is_global) {
+ is_declared = false;
+ }
+ if (!is_declared) {
error_node(op_expr, "`%.*s` is not declared by `%.*s`", LIT(sel_name), LIT(name));
goto error;
}
@@ -2638,6 +2612,11 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
if (entity == NULL && selector->kind == AstNode_Ident) {
sel = lookup_field(c->allocator, operand->type, selector->Ident.string, operand->mode == Addressing_Type);
entity = sel.entity;
+
+ // NOTE(bill): Add enum type info needed for fields like `names`
+ if (entity != NULL && (entity->flags&EntityFlag_EnumField)) {
+ add_type_info_type(c, operand->type);
+ }
}
if (entity == NULL && selector->kind == AstNode_BasicLit) {
if (is_type_struct(operand->type) || is_type_tuple(operand->type)) {
@@ -2699,6 +2678,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
}
+
add_entity_use(c, selector, entity);
switch (entity->kind) {
@@ -2755,10 +2735,11 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
if (err) {
- ast_node(proc, Ident, ce->proc);
- error(ce->close, "`%s` arguments for `%.*s`, expected %td, got %td",
- err, LIT(proc->string),
+ gbString expr = expr_to_string(ce->proc);
+ error(ce->close, "`%s` arguments for `%s`, expected %td, got %td",
+ err, expr,
bp->arg_count, ce->args.count);
+ gb_string_free(expr);
return false;
}
}
@@ -2852,19 +2833,12 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case BuiltinProc_reserve: {
- // reserve :: proc(^[dynamic]Type, count: int) {
- // reserve :: proc(^map[Key]Type, count: int) {
+ // reserve :: proc([dynamic]Type, count: int) {
+ // reserve :: proc(map[Key]Type, count: int) {
Type *type = operand->type;
- if (!is_type_pointer(type)) {
- gbString str = type_to_string(type);
- error_node(operand->expr, "Expected a pointer, got `%s`", str);
- gb_string_free(str);
- return false;
- }
- type = type_deref(type);
if (!is_type_dynamic_array(type) && !is_type_dynamic_map(type)) {
gbString str = type_to_string(type);
- error_node(operand->expr, "Expected a pointer to a dynamic array or dynamic map, got `%s`", str);
+ error_node(operand->expr, "Expected a dynamic array or dynamic map, got `%s`", str);
gb_string_free(str);
return false;
}
@@ -2887,16 +2861,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case BuiltinProc_clear: {
Type *type = operand->type;
- if (!is_type_pointer(type)) {
- gbString str = type_to_string(type);
- error_node(operand->expr, "Expected a pointer, got `%s`", str);
- gb_string_free(str);
- return false;
- }
- type = type_deref(type);
if (!is_type_dynamic_array(type) && !is_type_map(type)) {
gbString str = type_to_string(type);
- error_node(operand->expr, "Expected a pointer to a map or dynamic array, got `%s`", str);
+ error_node(operand->expr, "Expected a map or dynamic array, got `%s`", str);
gb_string_free(str);
return false;
}
@@ -2906,18 +2873,12 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
} break;
case BuiltinProc_append: {
- // append :: proc(^[dynamic]Type, item: ...Type) {
+ // append :: proc([dynamic]Type, item: ...Type) {
Type *type = operand->type;
- if (!is_type_pointer(type)) {
- gbString str = type_to_string(type);
- error_node(operand->expr, "Expected a pointer to a dynamic array, got `%s`", str);
- gb_string_free(str);
- return false;
- }
- type = base_type(type_deref(type));
+ type = base_type(type);
if (!is_type_dynamic_array(type)) {
gbString str = type_to_string(type);
- error_node(operand->expr, "Expected a pointer to a dynamic array, got `%s`", str);
+ error_node(operand->expr, "Expected a dynamic array, got `%s`", str);
gb_string_free(str);
return false;
}
@@ -3140,7 +3101,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
} break;
case BuiltinProc_compile_assert:
- // compile_assert :: proc(cond: bool)
+ // compile_assert :: proc(cond: bool) -> bool
if (!is_type_boolean(operand->type) && operand->mode != Addressing_Constant) {
gbString str = expr_to_string(ce->args.e[0]);
@@ -3153,10 +3114,13 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
error_node(call, "Compile time assertion: `%s`", str);
gb_string_free(str);
}
+
+ operand->mode = Addressing_Constant;
+ operand->type = t_untyped_bool;
break;
case BuiltinProc_assert:
- // assert :: proc(cond: bool)
+ // assert :: proc(cond: bool) -> bool
if (!is_type_boolean(operand->type)) {
gbString str = expr_to_string(ce->args.e[0]);
@@ -3165,7 +3129,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
return false;
}
- operand->mode = Addressing_NoValue;
+ operand->mode = Addressing_Value;
+ operand->type = t_untyped_bool;
break;
case BuiltinProc_panic:
@@ -5187,37 +5152,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
}
case_end;
- case_ast_node(de, DemaybeExpr, node);
- check_expr_or_type(c, o, de->expr);
- if (o->mode == Addressing_Invalid) {
- goto error;
- } else {
- Type *t = base_type(o->type);
- if (t->kind == Type_Maybe) {
- Entity **variables = gb_alloc_array(c->allocator, Entity *, 2);
- Type *elem = t->Maybe.elem;
- Token tok = make_token_ident(str_lit(""));
- variables[0] = make_entity_param(c->allocator, NULL, tok, elem, false, true);
- variables[1] = make_entity_param(c->allocator, NULL, tok, t_bool, false, true);
-
- Type *tuple = make_type_tuple(c->allocator);
- tuple->Tuple.variables = variables;
- tuple->Tuple.variable_count = 2;
-
- o->type = tuple;
- o->mode = Addressing_Variable;
- } else {
- gbString str = expr_to_string(o->expr);
- error_node(o->expr, "Cannot demaybe `%s`", str);
- gb_string_free(str);
- goto error;
- }
- }
- case_end;
-
case AstNode_ProcType:
case AstNode_PointerType:
- case AstNode_MaybeType:
case AstNode_ArrayType:
case AstNode_VectorType:
case AstNode_StructType:
@@ -5401,14 +5337,17 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = write_expr_to_string(str, ue->expr);
case_end;
- case_ast_node(de, DerefExpr, node);
- str = write_expr_to_string(str, de->expr);
- str = gb_string_appendc(str, "^");
+ case_ast_node(ce, CastExpr, node);
+ str = string_append_token(str, ce->token);
+ str = gb_string_appendc(str, "(");
+ str = write_expr_to_string(str, ce->type);
+ str = gb_string_appendc(str, ")");
+ str = write_expr_to_string(str, ce->expr);
case_end;
- case_ast_node(de, DemaybeExpr, node);
+ case_ast_node(de, DerefExpr, node);
str = write_expr_to_string(str, de->expr);
- str = gb_string_appendc(str, "?");
+ str = gb_string_appendc(str, "^");
case_end;
case_ast_node(be, BinaryExpr, node);
@@ -5462,11 +5401,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = write_expr_to_string(str, pt->type);
case_end;
- case_ast_node(mt, MaybeType, node);
- str = gb_string_appendc(str, "?");
- str = write_expr_to_string(str, mt->type);
- case_end;
-
case_ast_node(at, ArrayType, node);
str = gb_string_appendc(str, "[");
str = write_expr_to_string(str, at->count);
diff --git a/src/checker.c b/src/checker.c
index 78643e03c..32743d257 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -630,11 +630,12 @@ void init_universal_scope(BuildContext *bc) {
}
- t_u8_ptr = make_type_pointer(a, t_u8);
- t_int_ptr = make_type_pointer(a, t_int);
- t_i64_ptr = make_type_pointer(a, t_i64);
- t_f64_ptr = make_type_pointer(a, t_f64);
- t_byte_slice = make_type_slice(a, t_byte);
+ t_u8_ptr = make_type_pointer(a, t_u8);
+ t_int_ptr = make_type_pointer(a, t_int);
+ t_i64_ptr = make_type_pointer(a, t_i64);
+ t_f64_ptr = make_type_pointer(a, t_f64);
+ t_byte_slice = make_type_slice(a, t_byte);
+ t_string_slice = make_type_slice(a, t_string);
}
@@ -911,11 +912,6 @@ void add_type_info_type(Checker *c, Type *t) {
}
} break;
- case Type_Maybe:
- add_type_info_type(c, bt->Maybe.elem);
- add_type_info_type(c, t_bool);
- break;
-
case Type_Pointer:
add_type_info_type(c, bt->Pointer.elem);
break;
@@ -1099,48 +1095,46 @@ void init_preload(Checker *c) {
- if (record->field_count != 20) {
+ if (record->field_count != 19) {
compiler_error("Invalid `Type_Info` layout");
}
t_type_info_named = record->fields[ 1]->type;
t_type_info_integer = record->fields[ 2]->type;
t_type_info_float = record->fields[ 3]->type;
- t_type_info_any = record->fields[ 4]->type;
- t_type_info_string = record->fields[ 5]->type;
- t_type_info_boolean = record->fields[ 6]->type;
+ t_type_info_string = record->fields[ 4]->type;
+ t_type_info_boolean = record->fields[ 5]->type;
+ t_type_info_any = record->fields[ 6]->type;
t_type_info_pointer = record->fields[ 7]->type;
- t_type_info_maybe = record->fields[ 8]->type;
- t_type_info_procedure = record->fields[ 9]->type;
- t_type_info_array = record->fields[10]->type;
- t_type_info_dynamic_array = record->fields[11]->type;
- t_type_info_slice = record->fields[12]->type;
- t_type_info_vector = record->fields[13]->type;
- t_type_info_tuple = record->fields[14]->type;
- t_type_info_struct = record->fields[15]->type;
- t_type_info_union = record->fields[16]->type;
- t_type_info_raw_union = record->fields[17]->type;
- t_type_info_enum = record->fields[18]->type;
- t_type_info_map = record->fields[19]->type;
-
- t_type_info_named_ptr = make_type_pointer(heap_allocator(), t_type_info_named);
- t_type_info_integer_ptr = make_type_pointer(heap_allocator(), t_type_info_integer);
- t_type_info_float_ptr = make_type_pointer(heap_allocator(), t_type_info_float);
- t_type_info_any_ptr = make_type_pointer(heap_allocator(), t_type_info_any);
- t_type_info_string_ptr = make_type_pointer(heap_allocator(), t_type_info_string);
- t_type_info_boolean_ptr = make_type_pointer(heap_allocator(), t_type_info_boolean);
- t_type_info_pointer_ptr = make_type_pointer(heap_allocator(), t_type_info_pointer);
- t_type_info_maybe_ptr = make_type_pointer(heap_allocator(), t_type_info_maybe);
- t_type_info_procedure_ptr = make_type_pointer(heap_allocator(), t_type_info_procedure);
- t_type_info_array_ptr = make_type_pointer(heap_allocator(), t_type_info_array);
- t_type_info_dynamic_array_ptr = make_type_pointer(heap_allocator(), t_type_info_dynamic_array);
- t_type_info_slice_ptr = make_type_pointer(heap_allocator(), t_type_info_slice);
- t_type_info_vector_ptr = make_type_pointer(heap_allocator(), t_type_info_vector);
- t_type_info_tuple_ptr = make_type_pointer(heap_allocator(), t_type_info_tuple);
- t_type_info_struct_ptr = make_type_pointer(heap_allocator(), t_type_info_struct);
- t_type_info_union_ptr = make_type_pointer(heap_allocator(), t_type_info_union);
- t_type_info_raw_union_ptr = make_type_pointer(heap_allocator(), t_type_info_raw_union);
- t_type_info_enum_ptr = make_type_pointer(heap_allocator(), t_type_info_enum);
- t_type_info_map_ptr = make_type_pointer(heap_allocator(), t_type_info_map);
+ t_type_info_procedure = record->fields[ 8]->type;
+ t_type_info_array = record->fields[ 9]->type;
+ t_type_info_dynamic_array = record->fields[10]->type;
+ t_type_info_slice = record->fields[11]->type;
+ t_type_info_vector = record->fields[12]->type;
+ t_type_info_tuple = record->fields[13]->type;
+ t_type_info_struct = record->fields[14]->type;
+ t_type_info_union = record->fields[15]->type;
+ t_type_info_raw_union = record->fields[16]->type;
+ t_type_info_enum = record->fields[17]->type;
+ t_type_info_map = record->fields[18]->type;
+
+ t_type_info_named_ptr = make_type_pointer(c->allocator, t_type_info_named);
+ t_type_info_integer_ptr = make_type_pointer(c->allocator, t_type_info_integer);
+ t_type_info_float_ptr = make_type_pointer(c->allocator, t_type_info_float);
+ t_type_info_string_ptr = make_type_pointer(c->allocator, t_type_info_string);
+ t_type_info_boolean_ptr = make_type_pointer(c->allocator, t_type_info_boolean);
+ t_type_info_any_ptr = make_type_pointer(c->allocator, t_type_info_any);
+ t_type_info_pointer_ptr = make_type_pointer(c->allocator, t_type_info_pointer);
+ t_type_info_procedure_ptr = make_type_pointer(c->allocator, t_type_info_procedure);
+ t_type_info_array_ptr = make_type_pointer(c->allocator, t_type_info_array);
+ t_type_info_dynamic_array_ptr = make_type_pointer(c->allocator, t_type_info_dynamic_array);
+ t_type_info_slice_ptr = make_type_pointer(c->allocator, t_type_info_slice);
+ t_type_info_vector_ptr = make_type_pointer(c->allocator, t_type_info_vector);
+ t_type_info_tuple_ptr = make_type_pointer(c->allocator, t_type_info_tuple);
+ t_type_info_struct_ptr = make_type_pointer(c->allocator, t_type_info_struct);
+ t_type_info_union_ptr = make_type_pointer(c->allocator, t_type_info_union);
+ t_type_info_raw_union_ptr = make_type_pointer(c->allocator, t_type_info_raw_union);
+ t_type_info_enum_ptr = make_type_pointer(c->allocator, t_type_info_enum);
+ t_type_info_map_ptr = make_type_pointer(c->allocator, t_type_info_map);
}
if (t_allocator == NULL) {
@@ -1714,6 +1708,19 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
file_str = import_file;
}
+ if (fl->cond != NULL) {
+ Operand operand = {Addressing_Invalid};
+ check_expr(c, &operand, fl->cond);
+ if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
+ error_node(fl->cond, "Non-constant boolean `when` condition");
+ continue;
+ }
+ if (operand.value.kind == ExactValue_Bool &&
+ !operand.value.value_bool) {
+ continue;
+ }
+ }
+
String library_name = path_to_entity_name(fl->library_name.string, file_str);
if (str_eq(library_name, str_lit("_"))) {
error(fl->token, "File name, %.*s, cannot be as a library name as it is not a valid identifier", LIT(fl->library_name.string));
diff --git a/src/entity.c b/src/entity.c
index 221ec91b6..37c79b488 100644
--- a/src/entity.c
+++ b/src/entity.c
@@ -37,6 +37,7 @@ typedef enum EntityFlag {
EntityFlag_VectorElem = 1<<5,
EntityFlag_Ellipsis = 1<<6,
EntityFlag_NoAlias = 1<<7,
+ EntityFlag_EnumField = 1<<8,
} EntityFlag;
typedef enum OverloadKind {
diff --git a/src/ir.c b/src/ir.c
index 117173ab3..7ddcb6344 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -1788,11 +1788,6 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
case 0: result_type = make_type_pointer(a, t_type_info_ptr); break;
case 1: result_type = make_type_pointer(a, t_rawptr); break;
}
- } else if (is_type_maybe(t)) {
- switch (index) {
- case 0: result_type = make_type_pointer(a, t->Maybe.elem); break;
- case 1: result_type = make_type_pointer(a, t_bool); break;
- }
} else if (is_type_dynamic_array(t)) {
switch (index) {
case 0: result_type = make_type_pointer(a, make_type_pointer(a, t->DynamicArray.elem)); break;
@@ -1848,11 +1843,6 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
case 0: result_type = t_type_info_ptr; break;
case 1: result_type = t_rawptr; break;
}
- } else if (is_type_maybe(t)) {
- switch (index) {
- case 0: result_type = t->Maybe.elem; break;
- case 1: result_type = t_bool; break;
- }
} else if (is_type_dynamic_array(t)) {
switch (index) {
case 0: result_type = make_type_pointer(a, t->DynamicArray.elem); break;
@@ -2165,15 +2155,6 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
return value;
}
- if (is_type_maybe(dst)) {
- irValue *maybe = ir_add_local_generated(proc, dst);
- irValue *val = ir_emit_struct_ep(proc, maybe, 0);
- irValue *set = ir_emit_struct_ep(proc, maybe, 1);
- ir_emit_store(proc, val, value);
- ir_emit_store(proc, set, v_true);
- return ir_emit_load(proc, maybe);
- }
-
// integer -> integer
if (is_type_integer(src) && is_type_integer(dst)) {
GB_ASSERT(src->kind == Type_Basic &&
@@ -2396,7 +2377,6 @@ bool ir_is_type_aggregate(Type *t) {
case Type_Array:
case Type_Slice:
- case Type_Maybe:
case Type_Record:
case Type_Tuple:
return true;
@@ -3130,22 +3110,33 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
args[1] = ptr;
return ir_emit_global_call(proc, "free_ptr_with_allocator", args, 2);
} else if (is_type_dynamic_map(type)) {
- // irValue *val = ir_build_expr(proc, node);
- // irValue *map_ptr = ir_address_from_load_or_generate_local(proc, val);
-
- // {
- // irValue *array = ir_emit_conv(proc, ir_emit_struct_ep(proc, map_ptr, 0), t_raw_dynamic_array_ptr);
- // irValue **args = gb_alloc_array(a, irValue *, 1);
- // args[0] = array;
- // ir_emit_global_call(proc, "__free_raw_dynamic_array", args, 1);
- // }
- // {
- // irValue *array = ir_emit_conv(proc, ir_emit_struct_ep(proc, map_ptr, 1), t_raw_dynamic_array_ptr);
- // irValue **args = gb_alloc_array(a, irValue *, 1);
- // args[0] = array;
- // ir_emit_global_call(proc, "__free_raw_dynamic_array", args, 1);
- // }
+ irValue *map = ir_build_expr(proc, node);
+ irValue *map_ptr = ir_address_from_load_or_generate_local(proc, map);
+
+ {
+ irValue *array = ir_emit_struct_ep(proc, map_ptr, 0);
+
+ irValue *da_allocator = ir_emit_load(proc, ir_emit_struct_ep(proc, array, 3));
+ irValue *da_ptr = ir_emit_load(proc, ir_emit_struct_ep(proc, array, 0));
+ da_ptr = ir_emit_conv(proc, da_ptr, t_rawptr);
+
+ irValue **args = gb_alloc_array(a, irValue *, 1);
+ args[0] = da_allocator;
+ args[1] = da_ptr;
+ ir_emit_global_call(proc, "free_ptr_with_allocator", args, 2);
+ }
+ {
+ irValue *array = ir_emit_struct_ep(proc, map_ptr, 1);
+
+ irValue *da_allocator = ir_emit_load(proc, ir_emit_struct_ep(proc, array, 3));
+ irValue *da_ptr = ir_emit_load(proc, ir_emit_struct_ep(proc, array, 0));
+ da_ptr = ir_emit_conv(proc, da_ptr, t_rawptr);
+ irValue **args = gb_alloc_array(a, irValue *, 1);
+ args[0] = da_allocator;
+ args[1] = da_ptr;
+ ir_emit_global_call(proc, "free_ptr_with_allocator", args, 2);
+ }
return NULL;
}
@@ -3176,7 +3167,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
ir_emit_comment(proc, str_lit("reserve"));
gbAllocator a = proc->module->allocator;
- irValue *ptr = ir_build_expr(proc, ce->args.e[0]);
+ irValue *ptr = ir_build_addr(proc, ce->args.e[0]).addr;
Type *type = ir_type(ptr);
GB_ASSERT(is_type_pointer(type));
type = base_type(type_deref(type));
@@ -3208,8 +3199,8 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
} break;
case BuiltinProc_clear: {
- ir_emit_comment(proc, str_lit("reserve"));
- irValue *ptr = ir_build_expr(proc, ce->args.e[0]);
+ ir_emit_comment(proc, str_lit("clear"));
+ irValue *ptr = ir_build_addr(proc, ce->args.e[0]).addr;
Type *t = base_type(type_deref(ir_type(ptr)));
if (is_type_dynamic_array(t)) {
irValue *count_ptr = ir_emit_struct_ep(proc, ptr, 1);
@@ -3229,7 +3220,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
ir_emit_comment(proc, str_lit("append"));
gbAllocator a = proc->module->allocator;
- irValue *array_ptr = ir_build_expr(proc, ce->args.e[0]);
+ irValue *array_ptr = ir_build_addr(proc, ce->args.e[0]).addr;
Type *type = ir_type(array_ptr);
GB_ASSERT(is_type_pointer(type));
type = base_type(type_deref(type));
@@ -3348,7 +3339,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
ir_emit_jump(proc, done);
ir_start_block(proc, done);
- return NULL;
+ return cond;
} break;
case BuiltinProc_panic: {
@@ -3596,10 +3587,6 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
return ir_emit_call(proc, value, args, arg_count);
case_end;
- case_ast_node(de, DemaybeExpr, expr);
- return ir_addr_load(proc, ir_build_addr(proc, expr));
- case_end;
-
case_ast_node(se, SliceExpr, expr);
return ir_addr_load(proc, ir_build_addr(proc, expr));
case_end;
@@ -3722,7 +3709,34 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
AstNode *sel = unparen_expr(se->selector);
if (sel->kind == AstNode_Ident) {
String selector = sel->Ident.string;
- Type *type = base_type(type_of_expr(proc->module->info, se->expr));
+ Type *type = type_of_expr(proc->module->info, se->expr);
+
+ if (is_type_enum(type)) {
+ Selection sel = lookup_field(proc->module->allocator, type, selector, true);
+ Entity *e = sel.entity;
+ GB_ASSERT(e->kind == Entity_Variable);
+ i32 index = e->Variable.field_index;
+ switch (index) {
+ case 0: {
+ irValue *ti_ptr = ir_type_info(proc, type);
+ {
+ irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1);
+ args[0] = ti_ptr;
+ ti_ptr = ir_emit_global_call(proc, "type_info_base", args, 1);
+ }
+
+
+ irValue *enum_info = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
+ irValue *names_ptr = ir_emit_struct_ep(proc, enum_info, 1);
+ return ir_make_addr(names_ptr);
+ } break;
+ default:
+ GB_PANIC("Unhandled enum index %d %.*s", index, LIT(selector));
+ break;
+ }
+ }
+
+ type = base_type(type);
if (type == t_invalid) {
// NOTE(bill): Imports
@@ -4056,18 +4070,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
return ir_make_addr(addr);
case_end;
- case_ast_node(de, DemaybeExpr, expr);
- ir_emit_comment(proc, str_lit("DemaybeExpr"));
- irValue *maybe = ir_build_expr(proc, de->expr);
- Type *t = default_type(type_of_expr(proc->module->info, expr));
- GB_ASSERT(is_type_tuple(t));
-
- irValue *result = ir_add_local_generated(proc, t);
- ir_emit_store(proc, result, maybe);
-
- return ir_make_addr(result);
- case_end;
-
case_ast_node(ce, CallExpr, expr);
// NOTE(bill): This is make sure you never need to have an `array_ev`
irValue *e = ir_build_expr(proc, expr);
@@ -5276,6 +5278,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
String tag_var_name = ms->var->Ident.string;
+
AstNodeArray default_stmts = {0};
irBlock *default_block = NULL;
@@ -5291,19 +5294,32 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
default_block = ir_new_block(proc, clause, "type-match.dflt.body");
continue;
}
+ GB_ASSERT(cc->list.count == 1);
irBlock *body = ir_new_block(proc, clause, "type-match.case.body");
- Scope *scope = *map_scope_get(&proc->module->info->scopes, hash_pointer(clause));
- Entity *tag_var_entity = current_scope_lookup_entity(scope, tag_var_name);
- GB_ASSERT_MSG(tag_var_entity != NULL, "%.*s", LIT(tag_var_name));
+ Entity *tag_var_entity = NULL;
+ Type *tag_var_type = NULL;
+ if (str_eq(tag_var_name, str_lit("_"))) {
+ Type *t = type_of_expr(proc->module->info, cc->list.e[0]);
+ if (is_union_ptr) {
+ t = make_type_pointer(proc->module->allocator, t);
+ }
+ tag_var_type = t;
+ } else {
+ Scope *scope = *map_scope_get(&proc->module->info->scopes, hash_pointer(clause));
+ tag_var_entity = current_scope_lookup_entity(scope, tag_var_name);
+ GB_ASSERT_MSG(tag_var_entity != NULL, "%.*s", LIT(tag_var_name));
+ tag_var_type = tag_var_entity->type;
+ }
+ GB_ASSERT(tag_var_type != NULL);
irBlock *next_cond = NULL;
irValue *cond = NULL;
if (is_union_ptr) {
- Type *bt = type_deref(tag_var_entity->type);
+ Type *bt = type_deref(tag_var_type);
irValue *index = NULL;
Type *ut = base_type(type_deref(ir_type(parent)));
GB_ASSERT(ut->Record.kind == TypeRecord_Union);
@@ -5316,16 +5332,25 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
}
GB_ASSERT(index != NULL);
- irValue *tag_var = ir_add_local(proc, tag_var_entity);
- irValue *data_ptr = ir_emit_conv(proc, union_data, tag_var_entity->type);
+ irValue *tag_var = NULL;
+ if (tag_var_entity != NULL) {
+ tag_var = ir_add_local(proc, tag_var_entity);
+ } else {
+ tag_var = ir_add_local_generated(proc, tag_var_type);
+ }
+
+
+ irValue *data_ptr = ir_emit_conv(proc, union_data, tag_var_type);
ir_emit_store(proc, tag_var, data_ptr);
cond = ir_emit_comp(proc, Token_CmpEq, tag_index, index);
} else if (is_any) {
- Type *type = tag_var_entity->type;
+ Type *type = tag_var_type;
irValue *any_data = ir_emit_struct_ev(proc, parent, 1);
irValue *data = ir_emit_conv(proc, any_data, make_type_pointer(proc->module->allocator, type));
- ir_module_add_value(proc->module, tag_var_entity, data);
+ if (tag_var_entity != NULL) {
+ ir_module_add_value(proc->module, tag_var_entity, data);
+ }
irValue *any_ti = ir_emit_struct_ev(proc, parent, 0);
irValue *case_ti = ir_type_info(proc, type);
@@ -6228,11 +6253,6 @@ void ir_gen_tree(irGen *s) {
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Pointer.elem);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
} break;
- case Type_Maybe: {
- tag = ir_emit_conv(proc, ti_ptr, t_type_info_maybe_ptr);
- irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Maybe.elem);
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
- } break;
case Type_Array: {
tag = ir_emit_conv(proc, ti_ptr, t_type_info_array_ptr);
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Array.elem);
diff --git a/src/ir_print.c b/src/ir_print.c
index 670db48cd..da411fdc6 100644
--- a/src/ir_print.c
+++ b/src/ir_print.c
@@ -172,13 +172,6 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
ir_print_type(f, m, t->Pointer.elem);
ir_fprintf(f, "*");
return;
- case Type_Maybe:
- ir_fprintf(f, "{");
- ir_print_type(f, m, t->Maybe.elem);
- ir_fprintf(f, ", ");
- ir_print_type(f, m, t_bool);
- ir_fprintf(f, "}");
- return;
case Type_Array:
ir_fprintf(f, "[%lld x ", t->Array.count);
ir_print_type(f, m, t->Array.elem);
@@ -306,25 +299,11 @@ void ir_print_compound_element(irFileBuffer *f, irModule *m, ExactValue v, Type
ir_print_type(f, m, elem_type);
ir_fprintf(f, " ");
- if (v.kind != ExactValue_Invalid && is_type_maybe(elem_type)) {
- Type *t = base_type(elem_type)->Maybe.elem;
- ir_fprintf(f, "{");
- ir_print_type(f, m, t);
- ir_fprintf(f, " ");
- }
-
if (v.kind == ExactValue_Invalid || base_type(elem_type) == t_any) {
ir_fprintf(f, "zeroinitializer");
} else {
ir_print_exact_value(f, m, v, elem_type);
}
-
- if (v.kind != ExactValue_Invalid && is_type_maybe(elem_type)) {
- ir_fprintf(f, ", ");
- ir_print_type(f, m, t_bool);
- ir_fprintf(f, " ");
- ir_fprintf(f, "true}");
- }
}
void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *type) {
diff --git a/src/parser.c b/src/parser.c
index 079e39c2f..7531412ef 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -147,7 +147,6 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
AST_NODE_KIND(SelectorExpr, "selector expression", struct { Token token; AstNode *expr, *selector; }) \
AST_NODE_KIND(IndexExpr, "index expression", struct { AstNode *expr, *index; Token open, close; }) \
AST_NODE_KIND(DerefExpr, "dereference expression", struct { Token op; AstNode *expr; }) \
- AST_NODE_KIND(DemaybeExpr, "demaybe expression", struct { Token op; AstNode *expr; }) \
AST_NODE_KIND(SliceExpr, "slice expression", struct { \
AstNode *expr; \
Token open, close, interval; \
@@ -333,10 +332,6 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
Token token; \
AstNode *type; \
}) \
- AST_NODE_KIND(MaybeType, "maybe type", struct { \
- Token token; \
- AstNode *type; \
- }) \
AST_NODE_KIND(ArrayType, "array type", struct { \
Token token; \
AstNode *count; \
@@ -469,7 +464,6 @@ Token ast_node_token(AstNode *node) {
case AstNode_CastExpr: return node->CastExpr.token;
case AstNode_FieldValue: return node->FieldValue.eq;
case AstNode_DerefExpr: return node->DerefExpr.op;
- case AstNode_DemaybeExpr: return node->DemaybeExpr.op;
case AstNode_BlockExpr: return node->BlockExpr.open;
case AstNode_GiveExpr: return node->GiveExpr.token;
case AstNode_IfExpr: return node->IfExpr.token;
@@ -513,7 +507,6 @@ Token ast_node_token(AstNode *node) {
case AstNode_HelperType: return node->HelperType.token;
case AstNode_ProcType: return node->ProcType.token;
case AstNode_PointerType: return node->PointerType.token;
- case AstNode_MaybeType: return node->MaybeType.token;
case AstNode_ArrayType: return node->ArrayType.token;
case AstNode_DynamicArrayType: return node->DynamicArrayType.token;
case AstNode_VectorType: return node->VectorType.token;
@@ -693,13 +686,6 @@ AstNode *ast_deref_expr(AstFile *f, AstNode *expr, Token op) {
return result;
}
-AstNode *ast_demaybe_expr(AstFile *f, AstNode *expr, Token op) {
- AstNode *result = make_ast_node(f, AstNode_DemaybeExpr);
- result->DemaybeExpr.expr = expr;
- result->DemaybeExpr.op = op;
- return result;
-}
-
AstNode *ast_interval_expr(AstFile *f, Token op, AstNode *left, AstNode *right) {
AstNode *result = make_ast_node(f, AstNode_IntervalExpr);
@@ -1031,13 +1017,6 @@ AstNode *ast_pointer_type(AstFile *f, Token token, AstNode *type) {
return result;
}
-AstNode *ast_maybe_type(AstFile *f, Token token, AstNode *type) {
- AstNode *result = make_ast_node(f, AstNode_MaybeType);
- result->MaybeType.token = token;
- result->MaybeType.type = type;
- return result;
-}
-
AstNode *ast_array_type(AstFile *f, Token token, AstNode *count, AstNode *elem) {
AstNode *result = make_ast_node(f, AstNode_ArrayType);
result->ArrayType.token = token;
@@ -1999,10 +1978,6 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
break;
- case Token_Maybe: // Demaybe
- operand = ast_demaybe_expr(f, operand, expect_token(f, Token_Maybe));
- break;
-
case Token_OpenBrace:
if (!lhs && is_literal_type(operand) && f->expr_level >= 0) {
operand = parse_literal_value(f, operand);
@@ -2565,12 +2540,6 @@ AstNode *parse_type_or_ident(AstFile *f) {
return ast_pointer_type(f, token, elem);
}
- case Token_Maybe: {
- Token token = expect_token(f, Token_Maybe);
- AstNode *elem = parse_type(f);
- return ast_maybe_type(f, token, elem);
- }
-
case Token_OpenBracket: {
Token token = expect_token(f, Token_OpenBracket);
AstNode *count_expr = NULL;
diff --git a/src/tokenizer.c b/src/tokenizer.c
index 9dacdba64..308224157 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -17,7 +17,7 @@ TOKEN_KIND(Token__OperatorBegin, "_OperatorBegin"), \
TOKEN_KIND(Token_Hash, "#"), \
TOKEN_KIND(Token_At, "@"), \
TOKEN_KIND(Token_Pointer, "^"), \
- TOKEN_KIND(Token_Maybe, "?"), \
+ /* TOKEN_KIND(Token_Maybe, "?"), */ \
TOKEN_KIND(Token_Add, "+"), \
TOKEN_KIND(Token_Sub, "-"), \
TOKEN_KIND(Token_Mul, "*"), \
@@ -55,6 +55,8 @@ TOKEN_KIND(Token__AssignOpBegin, "_AssignOpBegin"), \
TOKEN_KIND(Token__AssignOpEnd, "_AssignOpEnd"), \
TOKEN_KIND(Token_ArrowRight, "->"), \
TOKEN_KIND(Token_ArrowLeft, "<-"), \
+ TOKEN_KIND(Token_Increment, "++"), \
+ TOKEN_KIND(Token_Decrement, "--"), \
\
TOKEN_KIND(Token__ComparisonBegin, "_ComparisonBegin"), \
TOKEN_KIND(Token_CmpEq, "=="), \
@@ -80,7 +82,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
\
TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
- /* TODO(bill): So of these keywords are not used but "reserved", why not remove them? */ \
+ /* TODO(bill): Of these keywords are not used but "reserved", why not remove them? */ \
TOKEN_KIND(Token_when, "when"), \
TOKEN_KIND(Token_if, "if"), \
TOKEN_KIND(Token_else, "else"), \
@@ -870,9 +872,9 @@ Token tokenizer_get_token(Tokenizer *t) {
case '^':
token.kind = Token_Pointer;
break;
- case '?':
- token.kind = Token_Maybe;
- break;
+ // case '?':
+ // token.kind = Token_Maybe;
+ // break;
case ';':
token.kind = Token_Semicolon;
break;
@@ -907,10 +909,10 @@ Token tokenizer_get_token(Tokenizer *t) {
case '~': token.kind = token_kind_variant2(t, Token_Xor, Token_XorEq); break;
case '!': token.kind = token_kind_variant2(t, Token_Not, Token_NotEq); break;
case '+':
- token.kind = token_kind_variant2(t, Token_Add, Token_AddEq);
+ token.kind = token_kind_variant3(t, Token_Add, Token_AddEq, '+', Token_Increment);
break;
case '-':
- token.kind = token_kind_variant3(t, Token_Sub, Token_SubEq, '>', Token_ArrowRight);
+ token.kind = token_kind_variant4(t, Token_Sub, Token_SubEq, '-', Token_Decrement, '>', Token_ArrowRight);
break;
case '/': {
if (t->curr_rune == '/') {
diff --git a/src/types.c b/src/types.c
index dbded4a73..71888a372 100644
--- a/src/types.c
+++ b/src/types.c
@@ -11,6 +11,20 @@ typedef enum BasicKind {
Basic_u32,
Basic_i64,
Basic_u64,
+
+/* Basic_i16le,
+ Basic_i16be,
+ Basic_u16le,
+ Basic_u16be,
+ Basic_i32le,
+ Basic_i32be,
+ Basic_u32le,
+ Basic_u32be,
+ Basic_i64le,
+ Basic_i64be,
+ Basic_u64le,
+ Basic_u64be, */
+
// Basic_i128,
// Basic_u128,
// Basic_f16,
@@ -93,6 +107,7 @@ typedef struct TypeRecord {
Entity * enum_count;
Entity * enum_min_value;
Entity * enum_max_value;
+ Entity * enum_names;
} TypeRecord;
#define TYPE_KINDS \
@@ -102,7 +117,6 @@ typedef struct TypeRecord {
TYPE_KIND(DynamicArray, struct { Type *elem; }) \
TYPE_KIND(Vector, struct { Type *elem; i64 count; }) \
TYPE_KIND(Slice, struct { Type *elem; }) \
- TYPE_KIND(Maybe, struct { Type *elem; }) \
TYPE_KIND(Record, TypeRecord) \
TYPE_KIND(Named, struct { \
String name; \
@@ -177,16 +191,16 @@ typedef struct BaseTypeSizes {
} BaseTypeSizes;
-typedef Array(isize) Array_isize;
+typedef Array(i32) Array_i32;
typedef struct Selection {
- Entity * entity;
- Array_isize index;
- bool indirect; // Set if there was a pointer deref anywhere down the line
+ Entity * entity;
+ Array_i32 index;
+ bool indirect; // Set if there was a pointer deref anywhere down the line
} Selection;
Selection empty_selection = {0};
-Selection make_selection(Entity *entity, Array_isize index, bool indirect) {
+Selection make_selection(Entity *entity, Array_i32 index, bool indirect) {
Selection s = {entity, index, indirect};
return s;
}
@@ -273,6 +287,7 @@ gb_global Type *t_int_ptr = NULL;
gb_global Type *t_i64_ptr = NULL;
gb_global Type *t_f64_ptr = NULL;
gb_global Type *t_byte_slice = NULL;
+gb_global Type *t_string_slice = NULL;
gb_global Type *t_type_info = NULL;
@@ -289,7 +304,6 @@ gb_global Type *t_type_info_any = NULL;
gb_global Type *t_type_info_string = NULL;
gb_global Type *t_type_info_boolean = NULL;
gb_global Type *t_type_info_pointer = NULL;
-gb_global Type *t_type_info_maybe = NULL;
gb_global Type *t_type_info_procedure = NULL;
gb_global Type *t_type_info_array = NULL;
gb_global Type *t_type_info_dynamic_array = NULL;
@@ -310,7 +324,6 @@ gb_global Type *t_type_info_any_ptr = NULL;
gb_global Type *t_type_info_string_ptr = NULL;
gb_global Type *t_type_info_boolean_ptr = NULL;
gb_global Type *t_type_info_pointer_ptr = NULL;
-gb_global Type *t_type_info_maybe_ptr = NULL;
gb_global Type *t_type_info_procedure_ptr = NULL;
gb_global Type *t_type_info_array_ptr = NULL;
gb_global Type *t_type_info_dynamic_array_ptr = NULL;
@@ -393,12 +406,6 @@ Type *make_type_pointer(gbAllocator a, Type *elem) {
return t;
}
-Type *make_type_maybe(gbAllocator a, Type *elem) {
- Type *t = alloc_type(a, Type_Maybe);
- t->Maybe.elem = elem;
- return t;
-}
-
Type *make_type_array(gbAllocator a, Type *elem, i64 count) {
Type *t = alloc_type(a, Type_Array);
t->Array.elem = elem;
@@ -630,10 +637,6 @@ bool is_type_pointer(Type *t) {
}
return t->kind == Type_Pointer;
}
-bool is_type_maybe(Type *t) {
- t = base_type(t);
- return t->kind == Type_Maybe;
-}
bool is_type_tuple(Type *t) {
t = base_type(t);
return t->kind == Type_Tuple;
@@ -780,7 +783,6 @@ bool type_has_nil(Type *t) {
case Type_DynamicArray:
case Type_Proc:
case Type_Pointer:
- case Type_Maybe:
return true;
}
return false;
@@ -890,12 +892,6 @@ bool are_types_identical(Type *x, Type *y) {
}
break;
- case Type_Maybe:
- if (y->kind == Type_Maybe) {
- return are_types_identical(x->Maybe.elem, y->Maybe.elem);
- }
- break;
-
case Type_Named:
if (y->kind == Type_Named) {
return x->Named.base == y->Named.base;
@@ -981,9 +977,6 @@ bool is_type_cte_safe(Type *type) {
case Type_Slice:
return false;
- case Type_Maybe:
- return is_type_cte_safe(type->Maybe.elem);
-
case Type_Record: {
if (type->Record.kind != TypeRecord_Struct) {
return false;
@@ -1026,12 +1019,14 @@ typedef enum ProcTypeOverloadKind {
ProcOverload_ResultCount,
ProcOverload_ResultTypes,
+ ProcOverload_NotProcedure,
+
} ProcTypeOverloadKind;
ProcTypeOverloadKind are_proc_types_overload_safe(Type *x, Type *y) {
- GB_ASSERT(is_type_proc(x));
- GB_ASSERT(is_type_proc(y));
+ if (!is_type_proc(x)) return ProcOverload_NotProcedure;
+ if (!is_type_proc(y)) return ProcOverload_NotProcedure;
TypeProc *px = &base_type(x)->Proc;
TypeProc *py = &base_type(y)->Proc;
@@ -1113,7 +1108,7 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
Entity *f = type->Record.fields[i];
if (f->kind == Entity_Variable) {
if (f->Variable.field_src_index == index) {
- Array_isize sel_array = {0};
+ Array_i32 sel_array = {0};
array_init_count(&sel_array, a, 1);
sel_array.e[0] = i;
return make_selection(f, sel_array, false);
@@ -1125,7 +1120,7 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
for (isize i = 0; i < max_count; i++) {
Entity *f = type->Tuple.variables[i];
if (i == index) {
- Array_isize sel_array = {0};
+ Array_i32 sel_array = {0};
array_init_count(&sel_array, a, 1);
sel_array.e[0] = i;
return make_selection(f, sel_array, false);
@@ -1352,6 +1347,10 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = type->Record.enum_max_value;
return sel;
}
+ if (str_eq(field_name, str_lit("names"))) {
+ sel.entity = type->Record.enum_names;
+ return sel;
+ }
}
for (isize i = 0; i < type->Record.field_count; i++) {
@@ -1558,17 +1557,6 @@ i64 type_align_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, Type
return max;
} break;
- case Type_Maybe: {
- Type *elem = t->Maybe.elem;
- type_path_push(path, elem);
- if (path->failure) {
- return FAILURE_ALIGNMENT;
- }
- i64 align = gb_max(type_align_of_internal(s, allocator, t->Maybe.elem, path), type_align_of_internal(s, allocator, t_bool, path));
- type_path_pop(path);
- return align;
- }
-
case Type_Map: {
if (t->Map.count == 0) { // Dynamic
return type_align_of_internal(s, allocator, t->Map.generated_struct_type, path);
@@ -1773,18 +1761,6 @@ i64 type_size_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypeP
case Type_Slice: // ptr + count
return 2 * s.word_size;
- case Type_Maybe: { // value + bool
- i64 align, size;
- Type *elem = t->Maybe.elem;
- align = type_align_of_internal(s, allocator, elem, path);
- if (path->failure) {
- return FAILURE_SIZE;
- }
- size = align_formula(type_size_of_internal(s, allocator, elem, path), align);
- size += type_size_of_internal(s, allocator, t_bool, path);
- return align_formula(size, align);
- }
-
case Type_Map: {
if (t->Map.count == 0) { // Dynamic
return type_size_of_internal(s, allocator, t->Map.generated_struct_type, path);
@@ -1969,11 +1945,6 @@ gbString write_type_to_string(gbString str, Type *type) {
str = write_type_to_string(str, type->Pointer.elem);
break;
- case Type_Maybe:
- str = gb_string_appendc(str, "?");
- str = write_type_to_string(str, type->Maybe.elem);
- break;
-
case Type_Array:
str = gb_string_appendc(str, gb_bprintf("[%lld]", type->Array.count));
str = write_type_to_string(str, type->Array.elem);