aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-04-02 18:16:45 +0100
committerGinger Bill <bill@gingerbill.org>2017-04-02 18:16:45 +0100
commit8ce58573dfa2c140dcafd633e51c56d555f7ebc1 (patch)
tree0bbcfca14f77f8cbcbb6385e72148d3fbb1caedb /src
parent2c8b99337bb33d0f713026c5c38e05428cc52143 (diff)
len, cap, make; remove .count, .capacity, new_slice
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c133
-rw-r--r--src/checker.c12
-rw-r--r--src/ir.c221
-rw-r--r--src/tokenizer.c10
-rw-r--r--src/types.c21
5 files changed, 373 insertions, 24 deletions
diff --git a/src/check_expr.c b/src/check_expr.c
index 55dcdb941..477520aa7 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -249,8 +249,12 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
operand->mode = Addressing_Invalid;
return;
}
- target_type = default_type(operand->type);
- GB_ASSERT(is_type_typed(target_type));
+ if (is_type_any(type)) {
+ target_type = t_any;
+ } else {
+ target_type = default_type(operand->type);
+ }
+ GB_ASSERT_MSG(is_type_typed(target_type), "%s", type_to_string(type));
add_type_info_type(c, type);
add_type_info_type(c, target_type);
}
@@ -1963,7 +1967,9 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
switch (op) {
case Token_CmpEq:
case Token_NotEq:
- defined = is_type_comparable(x->type);
+ defined = is_type_comparable(x->type) ||
+ (is_operand_nil(*x) && type_has_nil(y->type)) ||
+ (is_operand_nil(*y) && type_has_nil(x->type));
break;
case Token_Lt:
case Token_Gt:
@@ -1973,6 +1979,7 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
} break;
}
+ #if 0
// CLEANUP(bill) NOTE(bill): there is an auto assignment to `any` which needs to be checked
if (is_type_any(x->type) && !is_type_any(y->type)) {
err_type = x->type;
@@ -1981,8 +1988,14 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
err_type = y->type;
defined = false;
}
+ #endif
if (!defined) {
+ if (x->type == err_type && is_operand_nil(*x)) {
+ err_type = y->type;
+ }
+ gb_printf_err("%d %d\n", is_operand_nil(*x), type_has_nil(y->type));
+ gb_printf_err("%d %d\n", is_operand_nil(*y), type_has_nil(x->type));
gbString type_string = type_to_string(err_type);
err_str = gb_string_make(c->tmp_allocator,
gb_bprintf("operator `%.*s` not defined for type `%s`", LIT(token_strings[op]), type_string));
@@ -2659,7 +2672,9 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
break;
case Basic_UntypedNil:
- if (!type_has_nil(target_type)) {
+ if (is_type_any(target_type)) {
+ target_type = t_untyped_nil;
+ } else if (!type_has_nil(target_type)) {
operand->mode = Addressing_Invalid;
convert_untyped_error(c, operand, target_type);
return;
@@ -3070,11 +3085,11 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
}
}
- Operand prev_operand = *operand;
switch (id) {
case BuiltinProc_new:
- case BuiltinProc_new_slice:
+ // case BuiltinProc_new_slice:
+ case BuiltinProc_make:
case BuiltinProc_size_of:
case BuiltinProc_align_of:
case BuiltinProc_offset_of:
@@ -3090,6 +3105,53 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
GB_PANIC("Implement builtin procedure: %.*s", LIT(builtin_procs[id].name));
break;
+ case BuiltinProc_len:
+ case BuiltinProc_cap: {
+ // len :: proc(Type) -> int
+ // cap :: proc(Type) -> int
+ Type *op_type = type_deref(operand->type);
+ Type *type = t_int;
+ AddressingMode mode = Addressing_Invalid;
+ ExactValue value = {0};
+ if (is_type_string(op_type) && id == BuiltinProc_len) {
+ if (operand->mode == Addressing_Constant) {
+ mode = Addressing_Constant;
+ String str = operand->value.value_string;
+ value = exact_value_integer(str.len);
+ type = t_untyped_integer;
+ } else {
+ mode = Addressing_Value;
+ }
+ } else if (is_type_array(op_type)) {
+ Type *at = core_type(op_type);
+ mode = Addressing_Constant;
+ value = exact_value_integer(at->Array.count);
+ type = t_untyped_integer;
+ } else if (is_type_vector(op_type) && id == BuiltinProc_len) {
+ Type *at = core_type(op_type);
+ mode = Addressing_Constant;
+ value = exact_value_integer(at->Vector.count);
+ type = t_untyped_integer;
+ } else if (is_type_slice(op_type)) {
+ mode = Addressing_Value;
+ } else if (is_type_dynamic_array(op_type)) {
+ mode = Addressing_Value;
+ } else if (is_type_map(op_type)) {
+ mode = Addressing_Value;
+ }
+
+ if (mode == Addressing_Invalid) {
+ String name = builtin_procs[id].name;
+ gbString t = type_to_string(operand->type);
+ error_node(call, "`%.*s` is not supported for `%s`", LIT(name), t);
+ return false;
+ }
+
+ operand->mode = mode;
+ operand->value = value;
+ operand->type = type;
+ } break;
+
case BuiltinProc_new: {
// new :: proc(Type) -> ^Type
Operand op = {0};
@@ -3102,6 +3164,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Value;
operand->type = make_type_pointer(c->allocator, type);
} break;
+ #if 0
case BuiltinProc_new_slice: {
// new_slice :: proc(Type, len: int) -> []Type
// new_slice :: proc(Type, len, cap: int) -> []Type
@@ -3139,6 +3202,62 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Value;
operand->type = make_type_slice(c->allocator, type);
} break;
+ #endif
+ case BuiltinProc_make: {
+ // make :: proc(Type, len: int) -> []Type
+ // make :: proc(Type, len, cap: int) -> []Type
+ Operand op = {0};
+ check_expr_or_type(c, &op, ce->args.e[0]);
+ Type *type = op.type;
+ if ((op.mode != Addressing_Type && type == NULL) || type == t_invalid) {
+ error_node(ce->args.e[0], "Expected a type for `make`");
+ return false;
+ }
+
+ isize min_args = 0;
+ isize max_args = 1;
+ if (is_type_slice(type)) {
+ min_args = 2;
+ max_args = 3;
+ } else if (is_type_dynamic_map(type)) {
+ min_args = 1;
+ max_args = 2;
+ } else if (is_type_dynamic_array(type)) {
+ min_args = 1;
+ max_args = 3;
+ } else {
+ gbString str = type_to_string(type);
+ error_node(call, "Cannot `make` %s; type must be a slice, map, or dynamic array", str);
+ gb_string_free(str);
+ return false;
+ }
+
+ isize arg_count = ce->args.count;
+ if (arg_count < min_args || max_args < arg_count) {
+ error_node(ce->args.e[0], "`make` expects %td or %d argument, found %td", min_args, max_args, arg_count);
+ return false;
+ }
+
+ // If any are constant
+ i64 sizes[4] = {0};
+ isize size_count = 0;
+ for (isize i = 1; i < arg_count; i++) {
+ i64 val = 0;
+ bool ok = check_index_value(c, ce->args.e[i], -1, &val);
+ if (ok && val >= 0) {
+ GB_ASSERT(size_count < gb_count_of(sizes));
+ sizes[size_count++] = val;
+ }
+ }
+
+ if (size_count == 2 && sizes[0] > sizes[1]) {
+ error_node(ce->args.e[1], "`make` count and capacity are swapped");
+ // No need quit
+ }
+
+ operand->mode = Addressing_Value;
+ operand->type = type;
+ } break;
case BuiltinProc_free: {
// free :: proc(^Type)
@@ -3216,6 +3335,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case BuiltinProc_append: {
// append :: proc([dynamic]Type, item: ..Type)
// append :: proc([]Type, item: ..Type)
+ Operand prev_operand = *operand;
+
Type *type = operand->type;
bool is_pointer = is_type_pointer(type);
type = base_type(type_deref(type));
diff --git a/src/checker.c b/src/checker.c
index c594bbe8a..30b1857b5 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -23,9 +23,13 @@ typedef struct BuiltinProc {
typedef enum BuiltinProcId {
BuiltinProc_Invalid,
+ BuiltinProc_len,
+ BuiltinProc_cap,
+
BuiltinProc_new,
- BuiltinProc_new_slice,
BuiltinProc_free,
+ // BuiltinProc_new_slice,
+ BuiltinProc_make,
BuiltinProc_reserve,
BuiltinProc_clear,
@@ -75,9 +79,13 @@ typedef enum BuiltinProcId {
gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT(""), 0, false, Expr_Stmt},
+ {STR_LIT("len"), 1, false, Expr_Expr},
+ {STR_LIT("cap"), 1, false, Expr_Expr},
+
{STR_LIT("new"), 1, false, Expr_Expr},
- {STR_LIT("new_slice"), 2, true, Expr_Expr},
{STR_LIT("free"), 1, false, Expr_Stmt},
+ // {STR_LIT("new_slice"), 2, true, Expr_Expr},
+ {STR_LIT("make"), 1, true, Expr_Expr},
{STR_LIT("reserve"), 2, false, Expr_Stmt},
{STR_LIT("clear"), 1, false, Expr_Stmt},
diff --git a/src/ir.c b/src/ir.c
index bfe4f3781..a901ada4e 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -1470,6 +1470,7 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type)
GB_ASSERT_MSG(is_type_pointer(ir_type(map_val)), "%s", type_to_string(ir_type(map_val)));
gbAllocator a = proc->module->allocator;
irValue *h = ir_add_local_generated(proc, t_map_header);
+ map_type = base_type(map_type);
Type *key_type = map_type->Map.key;
Type *val_type = map_type->Map.value;
@@ -1962,12 +1963,74 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
return ir_emit(proc, ir_instr_binary_op(proc, op, left, right, type));
}
+irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue *x) {
+ Type *t = ir_type(x);
+ if (is_type_any(t)) {
+ irValue *ti = ir_emit_struct_ev(proc, x, 0);
+ irValue *data = ir_emit_struct_ev(proc, x, 1);
+ if (op_kind == Token_CmpEq) {
+ irValue *a = ir_emit_comp(proc, Token_CmpEq, ti, v_raw_nil);
+ irValue *b = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
+ return ir_emit_arith(proc, Token_Or, a, b, t_bool);
+ } else if (op_kind == Token_NotEq) {
+ irValue *a = ir_emit_comp(proc, Token_NotEq, ti, v_raw_nil);
+ irValue *b = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
+ return ir_emit_arith(proc, Token_And, a, b, t_bool);
+ }
+ } else if (is_type_slice(t)) {
+ irValue *data = ir_emit_struct_ev(proc, x, 0);
+ irValue *cap = ir_emit_struct_ev(proc, x, 2);
+ if (op_kind == Token_CmpEq) {
+ irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
+ irValue *b = ir_emit_comp(proc, Token_CmpEq, cap, v_zero);
+ return ir_emit_arith(proc, Token_Or, a, b, t_bool);
+ } else if (op_kind == Token_NotEq) {
+ irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
+ irValue *b = ir_emit_comp(proc, Token_NotEq, cap, v_zero);
+ return ir_emit_arith(proc, Token_And, a, b, t_bool);
+ }
+ } else if (is_type_dynamic_array(t)) {
+ irValue *data = ir_emit_struct_ev(proc, x, 0);
+ irValue *cap = ir_emit_struct_ev(proc, x, 2);
+ if (op_kind == Token_CmpEq) {
+ irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
+ irValue *b = ir_emit_comp(proc, Token_CmpEq, cap, v_zero);
+ return ir_emit_arith(proc, Token_Or, a, b, t_bool);
+ } else if (op_kind == Token_NotEq) {
+ irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
+ irValue *b = ir_emit_comp(proc, Token_NotEq, cap, v_zero);
+ return ir_emit_arith(proc, Token_And, a, b, t_bool);
+ }
+ } else if (is_type_map(t)) {
+ irValue *hashes = ir_emit_struct_ev(proc, x, 0);
+ irValue *entries = ir_emit_struct_ev(proc, x, 1);
+ irValue *a = ir_emit_comp_against_nil(proc, op_kind, hashes);
+ irValue *b = ir_emit_comp_against_nil(proc, op_kind, entries);
+ if (op_kind == Token_CmpEq) {
+ return ir_emit_arith(proc, Token_Or, a, b, t_bool);
+ } else if (op_kind == Token_NotEq) {
+ return ir_emit_arith(proc, Token_And, a, b, t_bool);
+ }
+ }
+ return NULL;
+}
+
irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irValue *right) {
Type *a = base_type(ir_type(left));
Type *b = base_type(ir_type(right));
GB_ASSERT(gb_is_between(op_kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1));
+ irValue *nil_check = NULL;
+ if (left->kind == irValue_Nil) {
+ nil_check = ir_emit_comp_against_nil(proc, op_kind, right);
+ } else if (right->kind == irValue_Nil) {
+ nil_check = ir_emit_comp_against_nil(proc, op_kind, left);
+ }
+ if (nil_check != NULL) {
+ return nil_check;
+ }
+
if (are_types_identical(a, b)) {
// NOTE(bill): No need for a conversion
} else if (left->kind == irValue_Constant || left->kind == irValue_Nil) {
@@ -3222,6 +3285,20 @@ void ir_build_defer_stmt(irProcedure *proc, irDefer d) {
}
+irValue *ir_emit_clamp(irProcedure *proc, Type *t, irValue *x, irValue *min, irValue *max) {
+ irValue *cond = NULL;
+ ir_emit_comment(proc, str_lit("clamp"));
+ x = ir_emit_conv(proc, x, t);
+ min = ir_emit_conv(proc, min, t);
+ max = ir_emit_conv(proc, max, t);
+
+ cond = ir_emit_comp(proc, Token_Gt, min, x);
+ x = ir_emit_select(proc, cond, min, x);
+ cond = ir_emit_comp(proc, Token_Lt, max, x);
+ x = ir_emit_select(proc, cond, max, x);
+ return x;
+}
+
irValue *ir_find_global_variable(irProcedure *proc, String name) {
irValue **value = map_ir_value_get(&proc->module->members, hash_string(name));
@@ -3505,6 +3582,59 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
return ir_type_info(proc, t);
} break;
+ case BuiltinProc_len: {
+ irValue *v = ir_build_expr(proc, ce->args.e[0]);
+ Type *t = base_type(ir_type(v));
+ if (is_type_pointer(t)) {
+ // IMPORTANT TODO(bill): Should there be a nil pointer check?
+ v = ir_emit_load(proc, v);
+ t = type_deref(t);
+ }
+ if (is_type_string(t)) {
+ return ir_string_len(proc, v);
+ } else if (is_type_array(t)) {
+ GB_PANIC("Array lengths are constant");
+ } else if (is_type_vector(t)) {
+ GB_PANIC("Vector lengths are constant");
+ } else if (is_type_slice(t)) {
+ return ir_slice_count(proc, v);
+ } else if (is_type_dynamic_array(t)) {
+ return ir_dynamic_array_count(proc, v);
+ } else if (is_type_map(t)) {
+ irValue *entries = ir_emit_struct_ev(proc, v, 1);
+ return ir_dynamic_array_count(proc, entries);
+ }
+
+ GB_PANIC("Unreachable");
+ } break;
+
+ case BuiltinProc_cap: {
+ irValue *v = ir_build_expr(proc, ce->args.e[0]);
+ Type *t = base_type(ir_type(v));
+ if (is_type_pointer(t)) {
+ // IMPORTANT TODO(bill): Should there be a nil pointer check?
+ v = ir_emit_load(proc, v);
+ t = type_deref(t);
+ }
+ if (is_type_string(t)) {
+ GB_PANIC("Unreachable");
+ } else if (is_type_array(t)) {
+ GB_PANIC("Array lengths are constant");
+ } else if (is_type_vector(t)) {
+ GB_PANIC("Unreachable");
+ } else if (is_type_slice(t)) {
+ return ir_slice_capacity(proc, v);
+ } else if (is_type_dynamic_array(t)) {
+ return ir_dynamic_array_capacity(proc, v);
+ } else if (is_type_map(t)) {
+ irValue *entries = ir_emit_struct_ev(proc, v, 1);
+ return ir_dynamic_array_capacity(proc, entries);
+ }
+
+ GB_PANIC("Unreachable");
+
+ } break;
+
case BuiltinProc_new: {
ir_emit_comment(proc, str_lit("new"));
// new :: proc(Type) -> ^Type
@@ -3524,6 +3654,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
return v;
} break;
+ #if 0
case BuiltinProc_new_slice: {
ir_emit_comment(proc, str_lit("new_slice"));
// new_slice :: proc(Type, len: int) -> []Type
@@ -3562,6 +3693,83 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
ir_fill_slice(proc, slice, ptr, count, capacity);
return ir_emit_load(proc, slice);
} break;
+ #endif
+ case BuiltinProc_make: {
+ ir_emit_comment(proc, str_lit("make"));
+ gbAllocator a = proc->module->allocator;
+ Type *type = type_of_expr(proc->module->info, ce->args.e[0]);
+
+ if (is_type_slice(type)) {
+ Type *elem_type = core_type(type)->Slice.elem;
+ Type *elem_ptr_type = make_type_pointer(a, elem_type);
+
+ irValue *elem_size = ir_const_int(a, type_size_of(a, elem_type));
+ irValue *elem_align = ir_const_int(a, type_align_of(a, elem_type));
+
+ irValue *count = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int);
+ irValue *capacity = count;
+
+ if (ce->args.count == 3) {
+ capacity = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[2]), t_int);
+ }
+
+ ir_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[1]), v_zero, count, capacity, false);
+
+ irValue *slice_size = ir_emit_arith(proc, Token_Mul, elem_size, capacity, t_int);
+
+ irValue **args = gb_alloc_array(a, irValue *, 2);
+ args[0] = slice_size;
+ args[1] = elem_align;
+ irValue *call = ir_emit_global_call(proc, "alloc_align", args, 2);
+
+ irValue *ptr = ir_emit_conv(proc, call, elem_ptr_type);
+ irValue *slice = ir_add_local_generated(proc, type);
+
+ ir_fill_slice(proc, slice, ptr, count, capacity);
+ return ir_emit_load(proc, slice);
+ } else if (is_type_dynamic_map(type)) {
+ irValue *int_16 = ir_const_int(a, 16);
+ irValue *cap = v_zero;
+ if (ce->args.count == 2) {
+ cap = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int);
+ }
+
+ irValue *cond = ir_emit_comp(proc, Token_Gt, cap, v_zero);
+ cap = ir_emit_select(proc, cond, cap, int_16);
+
+ irValue *map = ir_add_local_generated(proc, type);
+ irValue *header = ir_gen_map_header(proc, map, base_type(type));
+ irValue **args = gb_alloc_array(a, irValue *, 2);
+ args[0] = header;
+ args[1] = cap;
+ ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2);
+
+ return ir_emit_load(proc, map);
+ } else if (is_type_dynamic_array(type)) {
+ Type *elem_type = base_type(type)->DynamicArray.elem;
+ irValue *len = v_zero;
+ irValue *cap = ir_const_int(a, 8);
+ if (ce->args.count > 1) {
+ len = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int);
+ }
+ if (ce->args.count > 2) {
+ cap = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[2]), t_int);
+ }
+
+ ir_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[0]), v_zero, len, cap, false);
+
+ irValue *array = ir_add_local_generated(proc, type);
+ irValue **args = gb_alloc_array(a, irValue *, 5);
+ args[0] = array;
+ args[1] = ir_const_int(a, type_size_of(a, elem_type));
+ args[2] = ir_const_int(a, type_align_of(a, elem_type));;
+ args[3] = len;
+ args[4] = cap;
+ ir_emit_global_call(proc, "__dynamic_array_make", args, 5);
+
+ return ir_emit_load(proc, array);
+ }
+ } break;
case BuiltinProc_free: {
ir_emit_comment(proc, str_lit("free"));
@@ -4112,15 +4320,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
case BuiltinProc_clamp: {
ir_emit_comment(proc, str_lit("clamp"));
Type *t = type_of_expr(proc->module->info, expr);
- irValue *x = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[0]), t);
- irValue *min = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t);
- irValue *max = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[2]), t);
- irValue *cond;
- cond = ir_emit_comp(proc, Token_Gt, min, x);
- x = ir_emit_select(proc, cond, min, x);
- cond = ir_emit_comp(proc, Token_Lt, max, x);
- x = ir_emit_select(proc, cond, max, x);
- return x;
+ return ir_emit_clamp(proc, t,
+ ir_build_expr(proc, ce->args.e[0]),
+ ir_build_expr(proc, ce->args.e[1]),
+ ir_build_expr(proc, ce->args.e[2]));
} break;
}
}
diff --git a/src/tokenizer.c b/src/tokenizer.c
index 398f39f98..2ef1a7add 100644
--- a/src/tokenizer.c
+++ b/src/tokenizer.c
@@ -619,20 +619,22 @@ bool scan_escape(Tokenizer *t, Rune quote) {
advance_to_next_rune(t);
len = 8; base = 16; max = GB_RUNE_MAX;
} else {
- if (t->curr_rune < 0)
+ if (t->curr_rune < 0) {
tokenizer_err(t, "Escape sequence was not terminated");
- else
+ } else {
tokenizer_err(t, "Unknown escape sequence");
+ }
return false;
}
while (len --> 0) {
u32 d = cast(u32)digit_value(t->curr_rune);
if (d >= base) {
- if (t->curr_rune < 0)
+ if (t->curr_rune < 0) {
tokenizer_err(t, "Escape sequence was not terminated");
- else
+ } else {
tokenizer_err(t, "Illegal character %d in escape sequence", t->curr_rune);
+ }
return false;
}
diff --git a/src/types.c b/src/types.c
index 9735e6e38..c99aeeb18 100644
--- a/src/types.c
+++ b/src/types.c
@@ -834,9 +834,10 @@ bool type_has_nil(Type *t) {
return false;
} break;
case Type_Slice:
- case Type_DynamicArray:
case Type_Proc:
case Type_Pointer:
+ case Type_DynamicArray:
+ case Type_Map:
return true;
}
return false;
@@ -1232,6 +1233,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
if (type->kind == Type_Basic) {
switch (type->Basic.kind) {
case Basic_any: {
+ #if 1
+ // IMPORTANT TODO(bill): Should these members be available to should I only allow them with
+ // `Raw_Any` type?
String type_info_str = str_lit("type_info");
String data_str = str_lit("data");
if (entity__any_type_info == NULL) {
@@ -1250,8 +1254,10 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__any_data;
return sel;
}
+ #endif
} break;
case Basic_string: {
+ #if 0
String data_str = str_lit("data");
String count_str = str_lit("count");
if (entity__string_data == NULL) {
@@ -1271,11 +1277,13 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__string_count;
return sel;
}
+ #endif
} break;
}
return sel;
} else if (type->kind == Type_Array) {
+ #if 0
String count_str = str_lit("count");
// NOTE(bill): Underlying memory address cannot be changed
if (str_eq(field_name, count_str)) {
@@ -1283,7 +1291,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, exact_value_integer(type->Array.count));
return sel;
}
+ #endif
} else if (type->kind == Type_Vector) {
+ #if 0
String count_str = str_lit("count");
// NOTE(bill): Vectors are not addressable
if (str_eq(field_name, count_str)) {
@@ -1291,7 +1301,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, exact_value_integer(type->Vector.count));
return sel;
}
-
+ #endif
if (type->Vector.count <= 4 && !is_type_boolean(type->Vector.elem)) {
// HACK(bill): Memory leak
switch (type->Vector.count) {
@@ -1315,6 +1325,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
}
} else if (type->kind == Type_Slice) {
+ #if 0
String data_str = str_lit("data");
String count_str = str_lit("count");
String capacity_str = str_lit("capacity");
@@ -1341,8 +1352,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__slice_capacity;
return sel;
}
-
+ #endif
} else if (type->kind == Type_DynamicArray) {
+ #if 0
String data_str = str_lit("data");
String count_str = str_lit("count");
String capacity_str = str_lit("capacity");
@@ -1375,7 +1387,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__dynamic_array_allocator;
return sel;
}
+ #endif
} else if (type->kind == Type_Map) {
+ #if 0
String count_str = str_lit("count");
String capacity_str = str_lit("capacity");
String allocator_str = str_lit("allocator");
@@ -1405,6 +1419,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__dynamic_map_allocator;
return sel;
}
+ #endif
}
if (is_type) {