mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 20:02:22 -07:00
default: to case:; no_alias to #no_alias
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ main :: proc() {
|
||||
case '-': accumulator -= 1;
|
||||
case '*': accumulator *= 2;
|
||||
case '/': accumulator /= 2;
|
||||
default: // Ignore everything else
|
||||
case: // Ignore everything else
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-16
@@ -189,7 +189,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
||||
match {
|
||||
case ti == type_info(int): write_string(buf, "int");
|
||||
case ti == type_info(uint): write_string(buf, "uint");
|
||||
default:
|
||||
case:
|
||||
write_string(buf, info.signed ? "i" : "u");
|
||||
fi := Fmt_Info{buf = buf};
|
||||
fmt_int(&fi, u64(8*info.size), false, 64, 'd');
|
||||
@@ -440,7 +440,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
|
||||
case u16: num = int(i);
|
||||
case u32: num = int(i);
|
||||
case u64: num = int(i);
|
||||
default:
|
||||
case:
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
@@ -468,7 +468,7 @@ fmt_bool :: proc(using fi: ^Fmt_Info, b: bool, verb: rune) {
|
||||
match verb {
|
||||
case 't', 'v':
|
||||
write_string(buf, b ? "true" : "false");
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
}
|
||||
}
|
||||
@@ -515,7 +515,7 @@ is_integer_negative :: proc(u: u64, is_signed: bool, bit_size: int) -> (unsigned
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = u64(i);
|
||||
default:
|
||||
case:
|
||||
panic("is_integer_negative: Unknown integer size");
|
||||
}
|
||||
}
|
||||
@@ -555,7 +555,7 @@ _write_int :: proc(fi: ^Fmt_Info, u: u64, base: int, is_signed: bool, bit_size:
|
||||
match base {
|
||||
case 2, 8, 10, 12, 16:
|
||||
break;
|
||||
default:
|
||||
case:
|
||||
panic("_write_int: unknown base, whoops");
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@ fmt_int :: proc(fi: ^Fmt_Info, u: u64, is_signed: bool, bit_size: int, verb: run
|
||||
_write_int(fi, u, 16, false, bit_size, __DIGITS_UPPER);
|
||||
}
|
||||
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
}
|
||||
}
|
||||
@@ -659,7 +659,7 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
|
||||
_pad(fi, str[1..]);
|
||||
}
|
||||
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
}
|
||||
@@ -681,7 +681,7 @@ fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
|
||||
_write_int(fi, u64(s[i]), 16, false, 8, verb == 'x' ? __DIGITS_LOWER : __DIGITS_UPPER);
|
||||
}
|
||||
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
}
|
||||
}
|
||||
@@ -690,7 +690,7 @@ fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
|
||||
match verb {
|
||||
case 'p', 'v':
|
||||
// Okay
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
}
|
||||
@@ -709,7 +709,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
|
||||
using Type_Info;
|
||||
match e in v.type_info {
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
case Enum:
|
||||
@@ -760,7 +760,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
if !ok {
|
||||
write_string(fi.buf, "!%(BAD ENUM VALUE)");
|
||||
}
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
}
|
||||
@@ -796,7 +796,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
}
|
||||
write_byte(fi.buf, '}');
|
||||
|
||||
default:
|
||||
case:
|
||||
fmt_value(fi, any{v.data, info.base}, verb);
|
||||
}
|
||||
|
||||
@@ -956,7 +956,7 @@ fmt_complex :: proc(fi: ^Fmt_Info, c: complex128, bits: int, verb: rune) {
|
||||
fmt_float(fi, i, bits/2, verb);
|
||||
write_rune(fi.buf, 'i');
|
||||
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
}
|
||||
@@ -983,7 +983,7 @@ fmt_quaternion :: proc(fi: ^Fmt_Info, c: quaternion256, bits: int, verb: rune) {
|
||||
fmt_float(fi, k, bits/4, verb);
|
||||
write_rune(fi.buf, 'k');
|
||||
|
||||
default:
|
||||
case:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
}
|
||||
@@ -1029,7 +1029,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
||||
case u32: fmt_int(fi, u64(a), false, 32, verb);
|
||||
case u64: fmt_int(fi, u64(a), false, 64, verb);
|
||||
case string: fmt_string(fi, a, verb);
|
||||
default: fmt_value(fi, arg, verb);
|
||||
case: fmt_value(fi, arg, verb);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1102,7 +1102,7 @@ sbprintf :: proc(b: ^String_Buffer, fmt: string, args: ..any) -> string {
|
||||
fi.hash = true;
|
||||
case '0':
|
||||
fi.zero = !fi.minus;
|
||||
default:
|
||||
case:
|
||||
break prefix_loop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,3 +35,13 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
|
||||
return data[0..<bytes_read], true;
|
||||
}
|
||||
|
||||
write_entire_file :: proc(name: string, data: []byte) -> bool {
|
||||
fd, err := open(name, O_WRONLY, 0);
|
||||
if err != 0 {
|
||||
return false;
|
||||
}
|
||||
defer close(fd);
|
||||
|
||||
bytes_written, write_err := write(fd, data);
|
||||
return write_err != 0;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
|
||||
create_mode = win32.OPEN_ALWAYS;
|
||||
case mode&O_TRUNC == O_TRUNC:
|
||||
create_mode = win32.TRUNCATE_EXISTING;
|
||||
default:
|
||||
case:
|
||||
create_mode = win32.OPEN_EXISTING;
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ _alloc_command_line_arguments :: proc() -> []string {
|
||||
j += 2;
|
||||
case 0xdc00 <= str[j] && str[j] < 0xe000:
|
||||
return "";
|
||||
default:
|
||||
case:
|
||||
if i+3 > len {
|
||||
return "";
|
||||
}
|
||||
|
||||
+4
-4
@@ -108,7 +108,7 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
|
||||
case 64:
|
||||
bits = transmute(u64, val);
|
||||
flt = &f64_info;
|
||||
default:
|
||||
case:
|
||||
panic("strconv: invalid bit_size");
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
|
||||
case 0: // denormalized
|
||||
exp++;
|
||||
|
||||
default:
|
||||
case:
|
||||
mant |= u64(1) << flt.mantbits;
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ is_integer_negative :: proc(u: u64, is_signed: bool, bit_size: int) -> (unsigned
|
||||
neg = i < 0;
|
||||
if neg { i = -i; }
|
||||
u = u64(i);
|
||||
default:
|
||||
case:
|
||||
panic("is_integer_negative: Unknown integer size");
|
||||
}
|
||||
}
|
||||
@@ -356,7 +356,7 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i
|
||||
case 10: i--; a[i] = 'd';
|
||||
case 12: i--; a[i] = 'z';
|
||||
case 16: i--; a[i] = 'x';
|
||||
default: ok = false;
|
||||
case: ok = false;
|
||||
}
|
||||
if ok {
|
||||
i--;
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ encode :: proc(d: []u16, s: []rune) {
|
||||
d[n+1] = u16(r2);
|
||||
n += 2;
|
||||
|
||||
default:
|
||||
case:
|
||||
d[n] = u16(REPLACEMENT_CHAR);
|
||||
n++;
|
||||
}
|
||||
|
||||
@@ -417,68 +417,6 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
|
||||
check_init_variables(c, entities, entity_count, inits, str_lit("variable declaration"));
|
||||
}
|
||||
|
||||
|
||||
void check_alias_decl(Checker *c, Entity *e, AstNode *expr, Type *named_type) {
|
||||
GB_ASSERT(e->type == NULL);
|
||||
GB_ASSERT(e->kind == Entity_Alias);
|
||||
|
||||
if (e->flags & EntityFlag_Visited) {
|
||||
e->type = t_invalid;
|
||||
return;
|
||||
}
|
||||
e->flags |= EntityFlag_Visited;
|
||||
e->type = t_invalid;
|
||||
|
||||
expr = unparen_expr(expr);
|
||||
|
||||
if (expr->kind == AstNode_Alias) {
|
||||
error_node(expr, "#alias of an #alias is not allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
Operand operand = {0};
|
||||
check_expr_or_type(c, &operand, expr);
|
||||
if (operand.mode != Addressing_Type) {
|
||||
error_node(expr, "#alias declarations only allow types");
|
||||
return;
|
||||
}
|
||||
e->kind = Entity_TypeName;
|
||||
e->TypeName.is_type_alias = true;
|
||||
e->type = NULL;
|
||||
|
||||
DeclInfo *d = c->context.decl;
|
||||
d->type_expr = expr;
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
|
||||
|
||||
// Operand o = {0};
|
||||
// Entity *f = NULL;
|
||||
// if (expr->kind == AstNode_Ident) {
|
||||
// f = check_ident(c, &o, expr, NULL, NULL, true);
|
||||
// } else if (expr->kind == AstNode_SelectorExpr) {
|
||||
// f = check_selector(c, &o, expr, NULL);
|
||||
// } else {
|
||||
// check_expr_or_type(c, &o, expr);
|
||||
// }
|
||||
// if (o.mode == Addressing_Invalid) {
|
||||
// return;
|
||||
// }
|
||||
// switch (o.mode) {
|
||||
// case Addressing_Type:
|
||||
// e->type = o.type;
|
||||
// // e->kind = Entity_TypeName;
|
||||
// // e->TypeName.is_type_alias = true;
|
||||
// e->Alias.kind = EntityAlias_Type;
|
||||
// e->Alias.original = f;
|
||||
// break;
|
||||
// default:
|
||||
// error_node(expr, "#alias declarations only allow types");
|
||||
// e->kind = Entity_Invalid;
|
||||
// e->type = t_invalid;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
if (e->type != NULL) {
|
||||
return;
|
||||
@@ -513,9 +451,6 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
case Entity_TypeName:
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
break;
|
||||
case Entity_Alias:
|
||||
check_alias_decl(c, e, d->init_expr, named_type);
|
||||
break;
|
||||
case Entity_Procedure:
|
||||
check_proc_lit(c, e, d);
|
||||
break;
|
||||
|
||||
+2
-21
@@ -1313,8 +1313,8 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
||||
}
|
||||
break;
|
||||
|
||||
case Entity_TypeAlias:
|
||||
case Entity_TypeName:
|
||||
// NOTE(bill): Cyclical dependency checking is handled in the "type system" not here
|
||||
o->mode = Addressing_Type;
|
||||
break;
|
||||
|
||||
@@ -1344,17 +1344,6 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
||||
o->mode = Addressing_Value;
|
||||
break;
|
||||
|
||||
case Entity_Alias: {
|
||||
// error_node(n, "#alias entities are not yet supported");
|
||||
// TODO(bill): Fix Entity_Alias rules
|
||||
if (e->Alias.kind == EntityAlias_Type) {
|
||||
o->mode = Addressing_Type;
|
||||
} else {
|
||||
o->mode = Addressing_Invalid;
|
||||
return e;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
compiler_error("Unknown EntityKind");
|
||||
break;
|
||||
@@ -3070,10 +3059,6 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
||||
expr_entity = e;
|
||||
|
||||
Entity *original_e = e;
|
||||
while (e != NULL && e->kind == Entity_Alias && e->Alias.original != NULL) {
|
||||
e = e->Alias.original;
|
||||
}
|
||||
|
||||
if (e != NULL && e->kind == Entity_ImportName && selector->kind == AstNode_Ident) {
|
||||
// IMPORTANT NOTE(bill): This is very sloppy code but it's also very fragile
|
||||
// It pretty much needs to be in this order and this way
|
||||
@@ -3295,6 +3280,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
||||
operand->mode = Addressing_Value;
|
||||
}
|
||||
break;
|
||||
case Entity_TypeAlias:
|
||||
case Entity_TypeName:
|
||||
operand->mode = Addressing_Type;
|
||||
break;
|
||||
@@ -3306,11 +3292,6 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
||||
operand->builtin_id = entity->Builtin.id;
|
||||
break;
|
||||
|
||||
case Entity_Alias: {
|
||||
error_node(selector, "#alias entities are not yet supported");
|
||||
return NULL;
|
||||
} break;
|
||||
|
||||
// NOTE(bill): These cases should never be hit but are here for sanity reasons
|
||||
case Entity_Nil:
|
||||
operand->mode = Addressing_Value;
|
||||
|
||||
+4
-13
@@ -262,10 +262,10 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
||||
AstNode *ln = unparen_expr(lhs_node);
|
||||
if (ln->kind == AstNode_IndexExpr) {
|
||||
AstNode *x = ln->IndexExpr.expr;
|
||||
TypeAndValue *tav = type_and_value_of_expression(&c->info, x);
|
||||
GB_ASSERT(tav != NULL);
|
||||
if (tav->mode != Addressing_Variable) {
|
||||
if (!is_type_pointer(tav->type)) {
|
||||
TypeAndValue tav = type_and_value_of_expr(&c->info, x);
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
if (tav.mode != Addressing_Variable) {
|
||||
if (!is_type_pointer(tav.type)) {
|
||||
gbString str = expr_to_string(lhs.expr);
|
||||
error_node(lhs.expr, "Cannot assign to the value of a map `%s`", str);
|
||||
gb_string_free(str);
|
||||
@@ -443,15 +443,6 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
|
||||
add_entity_use(c, expr, e);
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_Alias: {
|
||||
if (e->Alias.original != NULL) {
|
||||
check_using_stmt_entity(c, us, expr, is_selector, e->Alias.original);
|
||||
} else {
|
||||
error(us->token, "`using` cannot be applied to the alias `%.*s`", LIT(e->token.string));
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_TypeName: {
|
||||
Type *t = base_type(e->type);
|
||||
if (is_type_union(t)) {
|
||||
|
||||
+35
-18
@@ -28,8 +28,8 @@ typedef enum BuiltinProcId {
|
||||
BuiltinProc_cap,
|
||||
|
||||
BuiltinProc_new,
|
||||
BuiltinProc_free,
|
||||
BuiltinProc_make,
|
||||
BuiltinProc_free,
|
||||
|
||||
BuiltinProc_reserve,
|
||||
BuiltinProc_clear,
|
||||
@@ -82,8 +82,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
||||
{STR_LIT("cap"), 1, false, Expr_Expr},
|
||||
|
||||
{STR_LIT("new"), 1, false, Expr_Expr},
|
||||
{STR_LIT("free"), 1, false, Expr_Stmt},
|
||||
{STR_LIT("make"), 1, true, Expr_Expr},
|
||||
{STR_LIT("free"), 1, false, Expr_Stmt},
|
||||
|
||||
{STR_LIT("reserve"), 2, false, Expr_Stmt},
|
||||
{STR_LIT("clear"), 1, false, Expr_Stmt},
|
||||
@@ -624,14 +624,15 @@ void add_declaration_dependency(Checker *c, Entity *e) {
|
||||
}
|
||||
|
||||
|
||||
void add_global_entity(Entity *entity) {
|
||||
Entity *add_global_entity(Entity *entity) {
|
||||
String name = entity->token.string;
|
||||
if (gb_memchr(name.text, ' ', name.len)) {
|
||||
return; // NOTE(bill): `untyped thing`
|
||||
return entity; // NOTE(bill): `untyped thing`
|
||||
}
|
||||
if (scope_insert_entity(universal_scope, entity)) {
|
||||
compiler_error("double declaration");
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
void add_global_constant(gbAllocator a, String name, Type *type, ExactValue value) {
|
||||
@@ -646,6 +647,11 @@ void add_global_string_constant(gbAllocator a, String name, String value) {
|
||||
|
||||
}
|
||||
|
||||
Type *add_global_type_alias(gbAllocator a, String name, Type *t) {
|
||||
Entity *e = add_global_entity(make_entity_type_alias(a, NULL, make_token_ident(name), t));
|
||||
return e->type;
|
||||
}
|
||||
|
||||
|
||||
void init_universal_scope(void) {
|
||||
BuildContext *bc = &build_context;
|
||||
@@ -657,9 +663,16 @@ void init_universal_scope(void) {
|
||||
for (isize i = 0; i < gb_count_of(basic_types); i++) {
|
||||
add_global_entity(make_entity_type_name(a, NULL, make_token_ident(basic_types[i].Basic.name), &basic_types[i]));
|
||||
}
|
||||
#if 1
|
||||
for (isize i = 0; i < gb_count_of(basic_type_aliases); i++) {
|
||||
add_global_entity(make_entity_type_name(a, NULL, make_token_ident(basic_type_aliases[i].Basic.name), &basic_type_aliases[i]));
|
||||
}
|
||||
#else
|
||||
{
|
||||
t_byte = add_global_type_alias(a, str_lit("byte"), &basic_types[Basic_u8]);
|
||||
t_rune = add_global_type_alias(a, str_lit("rune"), &basic_types[Basic_i32]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
add_global_constant(a, str_lit("true"), t_untyped_bool, exact_value_bool(true));
|
||||
@@ -786,11 +799,6 @@ void destroy_checker(Checker *c) {
|
||||
}
|
||||
|
||||
|
||||
TypeAndValue *type_and_value_of_expression(CheckerInfo *i, AstNode *expression) {
|
||||
TypeAndValue *found = map_tav_get(&i->types, hash_pointer(expression));
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
||||
if (identifier->kind == AstNode_Ident) {
|
||||
@@ -806,13 +814,22 @@ Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Type *type_of_expr(CheckerInfo *i, AstNode *expression) {
|
||||
TypeAndValue *found = type_and_value_of_expression(i, expression);
|
||||
if (found) {
|
||||
return found->type;
|
||||
|
||||
TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expression) {
|
||||
TypeAndValue result = {0};
|
||||
TypeAndValue *found = map_tav_get(&i->types, hash_pointer(expression));
|
||||
if (found) result = *found;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Type *type_of_expr(CheckerInfo *i, AstNode *expr) {
|
||||
TypeAndValue tav = type_and_value_of_expr(i, expr);
|
||||
if (tav.mode != Addressing_Invalid) {
|
||||
return tav.type;
|
||||
}
|
||||
if (expression->kind == AstNode_Ident) {
|
||||
Entity *entity = entity_of_ident(i, expression);
|
||||
if (expr->kind == AstNode_Ident) {
|
||||
Entity *entity = entity_of_ident(i, expr);
|
||||
if (entity) {
|
||||
return entity->type;
|
||||
}
|
||||
@@ -2102,6 +2119,7 @@ void check_parsed_files(Checker *c) {
|
||||
// TODO(bill): Any other checks?
|
||||
|
||||
|
||||
#if 1
|
||||
// Add "Basic" type information
|
||||
for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
|
||||
Type *t = &basic_types[i];
|
||||
@@ -2116,14 +2134,13 @@ void check_parsed_files(Checker *c) {
|
||||
add_type_info_type(c, t);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// NOTE(bill): Check for illegal cyclic type declarations
|
||||
for_array(i, c->info.definitions.entries) {
|
||||
Entity *e = c->info.definitions.entries.e[i].value;
|
||||
if (e->kind == Entity_TypeName ||
|
||||
(e->kind == Entity_Alias && e->Alias.kind == EntityAlias_Type)) {
|
||||
if (e->kind == Entity_TypeName) {
|
||||
if (e->type != NULL) {
|
||||
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
|
||||
i64 align = type_align_of(c->allocator, e->type);
|
||||
|
||||
+16
-9
@@ -14,7 +14,8 @@ typedef struct DeclInfo DeclInfo;
|
||||
ENTITY_KIND(Builtin) \
|
||||
ENTITY_KIND(ImportName) \
|
||||
ENTITY_KIND(LibraryName) \
|
||||
ENTITY_KIND(Alias) \
|
||||
ENTITY_KIND(TypeAlias) \
|
||||
ENTITY_KIND(ProcedureAlias) \
|
||||
ENTITY_KIND(Nil) \
|
||||
ENTITY_KIND(Label)
|
||||
|
||||
@@ -109,10 +110,10 @@ struct Entity {
|
||||
String name;
|
||||
bool used;
|
||||
} LibraryName;
|
||||
i32 TypeAlias;
|
||||
struct {
|
||||
EntityAliasKind kind;
|
||||
Entity * original;
|
||||
} Alias;
|
||||
Entity *original;
|
||||
} ProcedureAlias;
|
||||
i32 Nil;
|
||||
struct {
|
||||
String name;
|
||||
@@ -243,13 +244,19 @@ Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type
|
||||
return entity;
|
||||
}
|
||||
|
||||
Entity *make_entity_alias(gbAllocator a, Scope *scope, Token token, Type *type,
|
||||
EntityAliasKind kind, Entity *original) {
|
||||
Entity *entity = alloc_entity(a, Entity_Alias, scope, token, type);
|
||||
entity->Alias.kind = kind;
|
||||
entity->Alias.original = original;
|
||||
Entity *make_entity_type_alias(gbAllocator a, Scope *scope, Token token, Type *type) {
|
||||
Entity *entity = alloc_entity(a, Entity_TypeAlias, scope, token, type);
|
||||
return entity;
|
||||
}
|
||||
Entity *make_entity_procedure_alias(gbAllocator a, Scope *scope, Token token, Entity *original) {
|
||||
GB_ASSERT(original != NULL);
|
||||
Entity *entity = alloc_entity(a, Entity_ProcedureAlias, scope, token, original->type);
|
||||
entity->ProcedureAlias.original = original;
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Entity *make_entity_nil(gbAllocator a, String name, Type *type) {
|
||||
Token token = make_token_ident(name);
|
||||
|
||||
@@ -3570,23 +3570,23 @@ bool is_double_pointer(Type *t) {
|
||||
irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
|
||||
TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(expr));
|
||||
GB_ASSERT_NOT_NULL(tv);
|
||||
TypeAndValue tv = type_and_value_of_expr(proc->module->info, expr);
|
||||
GB_ASSERT(tv.mode != Addressing_Invalid);
|
||||
|
||||
if (tv->value.kind != ExactValue_Invalid) {
|
||||
if (tv.value.kind != ExactValue_Invalid) {
|
||||
// NOTE(bill): Edge case
|
||||
if (tv->value.kind != ExactValue_Compound &&
|
||||
is_type_vector(tv->type)) {
|
||||
Type *elem = base_vector_type(tv->type);
|
||||
ExactValue value = convert_exact_value_for_type(tv->value, elem);
|
||||
if (tv.value.kind != ExactValue_Compound &&
|
||||
is_type_vector(tv.type)) {
|
||||
Type *elem = base_vector_type(tv.type);
|
||||
ExactValue value = convert_exact_value_for_type(tv.value, elem);
|
||||
irValue *x = ir_add_module_constant(proc->module, elem, value);
|
||||
return ir_emit_conv(proc, x, tv->type);
|
||||
return ir_emit_conv(proc, x, tv.type);
|
||||
}
|
||||
|
||||
return ir_add_module_constant(proc->module, tv->type, tv->value);
|
||||
return ir_add_module_constant(proc->module, tv.type, tv.value);
|
||||
}
|
||||
|
||||
if (tv->mode == Addressing_Variable) {
|
||||
if (tv.mode == Addressing_Variable) {
|
||||
return ir_addr_load(proc, ir_build_addr(proc, expr));
|
||||
}
|
||||
|
||||
@@ -3614,7 +3614,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
LIT(token.pos.file), token.pos.line, token.pos.column);
|
||||
return NULL;
|
||||
} else if (e->kind == Entity_Nil) {
|
||||
return ir_value_nil(proc->module->allocator, tv->type);
|
||||
return ir_value_nil(proc->module->allocator, tv.type);
|
||||
}
|
||||
|
||||
irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
|
||||
@@ -3644,8 +3644,8 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(se, SelectorExpr, expr);
|
||||
TypeAndValue *tav = map_tav_get(&proc->module->info->types, hash_pointer(expr));
|
||||
GB_ASSERT(tav != NULL);
|
||||
TypeAndValue tav = type_and_value_of_expr(proc->module->info, expr);
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
return ir_addr_load(proc, ir_build_addr(proc, expr));
|
||||
case_end;
|
||||
|
||||
@@ -3725,7 +3725,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
|
||||
case_ast_node(ta, TypeAssertion, expr);
|
||||
TokenPos pos = ast_node_token(expr).pos;
|
||||
Type *type = tv->type;
|
||||
Type *type = tv.type;
|
||||
irValue *e = ir_build_expr(proc, ta->expr);
|
||||
Type *t = type_deref(ir_type(e));
|
||||
if (is_type_union(t)) {
|
||||
@@ -3744,13 +3744,13 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
case Token_And:
|
||||
return ir_emit_ptr_offset(proc, ir_build_addr(proc, ue->expr).addr, v_zero); // Make a copy of the pointer
|
||||
default:
|
||||
return ir_emit_unary_arith(proc, ue->op.kind, ir_build_expr(proc, ue->expr), tv->type);
|
||||
return ir_emit_unary_arith(proc, ue->op.kind, ir_build_expr(proc, ue->expr), tv.type);
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(be, BinaryExpr, expr);
|
||||
irValue *left = ir_build_expr(proc, be->left);
|
||||
Type *type = default_type(tv->type);
|
||||
Type *type = default_type(tv.type);
|
||||
|
||||
switch (be->op.kind) {
|
||||
case Token_Add:
|
||||
@@ -3822,7 +3822,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
if (map_tav_get(&proc->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
|
||||
GB_ASSERT(ce->args.count == 1);
|
||||
irValue *x = ir_build_expr(proc, ce->args.e[0]);
|
||||
irValue *y = ir_emit_conv(proc, x, tv->type);
|
||||
irValue *y = ir_emit_conv(proc, x, tv.type);
|
||||
return y;
|
||||
}
|
||||
|
||||
@@ -3843,7 +3843,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
|
||||
case BuiltinProc_transmute: {
|
||||
irValue *x = ir_build_expr(proc, ce->args.e[1]);
|
||||
return ir_emit_transmute(proc, x, tv->type);
|
||||
return ir_emit_transmute(proc, x, tv.type);
|
||||
}
|
||||
|
||||
case BuiltinProc_len: {
|
||||
@@ -4042,7 +4042,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
gbAllocator a = proc->module->allocator;
|
||||
|
||||
AstNode *node = ce->args.e[0];
|
||||
TypeAndValue tav = *type_and_value_of_expression(proc->module->info, node);
|
||||
TypeAndValue tav = type_and_value_of_expr(proc->module->info, node);
|
||||
Type *type = base_type(tav.type);
|
||||
|
||||
if (is_type_dynamic_array(type)) {
|
||||
@@ -4394,14 +4394,14 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
return ir_addr_load(proc, vector_addr);
|
||||
}
|
||||
irValue *src = vector_addr.addr;
|
||||
irValue *dst = ir_add_local_generated(proc, tv->type);
|
||||
irValue *dst = ir_add_local_generated(proc, tv.type);
|
||||
|
||||
for (i32 i = 1; i < ce->args.count; i++) {
|
||||
TypeAndValue *tv = type_and_value_of_expression(proc->module->info, ce->args.e[i]);
|
||||
GB_ASSERT(is_type_integer(tv->type));
|
||||
GB_ASSERT(tv->value.kind == ExactValue_Integer);
|
||||
TypeAndValue tv = type_and_value_of_expr(proc->module->info, ce->args.e[i]);
|
||||
GB_ASSERT(is_type_integer(tv.type));
|
||||
GB_ASSERT(tv.value.kind == ExactValue_Integer);
|
||||
|
||||
i32 src_index = cast(i32)tv->value.value_integer;
|
||||
i32 src_index = cast(i32)tv.value.value_integer;
|
||||
i32 dst_index = i-1;
|
||||
|
||||
irValue *src_elem = ir_emit_array_epi(proc, src, src_index);
|
||||
@@ -4418,9 +4418,9 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_comment(proc, str_lit("complex"));
|
||||
irValue *real = ir_build_expr(proc, ce->args.e[0]);
|
||||
irValue *imag = ir_build_expr(proc, ce->args.e[1]);
|
||||
irValue *dst = ir_add_local_generated(proc, tv->type);
|
||||
irValue *dst = ir_add_local_generated(proc, tv.type);
|
||||
|
||||
Type *ft = base_complex_elem_type(tv->type);
|
||||
Type *ft = base_complex_elem_type(tv.type);
|
||||
real = ir_emit_conv(proc, real, ft);
|
||||
imag = ir_emit_conv(proc, imag, ft);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, dst, 0), real);
|
||||
@@ -4435,9 +4435,9 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *imag = ir_build_expr(proc, ce->args.e[1]);
|
||||
irValue *jmag = ir_build_expr(proc, ce->args.e[2]);
|
||||
irValue *kmag = ir_build_expr(proc, ce->args.e[3]);
|
||||
irValue *dst = ir_add_local_generated(proc, tv->type);
|
||||
irValue *dst = ir_add_local_generated(proc, tv.type);
|
||||
|
||||
Type *ft = base_quaternion_elem_type(tv->type);
|
||||
Type *ft = base_quaternion_elem_type(tv.type);
|
||||
real = ir_emit_conv(proc, real, ft);
|
||||
imag = ir_emit_conv(proc, imag, ft);
|
||||
jmag = ir_emit_conv(proc, jmag, ft);
|
||||
@@ -4454,25 +4454,25 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
ir_emit_comment(proc, str_lit("real"));
|
||||
irValue *val = ir_build_expr(proc, ce->args.e[0]);
|
||||
irValue *real = ir_emit_struct_ev(proc, val, 0);
|
||||
return ir_emit_conv(proc, real, tv->type);
|
||||
return ir_emit_conv(proc, real, tv.type);
|
||||
} break;
|
||||
case BuiltinProc_imag: {
|
||||
ir_emit_comment(proc, str_lit("imag"));
|
||||
irValue *val = ir_build_expr(proc, ce->args.e[0]);
|
||||
irValue *imag = ir_emit_struct_ev(proc, val, 1);
|
||||
return ir_emit_conv(proc, imag, tv->type);
|
||||
return ir_emit_conv(proc, imag, tv.type);
|
||||
} break;
|
||||
case BuiltinProc_jmag: {
|
||||
ir_emit_comment(proc, str_lit("jmag"));
|
||||
irValue *val = ir_build_expr(proc, ce->args.e[0]);
|
||||
irValue *jmag = ir_emit_struct_ev(proc, val, 2);
|
||||
return ir_emit_conv(proc, jmag, tv->type);
|
||||
return ir_emit_conv(proc, jmag, tv.type);
|
||||
} break;
|
||||
case BuiltinProc_kmag: {
|
||||
ir_emit_comment(proc, str_lit("kmag"));
|
||||
irValue *val = ir_build_expr(proc, ce->args.e[0]);
|
||||
irValue *kmag = ir_emit_struct_ev(proc, val, 3);
|
||||
return ir_emit_conv(proc, kmag, tv->type);
|
||||
return ir_emit_conv(proc, kmag, tv.type);
|
||||
} break;
|
||||
|
||||
case BuiltinProc_conj: {
|
||||
@@ -4481,14 +4481,14 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *res = NULL;
|
||||
Type *t = ir_type(val);
|
||||
if (is_type_complex(t)) {
|
||||
res = ir_add_local_generated(proc, tv->type);
|
||||
res = ir_add_local_generated(proc, tv.type);
|
||||
irValue *real = ir_emit_struct_ev(proc, val, 0);
|
||||
irValue *imag = ir_emit_struct_ev(proc, val, 1);
|
||||
imag = ir_emit_unary_arith(proc, Token_Sub, imag, ir_type(imag));
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, res, 0), real);
|
||||
ir_emit_store(proc, ir_emit_struct_ep(proc, res, 1), imag);
|
||||
} else if (is_type_quaternion(t)) {
|
||||
res = ir_add_local_generated(proc, tv->type);
|
||||
res = ir_add_local_generated(proc, tv.type);
|
||||
irValue *real = ir_emit_struct_ev(proc, val, 0);
|
||||
irValue *imag = ir_emit_struct_ev(proc, val, 1);
|
||||
irValue *jmag = ir_emit_struct_ev(proc, val, 2);
|
||||
@@ -4526,9 +4526,9 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *s = ir_build_expr(proc, ce->args.e[0]);
|
||||
Type *t = base_type(ir_type(s));
|
||||
if (is_type_u8_slice(t)) {
|
||||
return ir_emit_conv(proc, s, tv->type);
|
||||
return ir_emit_conv(proc, s, tv.type);
|
||||
}
|
||||
irValue *slice = ir_add_local_generated(proc, tv->type);
|
||||
irValue *slice = ir_add_local_generated(proc, tv.type);
|
||||
i64 elem_size = type_size_of(proc->module->allocator, t->Slice.elem);
|
||||
|
||||
irValue *ptr = ir_emit_conv(proc, ir_slice_elem(proc, s), t_u8_ptr);
|
||||
@@ -4733,9 +4733,9 @@ bool ir_is_elem_const(irModule *m, AstNode *elem, Type *elem_type) {
|
||||
if (elem->kind == AstNode_FieldValue) {
|
||||
elem = elem->FieldValue.value;
|
||||
}
|
||||
TypeAndValue *tav = type_and_value_of_expression(m->info, elem);
|
||||
GB_ASSERT(tav != NULL);
|
||||
return tav->value.kind != ExactValue_Invalid;
|
||||
TypeAndValue tav = type_and_value_of_expr(m->info, elem);
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
return tav.value.kind != ExactValue_Invalid;
|
||||
}
|
||||
|
||||
irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) {
|
||||
@@ -4790,9 +4790,9 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
AstNode *sel = unparen_expr(se->selector);
|
||||
if (sel->kind == AstNode_Ident) {
|
||||
String selector = sel->Ident.string;
|
||||
TypeAndValue *tav = type_and_value_of_expression(proc->module->info, se->expr);
|
||||
TypeAndValue tav = type_and_value_of_expr(proc->module->info, se->expr);
|
||||
|
||||
if (tav == NULL) {
|
||||
if (tav.mode == Addressing_Invalid) {
|
||||
// NOTE(bill): Imports
|
||||
Entity *imp = entity_of_ident(proc->module->info, se->expr);
|
||||
if (imp != NULL) {
|
||||
@@ -4802,8 +4802,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
}
|
||||
|
||||
|
||||
Type *type = base_type(tav->type);
|
||||
if (tav->mode == Addressing_Type) { // Addressing_Type
|
||||
Type *type = base_type(tav.type);
|
||||
if (tav.mode == Addressing_Type) { // Addressing_Type
|
||||
Selection sel = lookup_field(proc->module->allocator, type, selector, true);
|
||||
Entity *e = sel.entity;
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
@@ -4838,7 +4838,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
Type *type = type_deref(type_of_expr(proc->module->info, se->expr));
|
||||
Type *selector_type = base_type(type_of_expr(proc->module->info, se->selector));
|
||||
GB_ASSERT_MSG(is_type_integer(selector_type), "%s", type_to_string(selector_type));
|
||||
ExactValue val = type_and_value_of_expression(proc->module->info, sel)->value;
|
||||
ExactValue val = type_and_value_of_expr(proc->module->info, sel).value;
|
||||
i64 index = val.value_integer;
|
||||
|
||||
Selection sel = lookup_field_from_index(proc->module->allocator, type, index);
|
||||
@@ -5009,7 +5009,6 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
|
||||
|
||||
case Type_Basic: { // Basic_string
|
||||
TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(ie->expr));
|
||||
irValue *str;
|
||||
irValue *elem;
|
||||
irValue *len;
|
||||
@@ -5214,7 +5213,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
index = sel.index.e[0];
|
||||
elem = fv->value;
|
||||
} else {
|
||||
TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem);
|
||||
TypeAndValue tav = type_and_value_of_expr(proc->module->info, elem);
|
||||
Selection sel = lookup_field(proc->module->allocator, bt, st->fields_in_src_order[field_index]->token.string, false);
|
||||
index = sel.index.e[0];
|
||||
}
|
||||
@@ -5370,7 +5369,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
||||
index = sel.index.e[0];
|
||||
elem = fv->value;
|
||||
} else {
|
||||
TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem);
|
||||
TypeAndValue tav = type_and_value_of_expr(proc->module->info, elem);
|
||||
Selection sel = lookup_field(proc->module->allocator, bt, field_names[field_index], false);
|
||||
index = sel.index.e[0];
|
||||
}
|
||||
@@ -6177,14 +6176,14 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
||||
irBlock *done = NULL;
|
||||
AstNode *expr = unparen_expr(rs->expr);
|
||||
|
||||
TypeAndValue *tav = type_and_value_of_expression(proc->module->info, expr);
|
||||
TypeAndValue tav = type_and_value_of_expr(proc->module->info, expr);
|
||||
|
||||
if (is_ast_node_a_range(expr)) {
|
||||
ir_build_range_interval(proc, &expr->BinaryExpr, val_type, &val, &index, &loop, &done);
|
||||
} else if (tav->mode == Addressing_Type) {
|
||||
} else if (tav.mode == Addressing_Type) {
|
||||
TokenPos pos = ast_node_token(expr).pos;
|
||||
gbAllocator a = proc->module->allocator;
|
||||
Type *t = tav->type;
|
||||
Type *t = tav.type;
|
||||
GB_ASSERT(is_type_enum(t));
|
||||
Type *enum_ptr = make_type_pointer(a, t);
|
||||
t = base_type(t);
|
||||
@@ -7158,12 +7157,12 @@ void ir_gen_tree(irGen *s) {
|
||||
if (is_type_any(e->type)) {
|
||||
|
||||
} else {
|
||||
TypeAndValue *tav = map_tav_get(&info->types, hash_pointer(decl->init_expr));
|
||||
if (tav != NULL) {
|
||||
if (tav->value.kind != ExactValue_Invalid) {
|
||||
ExactValue v = tav->value;
|
||||
TypeAndValue tav = type_and_value_of_expr(info, decl->init_expr);
|
||||
if (tav.mode != Addressing_Invalid) {
|
||||
if (tav.value.kind != ExactValue_Invalid) {
|
||||
ExactValue v = tav.value;
|
||||
// if (v.kind != ExactValue_String) {
|
||||
g->Global.value = ir_add_module_constant(m, tav->type, v);
|
||||
g->Global.value = ir_add_module_constant(m, tav.type, v);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
+15
-15
@@ -490,9 +490,9 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
if (i > 0) {
|
||||
ir_fprintf(f, ", ");
|
||||
}
|
||||
TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]);
|
||||
GB_ASSERT(tav != NULL);
|
||||
ir_print_compound_element(f, m, tav->value, elem_type);
|
||||
TypeAndValue tav = type_and_value_of_expr(m->info, cl->elems.e[i]);
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
ir_print_compound_element(f, m, tav.value, elem_type);
|
||||
}
|
||||
for (isize i = elem_count; i < type->Array.count; i++) {
|
||||
if (i >= elem_count) {
|
||||
@@ -520,23 +520,23 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
ir_fprintf(f, "][");
|
||||
|
||||
if (elem_count == 1 && type->Vector.count > 1) {
|
||||
TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[0]);
|
||||
GB_ASSERT(tav != NULL);
|
||||
TypeAndValue tav = type_and_value_of_expr(m->info, cl->elems.e[0]);
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
|
||||
for (isize i = 0; i < type->Vector.count; i++) {
|
||||
if (i > 0) {
|
||||
ir_fprintf(f, ", ");
|
||||
}
|
||||
ir_print_compound_element(f, m, tav->value, elem_type);
|
||||
ir_print_compound_element(f, m, tav.value, elem_type);
|
||||
}
|
||||
} else {
|
||||
for (isize i = 0; i < elem_count; i++) {
|
||||
if (i > 0) {
|
||||
ir_fprintf(f, ", ");
|
||||
}
|
||||
TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]);
|
||||
GB_ASSERT(tav != NULL);
|
||||
ir_print_compound_element(f, m, tav->value, elem_type);
|
||||
TypeAndValue tav = type_and_value_of_expr(m->info, cl->elems.e[i]);
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
ir_print_compound_element(f, m, tav.value, elem_type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,21 +562,21 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
||||
ast_node(fv, FieldValue, cl->elems.e[i]);
|
||||
String name = fv->field->Ident.string;
|
||||
|
||||
TypeAndValue *tav = type_and_value_of_expression(m->info, fv->value);
|
||||
GB_ASSERT(tav != NULL);
|
||||
TypeAndValue tav = type_and_value_of_expr(m->info, fv->value);
|
||||
GB_ASSERT(tav.mode != Addressing_Invalid);
|
||||
|
||||
Selection sel = lookup_field(m->allocator, type, name, false);
|
||||
Entity *f = type->Record.fields[sel.index.e[0]];
|
||||
|
||||
values[f->Variable.field_index] = tav->value;
|
||||
values[f->Variable.field_index] = tav.value;
|
||||
}
|
||||
} else {
|
||||
for (isize i = 0; i < value_count; i++) {
|
||||
Entity *f = type->Record.fields_in_src_order[i];
|
||||
TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]);
|
||||
TypeAndValue tav = type_and_value_of_expr(m->info, cl->elems.e[i]);
|
||||
ExactValue val = {0};
|
||||
if (tav != NULL) {
|
||||
val = tav->value;
|
||||
if (tav.mode != Addressing_Invalid) {
|
||||
val = tav.value;
|
||||
}
|
||||
values[f->Variable.field_index] = val;
|
||||
}
|
||||
|
||||
-1305
File diff suppressed because it is too large
Load Diff
+51
-55
@@ -1547,9 +1547,9 @@ void fix_advance_to_next_stmt(AstFile *f) {
|
||||
case Token_defer:
|
||||
case Token_asm:
|
||||
case Token_using:
|
||||
case Token_immutable:
|
||||
// case Token_thread_local:
|
||||
case Token_no_alias:
|
||||
// case Token_immutable:
|
||||
// case Token_no_alias:
|
||||
|
||||
case Token_break:
|
||||
case Token_continue:
|
||||
@@ -2703,14 +2703,38 @@ AstNode *parse_var_type(AstFile *f, bool allow_ellipsis) {
|
||||
return type;
|
||||
}
|
||||
|
||||
bool is_token_field_prefix(TokenKind kind) {
|
||||
switch (kind) {
|
||||
|
||||
typedef enum FieldPrefixKind {
|
||||
FieldPrefix_Invalid,
|
||||
|
||||
FieldPrefix_Using,
|
||||
FieldPrefix_Immutable,
|
||||
FieldPrefix_NoAlias,
|
||||
} FieldPrefixKind;
|
||||
|
||||
FieldPrefixKind is_token_field_prefix(AstFile *f) {
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_EOF:
|
||||
return FieldPrefix_Invalid;
|
||||
|
||||
case Token_using:
|
||||
case Token_no_alias:
|
||||
return FieldPrefix_Using;
|
||||
|
||||
case Token_immutable:
|
||||
return true;
|
||||
return FieldPrefix_Immutable;
|
||||
|
||||
case Token_Hash: {
|
||||
next_token(f);
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_Ident:
|
||||
if (str_eq(f->curr_token.string, str_lit("no_alias"))) {
|
||||
return FieldPrefix_NoAlias;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return false;
|
||||
return FieldPrefix_Invalid;
|
||||
}
|
||||
|
||||
|
||||
@@ -2719,16 +2743,20 @@ u32 parse_field_prefixes(AstFile *f) {
|
||||
i32 no_alias_count = 0;
|
||||
i32 immutable_count = 0;
|
||||
|
||||
while (is_token_field_prefix(f->curr_token.kind)) {
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_using: using_count += 1; next_token(f); break;
|
||||
case Token_no_alias: no_alias_count += 1; next_token(f); break;
|
||||
case Token_immutable: immutable_count += 1; next_token(f); break;
|
||||
for (;;) {
|
||||
FieldPrefixKind kind = is_token_field_prefix(f);
|
||||
if (kind == FieldPrefix_Invalid) {
|
||||
break;
|
||||
}
|
||||
switch (kind) {
|
||||
case FieldPrefix_Using: using_count += 1; next_token(f); break;
|
||||
case FieldPrefix_Immutable: immutable_count += 1; next_token(f); break;
|
||||
case FieldPrefix_NoAlias: no_alias_count += 1; next_token(f); break;
|
||||
}
|
||||
}
|
||||
if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list");
|
||||
if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple `no_alias` in this field list");
|
||||
if (immutable_count > 1) syntax_error(f->curr_token, "Multiple `immutable` in this field list");
|
||||
if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple `#no_alias` in this field list");
|
||||
|
||||
|
||||
u32 field_flags = 0;
|
||||
@@ -3369,50 +3397,23 @@ AstNode *parse_for_stmt(AstFile *f) {
|
||||
}
|
||||
|
||||
|
||||
AstNode *parse_case_clause(AstFile *f) {
|
||||
AstNode *parse_case_clause(AstFile *f, bool is_type) {
|
||||
Token token = f->curr_token;
|
||||
AstNodeArray list = make_ast_node_array(f);
|
||||
if (allow_token(f, Token_case)) {
|
||||
bool prev_allow_range = f->allow_range;
|
||||
f->allow_range = true;
|
||||
expect_token(f, Token_case);
|
||||
bool prev_allow_range = f->allow_range;
|
||||
f->allow_range = !is_type;
|
||||
if (f->curr_token.kind != Token_Colon) {
|
||||
list = parse_rhs_expr_list(f);
|
||||
f->allow_range = prev_allow_range;
|
||||
} else {
|
||||
expect_token(f, Token_default);
|
||||
}
|
||||
f->allow_range = prev_allow_range;
|
||||
expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
|
||||
// expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
|
||||
AstNodeArray stmts = parse_stmt_list(f);
|
||||
|
||||
return ast_case_clause(f, token, list, stmts);
|
||||
}
|
||||
|
||||
|
||||
AstNode *parse_type_case_clause(AstFile *f) {
|
||||
Token token = f->curr_token;
|
||||
AstNodeArray list = make_ast_node_array(f);
|
||||
if (allow_token(f, Token_case)) {
|
||||
for (;;) {
|
||||
AstNode *t = parse_type(f);
|
||||
array_add(&list, t);
|
||||
if (f->curr_token.kind != Token_Comma ||
|
||||
f->curr_token.kind == Token_EOF) {
|
||||
break;
|
||||
}
|
||||
next_token(f);
|
||||
}
|
||||
} else {
|
||||
expect_token(f, Token_default);
|
||||
}
|
||||
expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax?
|
||||
// expect_token(f, Token_ArrowRight); // TODO(bill): Is this the best syntax?
|
||||
AstNodeArray stmts = parse_stmt_list(f);
|
||||
|
||||
return ast_case_clause(f, token, list, stmts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AstNode *parse_match_stmt(AstFile *f) {
|
||||
if (f->curr_proc == NULL) {
|
||||
syntax_error(f->curr_token, "You cannot use a match statement in the file scope");
|
||||
@@ -3425,6 +3426,7 @@ AstNode *parse_match_stmt(AstFile *f) {
|
||||
AstNode *body = NULL;
|
||||
Token open, close;
|
||||
bool is_type_match = false;
|
||||
AstNodeArray list = make_ast_node_array(f);
|
||||
|
||||
if (f->curr_token.kind != Token_OpenBrace) {
|
||||
isize prev_level = f->expr_level;
|
||||
@@ -3445,15 +3447,9 @@ AstNode *parse_match_stmt(AstFile *f) {
|
||||
f->expr_level = prev_level;
|
||||
}
|
||||
open = expect_token(f, Token_OpenBrace);
|
||||
AstNodeArray list = make_ast_node_array(f);
|
||||
|
||||
while (f->curr_token.kind == Token_case ||
|
||||
f->curr_token.kind == Token_default) {
|
||||
if (is_type_match) {
|
||||
array_add(&list, parse_type_case_clause(f));
|
||||
} else {
|
||||
array_add(&list, parse_case_clause(f));
|
||||
}
|
||||
while (f->curr_token.kind == Token_case) {
|
||||
array_add(&list, parse_case_clause(f, is_type_match));
|
||||
}
|
||||
|
||||
close = expect_token(f, Token_CloseBrace);
|
||||
@@ -3863,7 +3859,7 @@ AstNodeArray parse_stmt_list(AstFile *f) {
|
||||
AstNodeArray list = make_ast_node_array(f);
|
||||
|
||||
while (f->curr_token.kind != Token_case &&
|
||||
f->curr_token.kind != Token_default &&
|
||||
// f->curr_token.kind != Token_default &&
|
||||
f->curr_token.kind != Token_CloseBrace &&
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
AstNode *stmt = parse_stmt(f);
|
||||
|
||||
@@ -1051,9 +1051,9 @@ ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) {
|
||||
AstNode *sel = unparen_expr(se->selector);
|
||||
if (sel->kind == AstNode_Ident) {
|
||||
String selector = sel->Ident.string;
|
||||
TypeAndValue *tav = type_and_value_of_expression(p->module->info, se->expr);
|
||||
TypeAndValue tav = type_and_value_of_expr(p->module->info, se->expr);
|
||||
|
||||
if (tav == NULL) {
|
||||
if (tav.mode == Addressing_Invalid) {
|
||||
// NOTE(bill): Imports
|
||||
Entity *imp = entity_of_ident(p->module->info, se->expr);
|
||||
if (imp != NULL) {
|
||||
@@ -1063,8 +1063,8 @@ ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) {
|
||||
}
|
||||
|
||||
|
||||
Type *type = base_type(tav->type);
|
||||
if (tav->mode == Addressing_Type) { // Addressing_Type
|
||||
Type *type = base_type(tav.type);
|
||||
if (tav.mode == Addressing_Type) { // Addressing_Type
|
||||
GB_PANIC("TODO: SelectorExpr Addressing_Type");
|
||||
// Selection sel = lookup_field(p->allocator, type, selector, true);
|
||||
// Entity *e = sel.entity;
|
||||
@@ -1099,7 +1099,7 @@ ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) {
|
||||
} else {
|
||||
Type *type = base_type(type_of_expr(p->module->info, se->expr));
|
||||
GB_ASSERT(is_type_integer(type));
|
||||
ExactValue val = type_and_value_of_expression(p->module->info, sel)->value;
|
||||
ExactValue val = type_and_value_of_expr(p->module->info, sel).value;
|
||||
i64 index = val.value_integer;
|
||||
|
||||
Selection sel = lookup_field_from_index(p->allocator, type, index);
|
||||
@@ -1635,43 +1635,43 @@ ssaValue *ssa_emit_logical_binary_expr(ssaProc *p, AstNode *expr) {
|
||||
ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
|
||||
TypeAndValue *tv = map_tav_get(&p->module->info->types, hash_pointer(expr));
|
||||
GB_ASSERT_NOT_NULL(tv);
|
||||
TypeAndValue tv = type_and_value_of_expr(p->module->info, expr);
|
||||
GB_ASSERT(tv.mode != Addressing_Invalid);
|
||||
|
||||
if (tv->value.kind != ExactValue_Invalid) {
|
||||
Type *t = core_type(tv->type);
|
||||
if (tv.value.kind != ExactValue_Invalid) {
|
||||
Type *t = core_type(tv.type);
|
||||
if (is_type_boolean(t)) {
|
||||
return ssa_const_bool(p, tv->type, tv->value.value_bool);
|
||||
return ssa_const_bool(p, tv.type, tv.value.value_bool);
|
||||
} else if (is_type_string(t)) {
|
||||
GB_ASSERT(tv->value.kind == ExactValue_String);
|
||||
return ssa_const_string(p, tv->type, tv->value.value_string);
|
||||
GB_ASSERT(tv.value.kind == ExactValue_String);
|
||||
return ssa_const_string(p, tv.type, tv.value.value_string);
|
||||
} else if(is_type_slice(t)) {
|
||||
return ssa_const_slice(p, tv->type, tv->value);
|
||||
return ssa_const_slice(p, tv.type, tv.value);
|
||||
} else if (is_type_integer(t)) {
|
||||
GB_ASSERT(tv->value.kind == ExactValue_Integer);
|
||||
GB_ASSERT(tv.value.kind == ExactValue_Integer);
|
||||
|
||||
i64 s = 8*type_size_of(p->allocator, t);
|
||||
switch (s) {
|
||||
case 8: return ssa_const_i8 (p, tv->type, tv->value.value_integer);
|
||||
case 16: return ssa_const_i16(p, tv->type, tv->value.value_integer);
|
||||
case 32: return ssa_const_i32(p, tv->type, tv->value.value_integer);
|
||||
case 64: return ssa_const_i64(p, tv->type, tv->value.value_integer);
|
||||
case 8: return ssa_const_i8 (p, tv.type, tv.value.value_integer);
|
||||
case 16: return ssa_const_i16(p, tv.type, tv.value.value_integer);
|
||||
case 32: return ssa_const_i32(p, tv.type, tv.value.value_integer);
|
||||
case 64: return ssa_const_i64(p, tv.type, tv.value.value_integer);
|
||||
default: GB_PANIC("Unknown integer size");
|
||||
}
|
||||
} else if (is_type_float(t)) {
|
||||
GB_ASSERT(tv->value.kind == ExactValue_Float);
|
||||
GB_ASSERT(tv.value.kind == ExactValue_Float);
|
||||
i64 s = 8*type_size_of(p->allocator, t);
|
||||
switch (s) {
|
||||
case 32: return ssa_const_f32(p, tv->type, tv->value.value_float);
|
||||
case 64: return ssa_const_f64(p, tv->type, tv->value.value_float);
|
||||
case 32: return ssa_const_f32(p, tv.type, tv.value.value_float);
|
||||
case 64: return ssa_const_f64(p, tv.type, tv.value.value_float);
|
||||
default: GB_PANIC("Unknown float size");
|
||||
}
|
||||
}
|
||||
// IMPORTANT TODO(bill): Do constant record/array literals correctly
|
||||
return ssa_const_nil(p, tv->type);
|
||||
return ssa_const_nil(p, tv.type);
|
||||
}
|
||||
|
||||
if (tv->mode == Addressing_Variable) {
|
||||
if (tv.mode == Addressing_Variable) {
|
||||
return ssa_addr_load(p, ssa_build_addr(p, expr));
|
||||
}
|
||||
|
||||
@@ -1716,12 +1716,12 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
||||
return ssa_build_addr(p, ue->expr).addr;
|
||||
}
|
||||
ssaValue *x = ssa_build_expr(p, ue->expr);
|
||||
return ssa_emit_unary_arith(p, ue->op.kind, x, tv->type);
|
||||
return ssa_emit_unary_arith(p, ue->op.kind, x, tv.type);
|
||||
|
||||
case_end;
|
||||
|
||||
case_ast_node(be, BinaryExpr, expr);
|
||||
Type *type = default_type(tv->type);
|
||||
Type *type = default_type(tv.type);
|
||||
|
||||
switch (be->op.kind) {
|
||||
case Token_Add:
|
||||
@@ -1803,7 +1803,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
||||
ssa_emit_jump(p, done);
|
||||
ssa_start_block(p, done);
|
||||
|
||||
return ssa_new_value2(p, ssaOp_Phi, tv->type, yes, no);
|
||||
return ssa_new_value2(p, ssaOp_Phi, tv.type, yes, no);
|
||||
case_end;
|
||||
|
||||
|
||||
@@ -1840,7 +1840,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
||||
if (map_tav_get(&p->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
|
||||
GB_ASSERT(ce->args.count == 1);
|
||||
ssaValue *x = ssa_build_expr(p, ce->args.e[0]);
|
||||
return ssa_emit_conv(p, x, tv->type);
|
||||
return ssa_emit_conv(p, x, tv.type);
|
||||
}
|
||||
|
||||
AstNode *p = unparen_expr(ce->proc);
|
||||
|
||||
@@ -88,14 +88,12 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_for, "for"), \
|
||||
TOKEN_KIND(Token_in, "in"), \
|
||||
TOKEN_KIND(Token_match, "match"), \
|
||||
TOKEN_KIND(Token_default, "default"), \
|
||||
TOKEN_KIND(Token_case, "case"), \
|
||||
TOKEN_KIND(Token_break, "break"), \
|
||||
TOKEN_KIND(Token_continue, "continue"), \
|
||||
TOKEN_KIND(Token_fallthrough, "fallthrough"), \
|
||||
TOKEN_KIND(Token_defer, "defer"), \
|
||||
TOKEN_KIND(Token_return, "return"), \
|
||||
TOKEN_KIND(Token_give, "give"), \
|
||||
TOKEN_KIND(Token_proc, "proc"), \
|
||||
TOKEN_KIND(Token_macro, "macro"), \
|
||||
TOKEN_KIND(Token_struct, "struct"), \
|
||||
@@ -107,7 +105,6 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_dynamic, "dynamic"), \
|
||||
TOKEN_KIND(Token_map, "map"), \
|
||||
TOKEN_KIND(Token_using, "using"), \
|
||||
TOKEN_KIND(Token_no_alias, "no_alias"), \
|
||||
TOKEN_KIND(Token_immutable, "immutable"), \
|
||||
TOKEN_KIND(Token_context, "context"), \
|
||||
TOKEN_KIND(Token_push_context, "push_context"), \
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ typedef enum BasicKind {
|
||||
Basic_UntypedRune,
|
||||
Basic_UntypedNil,
|
||||
|
||||
Basic_Count,
|
||||
Basic_COUNT,
|
||||
|
||||
Basic_byte = Basic_u8,
|
||||
Basic_rune = Basic_i32,
|
||||
@@ -290,10 +290,10 @@ gb_global Type *t_untyped_quaternion = &basic_types[Basic_UntypedQuaternion];
|
||||
gb_global Type *t_untyped_string = &basic_types[Basic_UntypedString];
|
||||
gb_global Type *t_untyped_rune = &basic_types[Basic_UntypedRune];
|
||||
gb_global Type *t_untyped_nil = &basic_types[Basic_UntypedNil];
|
||||
|
||||
gb_global Type *t_byte = &basic_type_aliases[0];
|
||||
gb_global Type *t_rune = &basic_type_aliases[1];
|
||||
|
||||
|
||||
gb_global Type *t_u8_ptr = NULL;
|
||||
gb_global Type *t_int_ptr = NULL;
|
||||
gb_global Type *t_i64_ptr = NULL;
|
||||
|
||||
Reference in New Issue
Block a user