enum_to_string fix; enum count, min_value, max_value

This commit is contained in:
Ginger Bill
2016-09-19 22:26:07 +01:00
parent 9561dc33ce
commit 3b266b194f
14 changed files with 174 additions and 77 deletions
+23 -17
View File
@@ -1,5 +1,27 @@
#import "fmt.odin" as fmt
main :: proc() {
Fruit :: enum {
APPLE = -2,
BANANA,
GRAPE,
MELON = 123,
TOMATO,
}
s1 := enum_to_string(Fruit.BANANA)
e := Fruit.MELON
s2 := enum_to_string(e)
fmt.println(Fruit.APPLE)
fmt.println(Fruit.count)
fmt.println(Fruit.min_value)
fmt.println(Fruit.max_value)
}
// #import "fmt.odin" as fmt
// #foreign_system_library "Ws2_32"
// WSADESCRIPTION_LEN :: 256
@@ -147,7 +169,7 @@
// <title>Demo Title</title>
// </head>
// <body>
// <h1 style="color: red;">Odin Server Demo</h1>
// <h1 style="color: orange;">Odin Server Demo</h1>
// </body>
// </html>
// `
@@ -174,19 +196,3 @@
// shutdown(client, SD_SEND)
// }
main :: proc() {
Fruit :: enum {
APPLE,
BANANA,
GRAPE,
MELON,
}
s1 := enum_to_string(Fruit.APPLE)
e := Fruit.APPLE
s2 := enum_to_string(e)
fmt.println(s1)
fmt.println(s2)
}
+24 -4
View File
@@ -437,10 +437,30 @@ print_any_to_buffer :: proc(buf: ^[]byte, arg: any) {
print_pointer_to_buffer(buf, v)
case Enum:
v: any
v.data = arg.data
v.type_info = info.base
print_any_to_buffer(buf, v)
value: i64 = 0
match type i : info.base {
case Integer:
if i.signed {
if arg.data != null {
match i.size {
case 1: value = (arg.data as ^i8)^ as i64
case 2: value = (arg.data as ^i16)^ as i64
case 4: value = (arg.data as ^i32)^ as i64
case 8: value = (arg.data as ^i64)^ as i64
}
}
} else {
if arg.data != null {
match i.size {
case 1: value = (arg.data as ^u8)^ as i64
case 2: value = (arg.data as ^u16)^ as i64
case 4: value = (arg.data as ^u32)^ as i64
case 8: value = (arg.data as ^u64)^ as i64
}
}
}
}
print_string_to_buffer(buf, __enum_to_string(arg.type_info, value))
case Array:
-1
View File
@@ -354,7 +354,6 @@ __enum_to_string :: proc(info: ^Type_Info, value: i64) -> string {
match type ti : info {
case Type_Info.Enum:
fmt.println("Here: ", ti.values.count)
for i := 0; i < ti.values.count; i++ {
if ti.values[i] == value {
return ti.names[i]
+3 -3
View File
@@ -631,7 +631,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
}
b32 add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
if (!are_strings_equal(entity->token.string, make_string("_"))) {
if (entity->token.string != make_string("_")) {
Entity *insert_entity = scope_insert_entity(scope, entity);
if (insert_entity) {
Entity *up = insert_entity->using_parent;
@@ -676,7 +676,7 @@ void add_entity_use(CheckerInfo *i, AstNode *identifier, Entity *entity) {
void add_file_entity(Checker *c, Scope *file_scope, AstNode *identifier, Entity *e, DeclInfo *d) {
GB_ASSERT(are_strings_equal(identifier->Ident.string, e->token.string));
GB_ASSERT(identifier->Ident.string == e->token.string);
add_entity(c, file_scope, identifier, e);
map_set(&c->info.entities, hash_pointer(e), d);
}
@@ -1048,7 +1048,7 @@ void check_parsed_files(Checker *c) {
warning(id->token, "Multiple #import of the same file within this scope");
}
if (are_strings_equal(id->import_name.string, make_string("_"))) {
if (id->import_name.string == make_string("_")) {
// NOTE(bill): Add imported entities to this file's scope
gb_for_array(elem_index, scope->elements.entries) {
Entity *e = scope->elements.entries[elem_index].value;
+36 -5
View File
@@ -545,6 +545,7 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec
}
void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *node) {
GB_ASSERT(node->kind == AstNode_EnumType);
GB_ASSERT(is_type_enum(enum_type));
@@ -571,12 +572,37 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
Entity **fields = gb_alloc_array(c->allocator, Entity *, gb_array_count(et->fields));
isize field_index = 0;
ExactValue iota = make_exact_value_integer(-1);
i64 min_value = 0;
i64 max_value = 0;
Type *constant_type = enum_type;
if (named_type != NULL) {
constant_type = named_type;
}
Token blank_token = {Token_Identifier};
blank_token.string = make_string("");
Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));;
gb_for_array(i, et->fields) {
AstNode *field = et->fields[i];
ast_node(f, FieldValue, field);
Token name_token = f->field->Ident;
if (name_token.string == make_string("count")) {
error(name_token, "`count` is a reserved identifier for enums");
fields[field_index++] = blank_entity;
continue;
} else if (name_token.string == make_string("min_value")) {
error(name_token, "`min_value` is a reserved identifier for enums");
fields[field_index++] = blank_entity;
continue;
} else if (name_token.string == make_string("max_value")) {
error(name_token, "`max_value` is a reserved identifier for enums");
fields[field_index++] = blank_entity;
continue;
}
Operand o = {};
if (f->value != NULL) {
check_expr(c, &o, f->value);
@@ -598,11 +624,14 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
iota = exact_binary_operator_value(add_token, iota, make_exact_value_integer(1));
}
Type *constant_type = enum_type;
if (named_type != NULL) {
constant_type = named_type;
}
Entity *e = make_entity_constant(c->allocator, c->context.scope, name_token, constant_type, iota);
if (min_value > iota.value_integer) {
min_value = iota.value_integer;
}
if (max_value < iota.value_integer) {
max_value = iota.value_integer;
}
HashKey key = hash_string(name_token.string);
if (map_get(&entity_map, key)) {
@@ -614,6 +643,8 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
}
add_entity_use(&c->info, f->field, e);
}
enum_type->Record.min_value = min_value;
enum_type->Record.max_value = max_value;
enum_type->Record.other_fields = fields;
enum_type->Record.other_field_count = gb_array_count(et->fields);
}
@@ -732,7 +763,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
o->expr = n;
Entity *e = scope_lookup_entity(c->context.scope, n->Ident.string);
if (e == NULL) {
if (are_strings_equal(n->Ident.string, make_string("_"))) {
if (n->Ident.string == make_string("_")) {
error(n->Ident, "`_` cannot be used as a value type");
} else {
auto *entries = c->context.scope->elements.entries;
+3 -3
View File
@@ -162,7 +162,7 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
// NOTE(bill): Ignore assignments to `_`
if (node->kind == AstNode_Ident) {
ast_node(i, Ident, node);
if (are_strings_equal(i->string, make_string("_"))) {
if (i->string == make_string("_")) {
add_entity_definition(&c->info, node, NULL);
check_assignment(c, op_a, NULL, make_string("assignment to `_` identifier"));
if (op_a->mode == Addressing_Invalid)
@@ -503,7 +503,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
if ((d->scope->is_file || d->scope->is_global) &&
are_strings_equal(e->token.string, make_string("main"))) {
e->token.string == make_string("main")) {
if (proc_type != NULL) {
auto *pt = &proc_type->Proc;
if (pt->param_count != 0 ||
@@ -701,7 +701,7 @@ void check_var_decl_node(Checker *c, AstNode *node) {
String str = token.string;
Entity *found = NULL;
// NOTE(bill): Ignore assignments to `_`
b32 can_be_ignored = are_strings_equal(str, make_string("_"));
b32 can_be_ignored = str == make_string("_");
if (!can_be_ignored) {
found = current_scope_lookup_entity(c->context.scope, str);
}
+44 -15
View File
@@ -120,6 +120,8 @@ struct Type {
// enum only
Type * enum_base; // Default is `int`
i64 min_value;
i64 max_value;
// struct only
i64 * struct_offsets;
@@ -710,12 +712,12 @@ 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;
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);
if (are_strings_equal(field_name, make_string("_"))) {
if (field_name == make_string("_")) {
return empty_selection;
}
@@ -740,11 +742,11 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
entity__any_data = make_entity_field(a, NULL, token, t_rawptr, false, 1);
}
if (are_strings_equal(field_name, type_info_str)) {
if (field_name == type_info_str) {
selection_add_index(&sel, 0);
sel.entity = entity__any_type_info;
return sel;
} else if (are_strings_equal(field_name, data_str)) {
} else if (field_name == data_str) {
selection_add_index(&sel, 1);
sel.entity = entity__any_data;
return sel;
@@ -765,11 +767,11 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
entity__string_count = make_entity_field(a, NULL, token, t_int, false, 1);
}
if (are_strings_equal(field_name, data_str)) {
if (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)) {
} else if (field_name == count_str) {
selection_add_index(&sel, 1);
sel.entity = entity__string_count;
return sel;
@@ -780,8 +782,8 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
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)) {
// NOTE(bill): Underlying memory address cannot be changed
if (field_name == count_str) {
Token token = {Token_Identifier};
token.string = count_str;
// HACK(bill): Memory leak
@@ -791,7 +793,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
} 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)) {
if (field_name == count_str) {
Token token = {Token_Identifier};
token.string = count_str;
// HACK(bill): Memory leak
@@ -803,21 +805,21 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
String count_str = make_string("count");
String capacity_str = make_string("capacity");
if (are_strings_equal(field_name, data_str)) {
if (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)) {
} else if (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)) {
} else if (field_name == capacity_str) {
selection_add_index(&sel, 2);
Token token = {Token_Identifier};
token.string = capacity_str;
@@ -837,7 +839,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
GB_ASSERT(f->kind == Entity_TypeName);
String str = f->token.string;
if (are_strings_equal(field_name, str)) {
if (field_name == str) {
return make_selection(f, NULL, i);
}
}
@@ -848,16 +850,43 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
GB_ASSERT(f->kind != Entity_Variable);
String str = f->token.string;
if (are_strings_equal(field_name, str)) {
if (field_name == str) {
return make_selection(f, NULL, i);
}
}
if (is_type_enum(type)) {
String count_str = make_string("count");
String min_value_str = make_string("min_value");
String max_value_str = make_string("max_value");
if (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->Record.other_field_count));
return sel;
} else if (field_name == min_value_str) {
Token token = {Token_Identifier};
token.string = min_value_str;
// HACK(bill): Memory leak
sel.entity = make_entity_constant(a, NULL, token, type->Record.enum_base, make_exact_value_integer(type->Record.min_value));
return sel;
} else if (field_name == max_value_str) {
Token token = {Token_Identifier};
token.string = max_value_str;
// HACK(bill): Memory leak
sel.entity = make_entity_constant(a, NULL, token, type->Record.enum_base, make_exact_value_integer(type->Record.max_value));
return sel;
}
}
} else if (!is_type_enum(type) && !is_type_union(type)) {
for (isize i = 0; i < type->Record.field_count; i++) {
Entity *f = type->Record.fields[i];
GB_ASSERT(f->kind == Entity_Variable && f->Variable.is_field);
String str = f->token.string;
if (are_strings_equal(field_name, str)) {
if (field_name == str) {
selection_add_index(&sel, i);
sel.entity = f;
return sel;
+1
View File
@@ -16,6 +16,7 @@ b32 ssa_gen_init(ssaGen *s, Checker *c) {
}
ssa_init_module(&s->module, c);
s->module.generate_debug_info = false;
// TODO(bill): generate appropriate output name
isize pos = string_extension_position(c->parser->init_fullpath);
+4 -2
View File
@@ -121,7 +121,7 @@ void ssa_print_encoded_local(ssaFileBuffer *f, String name) {
void ssa_print_encoded_global(ssaFileBuffer *f, String name, b32 global_scope) {
ssa_fprintf(f, "@");
if (!global_scope && !are_strings_equal(name, make_string("main"))) {
if (!global_scope && name != make_string("main")) {
ssa_fprintf(f, ".");
}
ssa_print_escape_string(f, name, true);
@@ -818,7 +818,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
if (proc->module->generate_debug_info && proc->entity != NULL) {
ssaDebugInfo *di = *map_get(&proc->module->debug_info, hash_pointer(proc->entity));
GB_ASSERT(di->kind == ssaDebugInfo_Proc);
ssa_fprintf(f, "!dbg !%d ", di->id);
ssa_fprintf(f, "!dbg !%d ", di->id);
}
@@ -839,6 +839,8 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
}
}
ssa_fprintf(f, "}\n");
} else {
ssa_fprintf(f, "\n");
}
gb_for_array(i, proc->children) {
+3 -3
View File
@@ -1566,7 +1566,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
if (value->kind == ssaValue_Constant) {
if (is_type_any(dst)) {
Type *dt = default_type(src);
Type *dt = default_type(get_base_type(src_type));
ssaValue *default_value = ssa_add_local_generated(proc, dt);
ssa_emit_store(proc, default_value, value);
return ssa_emit_conv(proc, ssa_emit_load(proc, default_value), t_any, is_argument);
@@ -3680,14 +3680,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
void ssa_emit_startup_runtime(ssaProcedure *proc) {
GB_ASSERT(proc->parent == NULL && are_strings_equal(proc->name, make_string("main")));
GB_ASSERT(proc->parent == NULL && proc->name == make_string("main"));
ssa_emit(proc, ssa_alloc_instr(proc, ssaInstr_StartupRuntime));
}
void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) {
if (parent == NULL) {
if (are_strings_equal(proc->name, make_string("main"))) {
if (proc->name == make_string("main")) {
ssa_emit_startup_runtime(proc);
}
}
+1 -1
View File
@@ -51,7 +51,7 @@ b32 hash_key_equal(HashKey a, HashKey b) {
if (a.key == b.key) {
// NOTE(bill): If two string's hashes collide, compare the strings themselves
if (a.is_string) {
if (b.is_string) return are_strings_equal(a.string, b.string);
if (b.is_string) return a.string == b.string;
return false;
}
return true;
+19 -19
View File
@@ -1179,11 +1179,11 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
String tag_name = te->name.string;
#define ELSE_IF_ADD_TAG(name) \
else if (are_strings_equal(tag_name, make_string(#name))) { \
else if (tag_name == make_string(#name)) { \
check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \
}
if (are_strings_equal(tag_name, make_string("foreign"))) {
if (tag_name == make_string("foreign")) {
check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name);
if (f->cursor[0].kind == Token_String) {
*foreign_name = f->cursor[0].string;
@@ -1194,7 +1194,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
next_token(f);
}
} else if (are_strings_equal(tag_name, make_string("link_name"))) {
} else if (tag_name == make_string("link_name")) {
check_proc_add_tag(f, tag_expr, tags, ProcTag_link_name, tag_name);
if (f->cursor[0].kind == Token_String) {
*link_name = f->cursor[0].string;
@@ -1277,7 +1277,7 @@ AstNode *parse_operand(AstFile *f, b32 lhs) {
case Token_Hash: {
operand = parse_tag_expr(f, NULL);
String name = operand->TagExpr.name.string;
if (are_strings_equal(name, make_string("rune"))) {
if (name == make_string("rune")) {
if (f->cursor[0].kind == Token_String) {
Token *s = &f->cursor[0];
@@ -1289,12 +1289,12 @@ AstNode *parse_operand(AstFile *f, b32 lhs) {
expect_token(f, Token_String);
}
operand = parse_operand(f, lhs);
} else if (are_strings_equal(name, make_string("file"))) {
} else if (name == make_string("file")) {
Token token = operand->TagExpr.name;
token.kind = Token_String;
token.string = token.pos.file;
return make_basic_lit(f, token);
} else if (are_strings_equal(name, make_string("line"))) {
} else if (name == make_string("line")) {
Token token = operand->TagExpr.name;
token.kind = Token_Integer;
char *str = gb_alloc_array(gb_arena_allocator(&f->arena), char, 20);
@@ -1930,11 +1930,11 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
b32 is_ordered = false;
while (allow_token(f, Token_Hash)) {
Token tag = expect_token(f, Token_Identifier);
if (are_strings_equal(tag.string, make_string("packed"))) {
if (tag.string == make_string("packed")) {
is_packed = true;
} else if (are_strings_equal(tag.string, make_string("ordered"))) {
} else if (tag.string == make_string("ordered")) {
is_ordered = true;
} else {
} else {
syntax_error(tag, "Expected a `#packed` or `#ordered` tag");
}
}
@@ -2137,7 +2137,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
if (name->kind == AstNode_Ident) {
String n = name->Ident.string;
// NOTE(bill): Check for reserved identifiers
if (are_strings_equal(n, make_string("context"))) {
if (n == make_string("context")) {
syntax_error(ast_node_token(name), "`context` is a reserved identifier");
break;
}
@@ -2578,14 +2578,14 @@ AstNode *parse_stmt(AstFile *f) {
case Token_Hash: {
s = parse_tag_stmt(f, NULL);
String tag = s->TagStmt.name.string;
if (are_strings_equal(tag, make_string("shared_global_scope"))) {
if (tag == make_string("shared_global_scope")) {
if (f->curr_proc == NULL) {
f->is_global_scope = true;
return make_empty_stmt(f, f->cursor[0]);
}
syntax_error(token, "You cannot use #shared_global_scope within a procedure. This must be done at the file scope.");
return make_bad_decl(f, token, f->cursor[0]);
} else if (are_strings_equal(tag, make_string("import"))) {
} else if (tag == make_string("import")) {
// TODO(bill): better error messages
Token import_name;
Token file_path = expect_token(f, Token_String);
@@ -2597,7 +2597,7 @@ AstNode *parse_stmt(AstFile *f) {
}
syntax_error(token, "You cannot use #import within a procedure. This must be done at the file scope.");
return make_bad_decl(f, token, file_path);
} else if (are_strings_equal(tag, make_string("load"))) {
} else if (tag == make_string("load")) {
// TODO(bill): better error messages
Token file_path = expect_token(f, Token_String);
Token import_name = file_path;
@@ -2608,14 +2608,14 @@ AstNode *parse_stmt(AstFile *f) {
}
syntax_error(token, "You cannot use #load within a procedure. This must be done at the file scope.");
return make_bad_decl(f, token, file_path);
} else if (are_strings_equal(tag, make_string("foreign_system_library"))) {
} else if (tag == make_string("foreign_system_library")) {
Token file_path = expect_token(f, Token_String);
if (f->curr_proc == NULL) {
return make_foreign_system_library(f, s->TagStmt.token, file_path);
}
syntax_error(token, "You cannot use #foreign_system_library within a procedure. This must be done at the file scope.");
return make_bad_decl(f, token, file_path);
} else if (are_strings_equal(tag, make_string("thread_local"))) {
} else if (tag == make_string("thread_local")) {
AstNode *var_decl = parse_simple_stmt(f);
if (var_decl->kind != AstNode_VarDecl) {
syntax_error(token, "#thread_local may only be applied to variable declarations");
@@ -2627,14 +2627,14 @@ AstNode *parse_stmt(AstFile *f) {
}
var_decl->VarDecl.tags |= VarDeclTag_thread_local;
return var_decl;
} else if (are_strings_equal(tag, make_string("bounds_check"))) {
} else if (tag == make_string("bounds_check")) {
s = parse_stmt(f);
s->stmt_state_flags |= StmtStateFlag_bounds_check;
if ((s->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) {
syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together");
}
return s;
} else if (are_strings_equal(tag, make_string("no_bounds_check"))) {
} else if (tag == make_string("no_bounds_check")) {
s = parse_stmt(f);
s->stmt_state_flags |= StmtStateFlag_no_bounds_check;
if ((s->stmt_state_flags & StmtStateFlag_bounds_check) != 0) {
@@ -2760,7 +2760,7 @@ void destroy_parser(Parser *p) {
b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
gb_for_array(i, p->imports) {
String import = p->imports[i].path;
if (are_strings_equal(import, path)) {
if (import == path) {
return false;
}
}
@@ -2814,7 +2814,7 @@ String get_fullpath_core(gbAllocator a, String path) {
b32 try_add_foreign_system_library_path(Parser *p, String import_file) {
gb_for_array(i, p->system_libraries) {
String import = p->system_libraries[i];
if (are_strings_equal(import, import_file)) {
if (import == import_file) {
return false;
}
}
+9
View File
@@ -88,6 +88,15 @@ GB_COMPARE_PROC(string_cmp_proc) {
}
bool operator ==(String a, String b) { return are_strings_equal(a, b) != 0; }
bool operator !=(String a, String b) { return !operator==(a, b); }
bool operator < (String a, String b) { return string_compare(a, b) < 0; }
bool operator > (String a, String b) { return string_compare(a, b) > 0; }
bool operator <=(String a, String b) { return string_compare(a, b) <= 0; }
bool operator >=(String a, String b) { return string_compare(a, b) >= 0; }
gb_inline isize string_extension_position(String str) {
isize dot_pos = -1;
isize i = str.len;
+4 -4
View File
@@ -675,15 +675,15 @@ Token tokenizer_get_token(Tokenizer *t) {
// NOTE(bill): All keywords are > 1
if (token.string.len > 1) {
if (are_strings_equal(token.string, token_strings[Token_as])) {
if (token.string == token_strings[Token_as]) {
token.kind = Token_as;
} else if (are_strings_equal(token.string, token_strings[Token_transmute])) {
} else if (token.string == token_strings[Token_transmute]) {
token.kind = Token_transmute;
} else if (are_strings_equal(token.string, token_strings[Token_down_cast])) {
} else if (token.string == token_strings[Token_down_cast]) {
token.kind = Token_down_cast;
} else {
for (i32 k = Token__KeywordBegin+1; k < Token__KeywordEnd; k++) {
if (are_strings_equal(token.string, token_strings[k])) {
if (token.string == token_strings[k]) {
token.kind = cast(TokenKind)k;
break;
}