aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-11-28 20:39:43 +0000
committerGinger Bill <bill@gingerbill.org>2016-11-28 20:39:43 +0000
commit598dab5bc4fb2836c8f2a6cad757dcb3760a895f (patch)
tree957f92585cae2e41bee93ce0b9d493b5178a0f54 /src
parentcbb70c78731b9d928508a52180a186b178d30a5e (diff)
#rune "" to ''; Remove infix and postfix call notation
Diffstat (limited to 'src')
-rw-r--r--src/array.c6
-rw-r--r--src/checker/checker.c18
-rw-r--r--src/checker/expr.c32
-rw-r--r--src/checker/types.c3
-rw-r--r--src/common.c20
-rw-r--r--src/exact_value.c36
-rw-r--r--src/map.c9
-rw-r--r--src/parser.c156
-rw-r--r--src/ssa.c19
-rw-r--r--src/string.c187
-rw-r--r--src/timings.c7
-rw-r--r--src/tokenizer.c59
-rw-r--r--src/unicode.c2
13 files changed, 285 insertions, 269 deletions
diff --git a/src/array.c b/src/array.c
index 7e185e872..d169a99ef 100644
--- a/src/array.c
+++ b/src/array.c
@@ -11,8 +11,8 @@ GB_STATIC_ASSERT(ARRAY_GROW_FORMULA(0) > 0);
typedef Array(void) ArrayVoid;
#define array_init_reserve(x_, allocator_, init_capacity_) do { \
- GB_ASSERT((x_) != NULL); \
void **e = cast(void **)&((x_)->e); \
+ GB_ASSERT((x_) != NULL); \
(x_)->allocator = (allocator_); \
(x_)->count = 0; \
(x_)->capacity = (init_capacity_); \
@@ -20,8 +20,8 @@ typedef Array(void) ArrayVoid;
} while (0)
#define array_init_count(x_, allocator_, init_count_) do { \
- GB_ASSERT((x_) != NULL); \
void **e = cast(void **)&((x_)->e); \
+ GB_ASSERT((x_) != NULL); \
(x_)->allocator = (allocator_); \
(x_)->count = (init_count_); \
(x_)->capacity = (init_count_); \
@@ -67,8 +67,8 @@ typedef Array(void) ArrayVoid;
void array__set_capacity(void *ptr, isize capacity, isize element_size) {
- GB_ASSERT(ptr != NULL);
ArrayVoid *x = cast(ArrayVoid *)ptr;
+ GB_ASSERT(ptr != NULL);
GB_ASSERT(element_size > 0);
diff --git a/src/checker/checker.c b/src/checker/checker.c
index ccd97cad3..e42e6126e 100644
--- a/src/checker/checker.c
+++ b/src/checker/checker.c
@@ -271,8 +271,9 @@ CycleChecker *cycle_checker_add(CycleChecker *cc, Entity *e) {
if (cc->path.e == NULL) {
array_init(&cc->path, heap_allocator());
}
- GB_ASSERT(e != NULL && e->kind == Entity_TypeName);
- array_add(&cc->path, e);
+ if (e != NULL && e->kind == Entity_TypeName) {
+ array_add(&cc->path, e);
+ }
return cc;
}
@@ -508,6 +509,11 @@ void add_global_constant(gbAllocator a, String name, Type *type, ExactValue valu
}
+void add_global_string_constant(gbAllocator a, String name, String value) {
+ add_global_constant(a, name, t_untyped_string, make_exact_value_string(value));
+
+}
+
void init_universal_scope(void) {
// NOTE(bill): No need to free these
@@ -528,9 +534,11 @@ void init_universal_scope(void) {
add_global_entity(make_entity_nil(a, str_lit("nil"), t_untyped_nil));
- add_global_constant(a, str_lit("ODIN_OS"), t_untyped_string, make_exact_value_string(str_lit("windows")));
- add_global_constant(a, str_lit("ODIN_ARCH"), t_untyped_string, make_exact_value_string(str_lit("amd64")));
- add_global_constant(a, str_lit("ODIN_VERSION"), t_untyped_string, make_exact_value_string(str_lit(VERSION_STRING)));
+ add_global_string_constant(a, str_lit("ODIN_OS"), str_lit("windows"));
+ add_global_string_constant(a, str_lit("ODIN_ARCH"), str_lit("amd64"));
+ add_global_string_constant(a, str_lit("ODIN_VENDOR"), str_lit("odin"));
+ add_global_string_constant(a, str_lit("ODIN_VERSION"), str_lit(VERSION_STRING));
+ add_global_string_constant(a, str_lit("ODIN_ENDIAN"), str_lit("little"));
// Builtin Procedures
diff --git a/src/checker/expr.c b/src/checker/expr.c
index 6f16da451..de6011a79 100644
--- a/src/checker/expr.c
+++ b/src/checker/expr.c
@@ -713,12 +713,10 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
if (o.mode != Addressing_Invalid) {
iota = o.value;
} else {
- Token add_token = {Token_Add};
- iota = exact_binary_operator_value(add_token, iota, make_exact_value_integer(1));
+ iota = exact_binary_operator_value(Token_Add, iota, make_exact_value_integer(1));
}
} else {
- Token add_token = {Token_Add};
- iota = exact_binary_operator_value(add_token, iota, make_exact_value_integer(1));
+ iota = exact_binary_operator_value(Token_Add, iota, make_exact_value_integer(1));
}
@@ -1492,7 +1490,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
if (is_type_unsigned(type)) {
precision = cast(i32)(8 * type_size_of(c->sizes, c->allocator, type));
}
- o->value = exact_unary_operator_value(op, o->value, precision);
+ o->value = exact_unary_operator_value(op.kind, o->value, precision);
if (is_type_typed(type)) {
if (node != NULL) {
@@ -1558,7 +1556,7 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) {
} else {
if (x->mode == Addressing_Constant &&
y->mode == Addressing_Constant) {
- x->value = make_exact_value_bool(compare_exact_values(op, x->value, y->value));
+ x->value = make_exact_value_bool(compare_exact_values(op.kind, x->value, y->value));
} else {
x->mode = Addressing_Value;
@@ -1645,7 +1643,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
x->type = t_untyped_integer;
}
- x->value = exact_value_shift(be->op, x_val, make_exact_value_integer(amount));
+ x->value = exact_value_shift(be->op.kind, x_val, make_exact_value_integer(amount));
if (is_type_typed(x->type)) {
check_is_expressible(c, x, base_type(x->type));
@@ -2168,7 +2166,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (op.kind == Token_Quo && is_type_integer(type)) {
op.kind = Token_QuoEq; // NOTE(bill): Hack to get division of integers
}
- x->value = exact_binary_operator_value(op, a, b);
+ x->value = exact_binary_operator_value(op.kind, a, b);
if (is_type_typed(type)) {
if (node != NULL) {
x->expr = node;
@@ -3166,7 +3164,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case BuiltinProc_min: {
// min :: proc(a, b: comparable) -> comparable
Type *type = base_type(operand->type);
- if (!is_type_comparable(type) || !is_type_numeric(type)) {
+ if (!is_type_comparable(type) || !(is_type_numeric(type) || is_type_string(type))) {
gbString type_str = type_to_string(operand->type);
error(ast_node_token(call),
"Expected a comparable numeric type to `min`, got `%s`",
@@ -3182,7 +3180,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
if (b.mode == Addressing_Invalid) {
return false;
}
- if (!is_type_comparable(b.type) || !is_type_numeric(type)) {
+ if (!is_type_comparable(b.type) || !(is_type_numeric(b.type) || is_type_string(b.type))) {
gbString type_str = type_to_string(b.type);
error(ast_node_token(call),
"Expected a comparable numeric type to `min`, got `%s`",
@@ -3195,10 +3193,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
b.mode == Addressing_Constant) {
ExactValue x = a.value;
ExactValue y = b.value;
- Token lt = {Token_Lt};
operand->mode = Addressing_Constant;
- if (compare_exact_values(lt, x, y)) {
+ if (compare_exact_values(Token_Lt, x, y)) {
operand->value = x;
operand->type = a.type;
} else {
@@ -3235,10 +3232,10 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case BuiltinProc_max: {
// min :: proc(a, b: comparable) -> comparable
Type *type = base_type(operand->type);
- if (!is_type_comparable(type) || !is_type_numeric(type)) {
+ if (!is_type_comparable(type) || !(is_type_numeric(type) || is_type_string(type))) {
gbString type_str = type_to_string(operand->type);
error(ast_node_token(call),
- "Expected a comparable numeric type to `max`, got `%s`",
+ "Expected a comparable numeric or string type to `max`, got `%s`",
type_str);
gb_string_free(type_str);
return false;
@@ -3251,10 +3248,10 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
if (b.mode == Addressing_Invalid) {
return false;
}
- if (!is_type_comparable(b.type) || !is_type_numeric(type)) {
+ if (!is_type_comparable(b.type) || !(is_type_numeric(type) || is_type_string(type))) {
gbString type_str = type_to_string(b.type);
error(ast_node_token(call),
- "Expected a comparable numeric type to `max`, got `%s`",
+ "Expected a comparable numeric or string type to `max`, got `%s`",
type_str);
gb_string_free(type_str);
return false;
@@ -3264,10 +3261,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
b.mode == Addressing_Constant) {
ExactValue x = a.value;
ExactValue y = b.value;
- Token gt = {Token_Gt};
operand->mode = Addressing_Constant;
- if (compare_exact_values(gt, x, y)) {
+ if (compare_exact_values(Token_Gt, x, y)) {
operand->value = x;
operand->type = a.type;
} else {
diff --git a/src/checker/types.c b/src/checker/types.c
index f51cbb660..26ac633fb 100644
--- a/src/checker/types.c
+++ b/src/checker/types.c
@@ -683,7 +683,8 @@ bool is_type_comparable(Type *t) {
return false;
} break;
case Type_Array:
- return is_type_comparable(t->Array.elem);
+ return false;
+ // return is_type_comparable(t->Array.elem);
case Type_Vector:
return is_type_comparable(t->Vector.elem);
case Type_Proc:
diff --git a/src/common.c b/src/common.c
index 9b70722d1..2d4600b89 100644
--- a/src/common.c
+++ b/src/common.c
@@ -14,14 +14,19 @@ gb_global bool global_module_path_set = false;
String get_module_dir() {
+ String path = global_module_path;
+ Array(wchar_t) path_buf;
+ isize len, i;
+ gbTempArenaMemory tmp;
+ wchar_t *text;
+
if (global_module_path_set) {
return global_module_path;
}
- Array(wchar_t) path_buf;
array_init_count(&path_buf, heap_allocator(), 300);
- isize len = 0;
+ len = 0;
for (;;) {
len = GetModuleFileNameW(NULL, &path_buf.e[0], path_buf.count);
if (len == 0) {
@@ -33,13 +38,13 @@ String get_module_dir() {
array_resize(&path_buf, 2*path_buf.count + 300);
}
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
+ tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
- wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
+ text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
GetModuleFileNameW(NULL, text, len);
- String path = string16_to_string(heap_allocator(), make_string16(text, len));
- for (isize i = path.len-1; i >= 0; i--) {
+ path = string16_to_string(heap_allocator(), make_string16(text, len));
+ for (i = path.len-1; i >= 0; i--) {
u8 c = path.text[i];
if (c == '/' || c == '\\') {
break;
@@ -141,8 +146,9 @@ i16 f32_to_f16(f32 value) {
if (e > 30) {
float volatile f = 1e12f;
int j;
- for (j = 0; j < 10; j++)
+ for (j = 0; j < 10; j++) {
f *= f; /* NOTE(bill): Cause overflow */
+ }
return cast(i16)(s | 0x7c00);
}
diff --git a/src/exact_value.c b/src/exact_value.c
index 313cda694..d220cac61 100644
--- a/src/exact_value.c
+++ b/src/exact_value.c
@@ -148,8 +148,8 @@ ExactValue exact_value_to_float(ExactValue v) {
}
-ExactValue exact_unary_operator_value(Token op, ExactValue v, i32 precision) {
- switch (op.kind) {
+ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision) {
+ switch (op) {
case Token_Add: {
switch (v.kind) {
case ExactValue_Invalid:
@@ -207,7 +207,7 @@ ExactValue exact_unary_operator_value(Token op, ExactValue v, i32 precision) {
}
failure:
- GB_PANIC("Invalid unary operation, %.*s", LIT(token_strings[op.kind]));
+ GB_PANIC("Invalid unary operation, %.*s", LIT(token_strings[op]));
ExactValue error_value = {0};
return error_value;
@@ -270,7 +270,7 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
}
// TODO(bill): Allow for pointer arithmetic? Or are pointer slices good enough?
-ExactValue exact_binary_operator_value(Token op, ExactValue x, ExactValue y) {
+ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) {
match_exact_values(&x, &y);
switch (x.kind) {
@@ -278,7 +278,7 @@ ExactValue exact_binary_operator_value(Token op, ExactValue x, ExactValue y) {
return x;
case ExactValue_Bool:
- switch (op.kind) {
+ switch (op) {
case Token_CmpAnd: return make_exact_value_bool(x.value_bool && y.value_bool);
case Token_CmpOr: return make_exact_value_bool(x.value_bool || y.value_bool);
case Token_And: return make_exact_value_bool(x.value_bool & y.value_bool);
@@ -291,7 +291,7 @@ ExactValue exact_binary_operator_value(Token op, ExactValue x, ExactValue y) {
i64 a = x.value_integer;
i64 b = y.value_integer;
i64 c = 0;
- switch (op.kind) {
+ switch (op) {
case Token_Add: c = a + b; break;
case Token_Sub: c = a - b; break;
case Token_Mul: c = a * b; break;
@@ -312,7 +312,7 @@ ExactValue exact_binary_operator_value(Token op, ExactValue x, ExactValue y) {
case ExactValue_Float: {
f64 a = x.value_float;
f64 b = y.value_float;
- switch (op.kind) {
+ switch (op) {
case Token_Add: return make_exact_value_float(a + b);
case Token_Sub: return make_exact_value_float(a - b);
case Token_Mul: return make_exact_value_float(a * b);
@@ -324,22 +324,22 @@ ExactValue exact_binary_operator_value(Token op, ExactValue x, ExactValue y) {
error:
ExactValue error_value = {0};
- // gb_printf_err("Invalid binary operation: %s\n", token_kind_to_string(op.kind));
+ // gb_printf_err("Invalid binary operation: %s\n", token_kind_to_string(op));
return error_value;
}
-gb_inline ExactValue exact_value_add(ExactValue x, ExactValue y) { Token op = {Token_Add}; return exact_binary_operator_value(op, x, y); }
-gb_inline ExactValue exact_value_sub(ExactValue x, ExactValue y) { Token op = {Token_Sub}; return exact_binary_operator_value(op, x, y); }
-gb_inline ExactValue exact_value_mul(ExactValue x, ExactValue y) { Token op = {Token_Mul}; return exact_binary_operator_value(op, x, y); }
-gb_inline ExactValue exact_value_quo(ExactValue x, ExactValue y) { Token op = {Token_Quo}; return exact_binary_operator_value(op, x, y); }
-gb_inline ExactValue exact_value_shift(Token op, ExactValue x, ExactValue y) { return exact_binary_operator_value(op, x, y); }
+gb_inline ExactValue exact_value_add(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Add, x, y); }
+gb_inline ExactValue exact_value_sub(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Sub, x, y); }
+gb_inline ExactValue exact_value_mul(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Mul, x, y); }
+gb_inline ExactValue exact_value_quo(ExactValue x, ExactValue y) { return exact_binary_operator_value(Token_Quo, x, y); }
+gb_inline ExactValue exact_value_shift(TokenKind op, ExactValue x, ExactValue y) { return exact_binary_operator_value(op, x, y); }
i32 cmp_f64(f64 a, f64 b) {
return (a > b) - (a < b);
}
-bool compare_exact_values(Token op, ExactValue x, ExactValue y) {
+bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
match_exact_values(&x, &y);
switch (x.kind) {
@@ -347,7 +347,7 @@ bool compare_exact_values(Token op, ExactValue x, ExactValue y) {
return false;
case ExactValue_Bool:
- switch (op.kind) {
+ switch (op) {
case Token_CmpEq: return x.value_bool == y.value_bool;
case Token_NotEq: return x.value_bool != y.value_bool;
}
@@ -356,7 +356,7 @@ bool compare_exact_values(Token op, ExactValue x, ExactValue y) {
case ExactValue_Integer: {
i64 a = x.value_integer;
i64 b = y.value_integer;
- switch (op.kind) {
+ switch (op) {
case Token_CmpEq: return a == b;
case Token_NotEq: return a != b;
case Token_Lt: return a < b;
@@ -369,7 +369,7 @@ bool compare_exact_values(Token op, ExactValue x, ExactValue y) {
case ExactValue_Float: {
f64 a = x.value_float;
f64 b = y.value_float;
- switch (op.kind) {
+ switch (op) {
case Token_CmpEq: return cmp_f64(a, b) == 0;
case Token_NotEq: return cmp_f64(a, b) != 0;
case Token_Lt: return cmp_f64(a, b) < 0;
@@ -384,7 +384,7 @@ bool compare_exact_values(Token op, ExactValue x, ExactValue y) {
String b = y.value_string;
isize len = gb_min(a.len, b.len);
// TODO(bill): gb_memcompare is used because the strings are UTF-8
- switch (op.kind) {
+ switch (op) {
case Token_CmpEq: return gb_memcompare(a.text, b.text, len) == 0;
case Token_NotEq: return gb_memcompare(a.text, b.text, len) != 0;
case Token_Lt: return gb_memcompare(a.text, b.text, len) < 0;
diff --git a/src/map.c b/src/map.c
index eea0e30d6..f974a46db 100644
--- a/src/map.c
+++ b/src/map.c
@@ -243,6 +243,7 @@ void _J2(MAP_PROC,set)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
+ MapFindResult last;
if (fr.entry_prev < 0) {
h->hashes.e[fr.hash_index] = h->entries.e[fr.entry_index].next;
} else {
@@ -253,7 +254,7 @@ void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
return;
}
h->entries.e[fr.entry_index] = h->entries.e[h->entries.count-1];
- MapFindResult last = _J2(MAP_PROC,_find)(h, h->entries.e[fr.entry_index].key);
+ last = _J2(MAP_PROC,_find)(h, h->entries.e[fr.entry_index].key);
if (last.entry_prev >= 0) {
h->entries.e[last.entry_prev].next = fr.entry_index;
} else {
@@ -314,11 +315,13 @@ void _J2(MAP_PROC,multi_get_all)(MAP_NAME *h, HashKey key, MAP_TYPE *items) {
}
void _J2(MAP_PROC,multi_insert)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
+ MapFindResult fr;
+ isize i;
if (h->hashes.count == 0) {
_J2(MAP_PROC,grow)(h);
}
- MapFindResult fr = _J2(MAP_PROC,_find)(h, key);
- isize i = _J2(MAP_PROC,_add_entry)(h, key);
+ fr = _J2(MAP_PROC,_find)(h, key);
+ i = _J2(MAP_PROC,_add_entry)(h, key);
if (fr.entry_prev < 0) {
h->hashes.e[fr.hash_index] = i;
} else {
diff --git a/src/parser.c b/src/parser.c
index c5eae58b0..79753c832 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -32,7 +32,7 @@ typedef struct AstFile {
isize expr_level;
AstNodeArray decls;
- bool is_global_scope;
+ bool is_global_scope;
AstNode * curr_proc;
isize scope_level;
@@ -86,13 +86,6 @@ typedef enum StmtStateFlag {
StmtStateFlag_no_bounds_check = GB_BIT(1),
} StmtStateFlag;
-
-typedef enum CallExprKind {
- CallExpr_Prefix, // call(...)
- CallExpr_Postfix, // a'call
- CallExpr_Infix, // a ''call b
-} CallExprKind;
-
AstNodeArray make_ast_node_array(AstFile *f) {
AstNodeArray a;
array_init(&a, gb_arena_allocator(&f->arena));
@@ -134,7 +127,6 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
AstNodeArray args; \
Token open, close; \
Token ellipsis; \
- CallExprKind kind; \
}) \
AST_NODE_KIND(SliceExpr, "slice expression", struct { \
AstNode *expr; \
@@ -256,9 +248,10 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
}) \
AST_NODE_KIND(ImportDecl, "import declaration", struct { \
Token token, relpath; \
+ String os, arch; \
String fullpath; \
Token import_name; \
- bool is_load; \
+ bool is_load; \
AstNode *note; \
}) \
AST_NODE_KIND(ForeignLibrary, "foreign library", struct { \
@@ -959,11 +952,15 @@ AstNode *make_type_decl(AstFile *f, Token token, AstNode *name, AstNode *type) {
return result;
}
-AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_name, bool is_load) {
+AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_name,
+ String os, String arch,
+ bool is_load) {
AstNode *result = make_node(f, AstNode_ImportDecl);
result->ImportDecl.token = token;
result->ImportDecl.relpath = relpath;
result->ImportDecl.import_name = import_name;
+ result->ImportDecl.os = os;
+ result->ImportDecl.arch = arch;
result->ImportDecl.is_load = is_load;
return result;
}
@@ -1374,19 +1371,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
case Token_Hash: {
Token token = expect_token(f, Token_Hash);
Token name = expect_token(f, Token_Identifier);
- if (str_eq(name.string, str_lit("rune"))) {
- if (f->curr_token.kind == Token_String) {
- Token *s = &f->curr_token;
-
- if (gb_utf8_strnlen(s->string.text, s->string.len) != 1) {
- syntax_error(*s, "Invalid rune literal %.*s", LIT(s->string));
- }
- s->kind = Token_Rune; // NOTE(bill): Change it
- } else {
- expect_token(f, Token_String);
- }
- operand = parse_operand(f, lhs);
- } else if (str_eq(name.string, str_lit("file"))) {
+ if (str_eq(name.string, str_lit("file"))) {
Token token = name;
token.kind = Token_String;
token.string = token.pos.file;
@@ -1513,19 +1498,6 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
bool loop = true;
while (loop) {
switch (f->curr_token.kind) {
-
- case Token_Prime: {
- Token op = expect_token(f, Token_Prime);
- if (lhs) {
- // TODO(bill): Handle this
- }
- AstNode *proc = parse_identifier(f);
- AstNodeArray args;
- array_init_reserve(&args, gb_arena_allocator(&f->arena), 1);
- array_add(&args, operand);
- operand = make_call_expr(f, proc, args, ast_node_token(operand), op, empty_token);
- } break;
-
case Token_OpenParen: {
if (lhs) {
// TODO(bill): Handle this shit! Is this even allowed in this language?!
@@ -1680,13 +1652,11 @@ i32 token_precedence(Token t) {
case Token_Shl:
case Token_Shr:
return 5;
- case Token_DoublePrime:
- return 6;
case Token_as:
case Token_transmute:
case Token_down_cast:
case Token_union_cast:
- return 7;
+ return 6;
}
return 0;
@@ -1708,28 +1678,6 @@ AstNode *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
}
switch (op.kind) {
- case Token_DoublePrime: {
- // TODO(bill): Properly define semantic for in-fix and post-fix calls
- AstNode *proc = parse_identifier(f);
- /* if (f->curr_token.kind == Token_OpenParen) {
- AstNode *call = parse_call_expr(f, proc);
- array_add(&call->CallExpr.args, expression);
- for (isize i = gb_array_count(call->CallExpr.args)-1; i > 0; i--) {
- gb_swap(AstNode *, call->CallExpr.args[i], call->CallExpr.args[i-1]);
- }
-
- expression = call;
- } else */{
- right = parse_binary_expr(f, false, prec+1);
- AstNodeArray args = {0};
- array_init_reserve(&args, gb_arena_allocator(&f->arena), 2);
- array_add(&args, expression);
- array_add(&args, right);
- expression = make_call_expr(f, proc, args, op, ast_node_token(right), empty_token);
- }
- continue;
- } break;
-
case Token_as:
case Token_transmute:
case Token_down_cast:
@@ -2755,42 +2703,6 @@ AstNode *parse_stmt(AstFile *f) {
}
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->curr_token);
- } else if (str_eq(tag, str_lit("import"))) {
- // TODO(bill): better error messages
- Token import_name = {0};
- Token file_path = expect_token_after(f, Token_String, "#import");
- if (allow_token(f, Token_as)) {
- // NOTE(bill): Custom import name
- if (f->curr_token.kind == Token_Period) {
- import_name = f->curr_token;
- import_name.kind = Token_Identifier;
- next_token(f);
- } else {
- import_name = expect_token_after(f, Token_Identifier, "`as` for import declaration");
- }
-
- if (str_eq(import_name.string, str_lit("_"))) {
- syntax_error(token, "Illegal import name: `_`");
- return make_bad_decl(f, token, f->curr_token);
- }
- }
-
- if (f->curr_proc == NULL) {
- return make_import_decl(f, s->TagStmt.token, file_path, import_name, false);
- }
- 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 (str_eq(tag, str_lit("load"))) {
- // TODO(bill): better error messages
- Token file_path = expect_token(f, Token_String);
- Token import_name = file_path;
- import_name.string = str_lit(".");
-
- if (f->curr_proc == NULL) {
- return make_import_decl(f, s->TagStmt.token, file_path, import_name, true);
- }
- 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 (str_eq(tag, str_lit("foreign_system_library"))) {
Token file_path = expect_token(f, Token_String);
if (f->curr_proc == NULL) {
@@ -2831,6 +2743,54 @@ AstNode *parse_stmt(AstFile *f) {
syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together");
}
return s;
+ } else if (str_eq(tag, str_lit("import"))) {
+ String os = {0};
+ String arch = {0};
+
+ // if (tag.len > 6) {
+ // String sub = make_string(tag.text+6, tag.len-6);
+ // }
+
+ // TODO(bill): better error messages
+ Token import_name = {0};
+ Token file_path = expect_token_after(f, Token_String, "#import");
+ if (allow_token(f, Token_as)) {
+ // NOTE(bill): Custom import name
+ if (f->curr_token.kind == Token_Period) {
+ import_name = f->curr_token;
+ import_name.kind = Token_Identifier;
+ next_token(f);
+ } else {
+ import_name = expect_token_after(f, Token_Identifier, "`as` for import declaration");
+ }
+
+ if (str_eq(import_name.string, str_lit("_"))) {
+ syntax_error(token, "Illegal import name: `_`");
+ return make_bad_decl(f, token, f->curr_token);
+ }
+ }
+
+ if (f->curr_proc != NULL) {
+ 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);
+ }
+
+ return make_import_decl(f, s->TagStmt.token, file_path, import_name, os, arch, false);
+ } else if (str_eq(tag, str_lit("load"))) {
+ String os = {0};
+ String arch = {0};
+ // TODO(bill): better error messages
+ Token file_path = expect_token(f, Token_String);
+ Token import_name = file_path;
+ import_name.string = str_lit(".");
+
+ if (f->curr_proc == NULL) {
+ return make_import_decl(f, s->TagStmt.token, file_path, import_name, os, arch, true);
+ }
+ 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 {
+
}
s->TagStmt.stmt = parse_stmt(f); // TODO(bill): Find out why this doesn't work as an argument
diff --git a/src/ssa.c b/src/ssa.c
index b34bc7c51..42437d7e7 100644
--- a/src/ssa.c
+++ b/src/ssa.c
@@ -2447,27 +2447,11 @@ void ssa_emit_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low,
return;
}
-
low = ssa_emit_conv(proc, low, t_int);
high = ssa_emit_conv(proc, high, t_int);
max = ssa_emit_conv(proc, max, t_int);
ssa_emit(proc, ssa_make_instr_slice_bounds_check(proc, token.pos, low, high, max, is_substring));
-
- // gbAllocator a = proc->module->allocator;
- // ssaValue **args = gb_alloc_array(a, ssaValue *, 6);
- // args[0] = ssa_emit_global_string(proc, token.pos.file);
- // args[1] = ssa_make_const_int(a, token.pos.line);
- // args[2] = ssa_make_const_int(a, token.pos.column);
- // args[3] = ssa_emit_conv(proc, low, t_int);
- // args[4] = ssa_emit_conv(proc, high, t_int);
- // args[5] = ssa_emit_conv(proc, max, t_int);
-
- // if (!is_substring) {
- // ssa_emit_global_call(proc, "__slice_expr_error", args, 6);
- // } else {
- // ssa_emit_global_call(proc, "__substring_expr_error", args, 5);
- // }
}
@@ -2878,7 +2862,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
Type *elem_type = slice_type->Slice.elem;
i64 size_of_elem = type_size_of(proc->module->sizes, proc->module->allocator, elem_type);
-
ssaValue *dst = ssa_emit_conv(proc, ssa_slice_elem(proc, dst_slice), t_rawptr);
ssaValue *src = ssa_emit_conv(proc, ssa_slice_elem(proc, src_slice), t_rawptr);
@@ -3031,7 +3014,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_emit_comment(proc, str_lit("min"));
ssaValue *x = ssa_build_expr(proc, ce->args.e[0]);
ssaValue *y = ssa_build_expr(proc, ce->args.e[1]);
- Type *t = base_type(ssa_type(x));
ssaValue *cond = ssa_emit_comp(proc, Token_Lt, x, y);
return ssa_emit_select(proc, cond, x, y);
} break;
@@ -3040,7 +3022,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_emit_comment(proc, str_lit("max"));
ssaValue *x = ssa_build_expr(proc, ce->args.e[0]);
ssaValue *y = ssa_build_expr(proc, ce->args.e[1]);
- Type *t = base_type(ssa_type(x));
ssaValue *cond = ssa_emit_comp(proc, Token_Gt, x, y);
return ssa_emit_select(proc, cond, x, y);
} break;
diff --git a/src/string.c b/src/string.c
index b54b1d24f..75a2e50b7 100644
--- a/src/string.c
+++ b/src/string.c
@@ -52,7 +52,8 @@ gb_inline String make_string_c(char *text) {
gb_inline bool str_eq_ignore_case(String a, String b) {
if (a.len == b.len) {
- for (isize i = 0; i < a.len; i++) {
+ isize i;
+ for (i = 0; i < a.len; i++) {
char x = cast(char)a.text[i];
char y = cast(char)b.text[i];
if (gb_char_to_lower(x) != gb_char_to_lower(y))
@@ -64,39 +65,40 @@ gb_inline bool str_eq_ignore_case(String a, String b) {
}
int string_compare(String x, String y) {
- if (x.len == y.len &&
- x.text == y.text) {
- return 0;
- }
-
- isize n = gb_min(x.len, y.len);
-
- isize fast = n/gb_size_of(isize) + 1;
- isize offset = (fast-1)*gb_size_of(isize);
- isize curr_block = 0;
- if (n <= gb_size_of(isize)) {
- fast = 0;
- }
+ if (!(x.len == y.len &&
+ x.text == y.text)) {
+ isize n, fast, offset, curr_block;
+ isize *la, *lb;
+ isize pos;
+
+ n = gb_min(x.len, y.len);
+
+ fast = n/gb_size_of(isize) + 1;
+ offset = (fast-1)*gb_size_of(isize);
+ curr_block = 0;
+ if (n <= gb_size_of(isize)) {
+ fast = 0;
+ }
- isize *la = cast(isize *)x.text;
- isize *lb = cast(isize *)y.text;
+ la = cast(isize *)x.text;
+ lb = cast(isize *)y.text;
- for (; curr_block < fast; curr_block++) {
- if (la[curr_block] ^ lb[curr_block]) {
- for (isize pos = curr_block*gb_size_of(isize); pos < n; pos++) {
- if (x.text[pos] ^ y.text[pos]) {
- return cast(int)x.text[pos] - cast(int)y.text[pos];
+ for (; curr_block < fast; curr_block++) {
+ if (la[curr_block] ^ lb[curr_block]) {
+ for (pos = curr_block*gb_size_of(isize); pos < n; pos++) {
+ if (x.text[pos] ^ y.text[pos]) {
+ return cast(int)x.text[pos] - cast(int)y.text[pos];
+ }
}
}
}
- }
- for (; offset < n; offset++) {
- if (x.text[offset] ^ y.text[offset]) {
- return cast(int)x.text[offset] - cast(int)y.text[offset];
+ for (; offset < n; offset++) {
+ if (x.text[offset] ^ y.text[offset]) {
+ return cast(int)x.text[offset] - cast(int)y.text[offset];
+ }
}
}
-
return 0;
}
@@ -126,7 +128,18 @@ gb_inline bool str_gt(String a, String b) { return string_compare(a, b) > 0;
gb_inline bool str_le(String a, String b) { return string_compare(a, b) <= 0; }
gb_inline bool str_ge(String a, String b) { return string_compare(a, b) >= 0; }
-
+gb_inline bool str_has_prefix(String s, String prefix) {
+ isize i;
+ if (prefix.len < s.len) {
+ return false;
+ }
+ for (i = 0; i < prefix.len; i++) {
+ if (s.text[i] != prefix.text[i]) {
+ return false;
+ }
+ }
+ return true;
+}
gb_inline isize string_extension_position(String str) {
isize dot_pos = -1;
@@ -157,7 +170,8 @@ gb_inline bool string_has_extension(String str, String ext) {
}
bool string_contains_char(String s, u8 c) {
- for (isize i = 0; i < s.len; i++) {
+ isize i;
+ for (i = 0; i < s.len; i++) {
if (s.text[i] == c)
return true;
}
@@ -166,20 +180,23 @@ bool string_contains_char(String s, u8 c) {
// TODO(bill): Make this non-windows specific
String16 string_to_string16(gbAllocator a, String s) {
+ int len, len1;
+ wchar_t *text;
+
if (s.len < 1) {
return make_string16(NULL, 0);
}
- int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- cast(char *)s.text, s.len, NULL, 0);
+ len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+ cast(char *)s.text, s.len, NULL, 0);
if (len == 0) {
return make_string16(NULL, 0);
}
- wchar_t *text = gb_alloc_array(a, wchar_t, len+1);
+ text = gb_alloc_array(a, wchar_t, len+1);
- int len1 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- cast(char *)s.text, s.len, text, len);
+ len1 = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+ cast(char *)s.text, s.len, text, len);
if (len1 == 0) {
gb_free(a, text);
return make_string16(NULL, 0);
@@ -190,22 +207,23 @@ String16 string_to_string16(gbAllocator a, String s) {
}
String string16_to_string(gbAllocator a, String16 s) {
+ int len, len1;
+ u8 *text;
+
if (s.len < 1) {
return make_string(NULL, 0);
}
- int len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
- s.text, s.len, NULL, 0,
- NULL, NULL);
+ len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
+ s.text, s.len, NULL, 0, NULL, NULL);
if (len == 0) {
return make_string(NULL, 0);
}
- u8 *text = gb_alloc_array(a, u8, len+1);
+ text = gb_alloc_array(a, u8, len+1);
- int len1 = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
- s.text, s.len, cast(char *)text, len,
- NULL, NULL);
+ len1 = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
+ s.text, s.len, cast(char *)text, len, NULL, NULL);
if (len1 == 0) {
gb_free(a, text);
return make_string(NULL, 0);
@@ -233,8 +251,10 @@ String string16_to_string(gbAllocator a, String16 s) {
bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) {
+ u8 c;
+
if (s.text[0] == quote &&
- (quote == '$' || quote == '"')) {
+ (quote == '\'' || quote == '"')) {
return false;
} else if (s.text[0] >= 0x80) {
Rune r = -1;
@@ -252,7 +272,7 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *
if (s.len <= 1) {
return false;
}
- u8 c = s.text[1];
+ c = s.text[1];
s = make_string(s.text+2, s.len-2);
switch (c) {
@@ -268,7 +288,7 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *
case '\\': *rune = '\\'; break;
- case '$':
+ case '\'':
case '"':
if (c != quote) {
return false;
@@ -284,11 +304,12 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *
case '5':
case '6':
case '7': {
+ isize i;
i32 r = gb_digit_to_int(c);
if (s.len < 2) {
return false;
}
- for (isize i = 0; i < 2; i++) {
+ for (i = 0; i < 2; i++) {
i32 d = gb_digit_to_int(s.text[i]);
if (d < 0 || d > 7) {
return false;
@@ -305,18 +326,18 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *
case 'x':
case 'u':
case 'U': {
- isize count = 0;
+ Rune r = 0;
+ isize i, count = 0;
switch (c) {
case 'x': count = 2; break;
case 'u': count = 4; break;
case 'U': count = 8; break;
}
- Rune r = 0;
if (s.len < count) {
return false;
}
- for (isize i = 0; i < count; i++) {
+ for (i = 0; i < count; i++) {
i32 d = gb_hex_digit_to_int(s.text[i]);
if (d < 0) {
return false;
@@ -344,14 +365,16 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *
// 1 == original memory
// 2 == new allocation
i32 unquote_string(gbAllocator a, String *s_) {
- GB_ASSERT(s_ != NULL);
String s = *s_;
isize n = s.len;
- if (n < 2)
+ u8 quote;
+ if (n < 2) {
return 0;
- u8 quote = s.text[0];
- if (quote != s.text[n-1])
+ }
+ quote = s.text[0];
+ if (quote != s.text[n-1]) {
return 0;
+ }
s.text += 1;
s.len -= 2;
@@ -362,17 +385,19 @@ i32 unquote_string(gbAllocator a, String *s_) {
*s_ = s;
return 1;
}
- if (quote != '"' && quote != '$')
+ if (quote != '"' && quote != '\'') {
return 0;
+ }
- if (string_contains_char(s, '\n'))
+ if (string_contains_char(s, '\n')) {
return 0;
+ }
if (!string_contains_char(s, '\\') && !string_contains_char(s, quote)) {
if (quote == '"') {
*s_ = s;
return 1;
- } else if (quote == '$') {
+ } else if (quote == '\'') {
Rune r = GB_RUNE_INVALID;
isize size = gb_utf8_decode(s.text, s.len, &r);
if ((size == s.len) && (r != -1 || size != 1)) {
@@ -383,34 +408,36 @@ i32 unquote_string(gbAllocator a, String *s_) {
}
- u8 rune_temp[4] = {0};
- isize buf_len = 3*s.len / 2;
- u8 *buf = gb_alloc_array(a, u8, buf_len);
- isize offset = 0;
- while (s.len > 0) {
- String tail_string = {0};
- Rune r = 0;
- bool multiple_bytes = false;
- bool success = unquote_char(s, quote, &r, &multiple_bytes, &tail_string);
- if (!success) {
- gb_free(a, buf);
- return 0;
- }
- s = tail_string;
-
- if (r < 0x80 || !multiple_bytes) {
- buf[offset++] = cast(u8)r;
- } else {
- isize size = gb_utf8_encode_rune(rune_temp, r);
- gb_memmove(buf+offset, rune_temp, size);
- offset += size;
- }
+ {
+ u8 rune_temp[4] = {0};
+ isize buf_len = 3*s.len / 2;
+ u8 *buf = gb_alloc_array(a, u8, buf_len);
+ isize offset = 0;
+ while (s.len > 0) {
+ String tail_string = {0};
+ Rune r = 0;
+ bool multiple_bytes = false;
+ bool success = unquote_char(s, quote, &r, &multiple_bytes, &tail_string);
+ if (!success) {
+ gb_free(a, buf);
+ return 0;
+ }
+ s = tail_string;
+
+ if (r < 0x80 || !multiple_bytes) {
+ buf[offset++] = cast(u8)r;
+ } else {
+ isize size = gb_utf8_encode_rune(rune_temp, r);
+ gb_memmove(buf+offset, rune_temp, size);
+ offset += size;
+ }
- if (quote == '$' && s.len != 0) {
- gb_free(a, buf);
- return 0;
+ if (quote == '\'' && s.len != 0) {
+ gb_free(a, buf);
+ return 0;
+ }
}
+ *s_ = make_string(buf, offset);
}
- *s_ = make_string(buf, offset);
return 2;
}
diff --git a/src/timings.c b/src/timings.c
index a1eecc01a..a934414ec 100644
--- a/src/timings.c
+++ b/src/timings.c
@@ -77,12 +77,13 @@ f64 time_stamp_as_ms(TimeStamp ts, u64 freq) {
}
void timings_print_all(Timings *t) {
+ char const SPACES[] = " ";
+ isize max_len, i;
+
timings__stop_current_section(t);
t->total.finish = time_stamp_time_now();
- char const SPACES[] = " ";
-
- isize max_len = t->total.label.len;
+ max_len = t->total.label.len;
for_array(i, t->sections) {
TimeStamp ts = t->sections.e[i];
max_len = gb_max(max_len, ts.label.len);
diff --git a/src/tokenizer.c b/src/tokenizer.c
index edf6e9721..c7d62cb2b 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -35,9 +35,6 @@ TOKEN_KIND(Token__OperatorBegin, "_OperatorBegin"), \
TOKEN_KIND(Token_down_cast, "down_cast"), \
TOKEN_KIND(Token_union_cast, "union_cast"), \
\
- TOKEN_KIND(Token_Prime, "'"), \
- TOKEN_KIND(Token_DoublePrime, "''"), \
-\
TOKEN_KIND(Token_CmpAnd, "&&"), \
TOKEN_KIND(Token_CmpOr, "||"), \
\
@@ -656,17 +653,50 @@ Token tokenizer_get_token(Tokenizer *t) {
token.kind = Token_EOF;
break;
- case '\'':
- token.kind = Token_Prime;
- if (t->curr_rune == '\'') {
+ case '\'': // Rune Literal
+ {
+ token.kind = Token_Rune;
+ Rune quote = curr_rune;
+ bool valid = true;
+ i32 n = 0, success;
+ for (;;) {
+ Rune r = t->curr_rune;
+ if (r == '\n' || r < 0) {
+ tokenizer_err(t, "Rune literal not terminated");
+ break;
+ }
advance_to_next_rune(t);
- token.kind = Token_DoublePrime;
+ if (r == quote) {
+ break;
+ }
+ n++;
+ if (r == '\\') {
+ if (!scan_escape(t, quote)) {
+ valid = false;
+ }
+ }
}
- break;
+
+ // TODO(bill): Better Error Handling
+ if (valid && n != 1) {
+ tokenizer_err(t, "Invalid rune literal");
+ }
+ token.string.len = t->curr - token.string.text;
+ success = unquote_string(heap_allocator(), &token.string);
+ if (success > 0) {
+ if (success == 2) {
+ array_add(&t->allocated_strings, token.string);
+ }
+ return token;
+ } else {
+ tokenizer_err(t, "Invalid rune literal");
+ }
+ } break;
case '`': // Raw String Literal
case '"': // String Literal
{
+ i32 success;
Rune quote = curr_rune;
token.kind = Token_String;
if (curr_rune == '"') {
@@ -677,10 +707,12 @@ Token tokenizer_get_token(Tokenizer *t) {
break;
}
advance_to_next_rune(t);
- if (r == quote)
+ if (r == quote) {
break;
- if (r == '\\')
- scan_escape(t, '"');
+ }
+ if (r == '\\') {
+ scan_escape(t, quote);
+ }
}
} else {
for (;;) {
@@ -690,12 +722,13 @@ Token tokenizer_get_token(Tokenizer *t) {
break;
}
advance_to_next_rune(t);
- if (r == quote)
+ if (r == quote) {
break;
+ }
}
}
token.string.len = t->curr - token.string.text;
- i32 success = unquote_string(heap_allocator(), &token.string);
+ success = unquote_string(heap_allocator(), &token.string);
if (success > 0) {
if (success == 2) {
array_add(&t->allocated_strings, token.string);
diff --git a/src/unicode.c b/src/unicode.c
index 5c9f91f46..e4bf28be8 100644
--- a/src/unicode.c
+++ b/src/unicode.c
@@ -42,10 +42,10 @@ bool rune_is_whitespace(Rune r) {
bool is_string_an_identifier(String s) {
+ isize offset = 0;
if (s.len < 1) {
return false;
}
- isize offset = 0;
while (offset < s.len) {
bool ok = false;
Rune r = -1;