mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
Remove len(), cap() and replace with selectors; fix defer in match
This commit is contained in:
@@ -124,7 +124,6 @@ enum BuiltinProcId {
|
||||
|
||||
BuiltinProc_new,
|
||||
BuiltinProc_new_slice,
|
||||
BuiltinProc_delete,
|
||||
|
||||
BuiltinProc_size_of,
|
||||
BuiltinProc_size_of_val,
|
||||
@@ -139,8 +138,6 @@ enum BuiltinProcId {
|
||||
BuiltinProc_compile_assert,
|
||||
BuiltinProc_assert,
|
||||
|
||||
BuiltinProc_len,
|
||||
BuiltinProc_cap,
|
||||
BuiltinProc_copy,
|
||||
BuiltinProc_append,
|
||||
|
||||
@@ -168,7 +165,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
||||
|
||||
{STR_LIT("new"), 1, false, Expr_Expr},
|
||||
{STR_LIT("new_slice"), 2, true, Expr_Expr},
|
||||
{STR_LIT("delete"), 1, false, Expr_Stmt},
|
||||
|
||||
{STR_LIT("size_of"), 1, false, Expr_Expr},
|
||||
{STR_LIT("size_of_val"), 1, false, Expr_Expr},
|
||||
@@ -183,8 +179,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
||||
{STR_LIT("compile_assert"), 1, false, Expr_Stmt},
|
||||
{STR_LIT("assert"), 1, false, Expr_Stmt},
|
||||
|
||||
{STR_LIT("len"), 1, false, Expr_Expr},
|
||||
{STR_LIT("cap"), 1, false, Expr_Expr},
|
||||
{STR_LIT("copy"), 2, false, Expr_Expr},
|
||||
{STR_LIT("append"), 2, false, Expr_Expr},
|
||||
|
||||
|
||||
@@ -2095,21 +2095,6 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = make_type_slice(c->allocator, type);
|
||||
} break;
|
||||
case BuiltinProc_delete: {
|
||||
// delete :: proc(ptr: ^T)
|
||||
Type *type = get_base_type(operand->type);
|
||||
if (!is_type_pointer(type) && !is_type_slice(type)) {
|
||||
gbString type_str = type_to_string(operand->type);
|
||||
defer (gb_string_free(type_str));
|
||||
error(&c->error_collector, ast_node_token(call),
|
||||
"Expected a pointer or slice to `delete`, got `%s`",
|
||||
type_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
operand->mode = Addressing_NoValue;
|
||||
operand->type = NULL;
|
||||
} break;
|
||||
|
||||
case BuiltinProc_size_of: {
|
||||
// size_of :: proc(Type) -> int
|
||||
@@ -2289,58 +2274,6 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
||||
}
|
||||
break;
|
||||
|
||||
// TODO(bill): Should these be procedures and are their names appropriate?
|
||||
case BuiltinProc_len:
|
||||
case BuiltinProc_cap: {
|
||||
Type *t = get_base_type(operand->type);
|
||||
|
||||
AddressingMode mode = Addressing_Invalid;
|
||||
ExactValue value = {};
|
||||
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
if (id == BuiltinProc_len) {
|
||||
if (is_type_string(t)) {
|
||||
if (operand->mode == Addressing_Constant) {
|
||||
mode = Addressing_Constant;
|
||||
value = make_exact_value_integer(operand->value.value_string);
|
||||
} else {
|
||||
mode = Addressing_Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_Array:
|
||||
mode = Addressing_Constant;
|
||||
value = make_exact_value_integer(t->Array.count);
|
||||
break;
|
||||
|
||||
case Type_Vector:
|
||||
mode = Addressing_Constant;
|
||||
value = make_exact_value_integer(t->Vector.count);
|
||||
break;
|
||||
|
||||
case Type_Slice:
|
||||
mode = Addressing_Value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode == Addressing_Invalid) {
|
||||
gbString str = expr_to_string(operand->expr);
|
||||
error(&c->error_collector, ast_node_token(operand->expr),
|
||||
"Invalid expression `%s` for `%.*s`",
|
||||
str, LIT(bp->name));
|
||||
gb_string_free(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
operand->mode = mode;
|
||||
operand->type = t_int;
|
||||
operand->value = value;
|
||||
|
||||
} break;
|
||||
|
||||
case BuiltinProc_copy: {
|
||||
// copy :: proc(x, y: []Type) -> int
|
||||
Type *dest_type = NULL, *src_type = NULL;
|
||||
|
||||
+81
-3
@@ -350,6 +350,7 @@ gb_global Type *t_untyped_rune = &basic_types[Basic_UntypedRune];
|
||||
gb_global Type *t_byte = &basic_type_aliases[Basic_byte];
|
||||
gb_global Type *t_rune = &basic_type_aliases[Basic_rune];
|
||||
|
||||
|
||||
gb_global Type *t_type_info = NULL;
|
||||
gb_global Type *t_type_info_ptr = NULL;
|
||||
gb_global Type *t_type_info_member = NULL;
|
||||
@@ -588,7 +589,9 @@ b32 are_types_identical(Type *x, Type *y) {
|
||||
case TypeRecord_Struct:
|
||||
case TypeRecord_RawUnion:
|
||||
case TypeRecord_Union:
|
||||
if (x->Record.field_count == y->Record.field_count) {
|
||||
if (x->Record.field_count == y->Record.field_count &&
|
||||
x->Record.struct_is_packed == y->Record.struct_is_packed &&
|
||||
x->Record.struct_is_ordered == y->Record.struct_is_ordered) {
|
||||
for (isize i = 0; i < x->Record.field_count; i++) {
|
||||
if (!are_types_identical(x->Record.fields[i]->type, y->Record.fields[i]->type)) {
|
||||
return false;
|
||||
@@ -709,6 +712,8 @@ void selection_add_index(Selection *s, isize index) {
|
||||
|
||||
gb_global Entity *entity__any_type_info = NULL;
|
||||
gb_global Entity *entity__any_data = NULL;
|
||||
gb_global Entity *entity__string_data = NULL;
|
||||
gb_global Entity *entity__string_count = NULL;
|
||||
|
||||
Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection sel = empty_selection) {
|
||||
GB_ASSERT(type_ != NULL);
|
||||
@@ -717,6 +722,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
return empty_selection;
|
||||
}
|
||||
|
||||
gbAllocator a = gb_heap_allocator();
|
||||
Type *type = type_deref(type_);
|
||||
b32 is_ptr = type != type_;
|
||||
type = get_base_type(type);
|
||||
@@ -729,12 +735,12 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
if (entity__any_type_info == NULL) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = type_info_str;
|
||||
entity__any_type_info = make_entity_field(gb_heap_allocator(), NULL, token, t_type_info_ptr, false, 0);
|
||||
entity__any_type_info = make_entity_field(a, NULL, token, t_type_info_ptr, false, 0);
|
||||
}
|
||||
if (entity__any_data == NULL) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = data_str;
|
||||
entity__any_data = make_entity_field(gb_heap_allocator(), NULL, token, t_rawptr, false, 1);
|
||||
entity__any_data = make_entity_field(a, NULL, token, t_rawptr, false, 1);
|
||||
}
|
||||
|
||||
if (are_strings_equal(field_name, type_info_str)) {
|
||||
@@ -747,9 +753,81 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
return sel;
|
||||
}
|
||||
} break;
|
||||
case Basic_string: {
|
||||
String data_str = make_string("data");
|
||||
String count_str = make_string("count");
|
||||
if (entity__string_data == NULL) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = data_str;
|
||||
entity__string_data = make_entity_field(a, NULL, token, make_type_pointer(a, t_byte), false, 0);
|
||||
}
|
||||
|
||||
if (entity__string_count == NULL) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
entity__string_count = make_entity_field(a, NULL, token, t_int, false, 1);
|
||||
}
|
||||
|
||||
if (are_strings_equal(field_name, data_str)) {
|
||||
selection_add_index(&sel, 0);
|
||||
sel.entity = entity__string_data;
|
||||
return sel;
|
||||
} else if (are_strings_equal(field_name, count_str)) {
|
||||
selection_add_index(&sel, 1);
|
||||
sel.entity = entity__string_count;
|
||||
return sel;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
return sel;
|
||||
} else if (type->kind == Type_Array) {
|
||||
String count_str = make_string("count");
|
||||
// NOTE(bill):U nderlying memory address cannot be changed
|
||||
if (are_strings_equal(field_name, count_str)) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_constant(a, NULL, token, t_int, make_exact_value_integer(type->Array.count));
|
||||
return sel;
|
||||
}
|
||||
} else if (type->kind == Type_Vector) {
|
||||
String count_str = make_string("count");
|
||||
// NOTE(bill): Vectors are not addressable
|
||||
if (are_strings_equal(field_name, count_str)) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_constant(a, NULL, token, t_int, make_exact_value_integer(type->Vector.count));
|
||||
return sel;
|
||||
}
|
||||
} else if (type->kind == Type_Slice) {
|
||||
String data_str = make_string("data");
|
||||
String count_str = make_string("count");
|
||||
String capacity_str = make_string("capacity");
|
||||
|
||||
if (are_strings_equal(field_name, data_str)) {
|
||||
selection_add_index(&sel, 0);
|
||||
Token token = {Token_Identifier};
|
||||
token.string = data_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_field(a, NULL, token, make_type_pointer(a, type->Slice.elem), false, 0);
|
||||
return sel;
|
||||
} else if (are_strings_equal(field_name, count_str)) {
|
||||
selection_add_index(&sel, 1);
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_field(a, NULL, token, t_int, false, 1);
|
||||
return sel;
|
||||
} else if (are_strings_equal(field_name, capacity_str)) {
|
||||
selection_add_index(&sel, 2);
|
||||
Token token = {Token_Identifier};
|
||||
token.string = capacity_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_field(a, NULL, token, t_int, false, 2);
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->kind != Type_Record) {
|
||||
|
||||
Reference in New Issue
Block a user