@@ -3227,9 +3227,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
3227
3227
}
3228
3228
3229
3229
{
3230
- auto entry = g->primitive_type_table .maybe_get (tld->name );
3231
- if (entry) {
3232
- TypeTableEntry *type = entry->value ;
3230
+ TypeTableEntry *type = get_primitive_type (g, tld->name );
3231
+ if (type != nullptr ) {
3233
3232
add_node_error (g, tld->source_node ,
3234
3233
buf_sprintf (" declaration shadows type '%s'" , buf_ptr (&type->name )));
3235
3234
}
@@ -3474,9 +3473,8 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
3474
3473
add_error_note (g, msg, existing_var->decl_node , buf_sprintf (" previous declaration is here" ));
3475
3474
variable_entry->value ->type = g->builtin_types .entry_invalid ;
3476
3475
} else {
3477
- auto primitive_table_entry = g->primitive_type_table .maybe_get (name);
3478
- if (primitive_table_entry) {
3479
- TypeTableEntry *type = primitive_table_entry->value ;
3476
+ TypeTableEntry *type = get_primitive_type (g, name);
3477
+ if (type != nullptr ) {
3480
3478
add_node_error (g, source_node,
3481
3479
buf_sprintf (" variable shadows type '%s'" , buf_ptr (&type->name )));
3482
3480
variable_entry->value ->type = g->builtin_types .entry_invalid ;
@@ -4307,43 +4305,7 @@ void semantic_analyze(CodeGen *g) {
4307
4305
}
4308
4306
}
4309
4307
4310
- TypeTableEntry **get_int_type_ptr (CodeGen *g, bool is_signed, uint32_t size_in_bits) {
4311
- size_t index;
4312
- if (size_in_bits == 2 ) {
4313
- index = 0 ;
4314
- } else if (size_in_bits == 3 ) {
4315
- index = 1 ;
4316
- } else if (size_in_bits == 4 ) {
4317
- index = 2 ;
4318
- } else if (size_in_bits == 5 ) {
4319
- index = 3 ;
4320
- } else if (size_in_bits == 6 ) {
4321
- index = 4 ;
4322
- } else if (size_in_bits == 7 ) {
4323
- index = 5 ;
4324
- } else if (size_in_bits == 8 ) {
4325
- index = 6 ;
4326
- } else if (size_in_bits == 16 ) {
4327
- index = 7 ;
4328
- } else if (size_in_bits == 29 ) {
4329
- index = 8 ;
4330
- } else if (size_in_bits == 32 ) {
4331
- index = 9 ;
4332
- } else if (size_in_bits == 64 ) {
4333
- index = 10 ;
4334
- } else if (size_in_bits == 128 ) {
4335
- index = 11 ;
4336
- } else {
4337
- return nullptr ;
4338
- }
4339
- return &g->builtin_types .entry_int [is_signed ? 0 : 1 ][index];
4340
- }
4341
-
4342
4308
TypeTableEntry *get_int_type (CodeGen *g, bool is_signed, uint32_t size_in_bits) {
4343
- TypeTableEntry **common_entry = get_int_type_ptr (g, is_signed, size_in_bits);
4344
- if (common_entry)
4345
- return *common_entry;
4346
-
4347
4309
TypeId type_id = {};
4348
4310
type_id.id = TypeTableEntryIdInt;
4349
4311
type_id.data .integer .is_signed = is_signed;
@@ -4953,6 +4915,8 @@ bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type) {
4953
4915
while (scope) {
4954
4916
if (scope->id == ScopeIdVarDecl) {
4955
4917
ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
4918
+ if (type_is_invalid (var_scope->var ->value ->type ))
4919
+ return false ;
4956
4920
if (can_mutate_comptime_var_state (var_scope->var ->value ))
4957
4921
return false ;
4958
4922
} else if (scope->id == ScopeIdFnDef) {
@@ -6310,3 +6274,28 @@ bool type_can_fail(TypeTableEntry *type_entry) {
6310
6274
bool fn_type_can_fail (FnTypeId *fn_type_id) {
6311
6275
return type_can_fail (fn_type_id->return_type ) || fn_type_id->cc == CallingConventionAsync;
6312
6276
}
6277
+
6278
+ TypeTableEntry *get_primitive_type (CodeGen *g, Buf *name) {
6279
+ if (buf_len (name) >= 2 ) {
6280
+ uint8_t first_c = buf_ptr (name)[0 ];
6281
+ if (first_c == ' i' || first_c == ' u' ) {
6282
+ for (size_t i = 1 ; i < buf_len (name); i += 1 ) {
6283
+ uint8_t c = buf_ptr (name)[i];
6284
+ if (c < ' 0' || c > ' 9' ) {
6285
+ goto not_integer;
6286
+ }
6287
+ }
6288
+ bool is_signed = (first_c == ' i' );
6289
+ uint32_t bit_count = atoi (buf_ptr (name) + 1 );
Collapse comment Comment on line R6289
atoi parses to an int instead of u32 and it doesn't do any error handling (undefined if out of range).
If only you could write this in some language that didn't allow you to forget to handle errors! ;)
Curiously it works though. =D
Indeed, you can bet your bottom dollar the self hosted version will use std.fmt.parseUnsigned
and handle the error code!
Code has comments. Press enter to view.
6290
+ return get_int_type (g, is_signed, bit_count);
6291
+ }
6292
+ }
6293
+
6294
+ not_integer:
6295
+
6296
+ auto primitive_table_entry = g->primitive_type_table .maybe_get (name);
6297
+ if (primitive_table_entry != nullptr ) {
6298
+ return primitive_table_entry->value ;
6299
+ }
6300
+ return nullptr ;
6301
+ }
0 commit comments