Overloaded free; 3 dotted ellipsis

This commit is contained in:
Ginger Bill
2017-01-28 20:16:18 +00:00
parent 31aacd5bf4
commit e86c990b75
12 changed files with 111 additions and 48 deletions
+28 -6
View File
@@ -1519,12 +1519,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
return;
}
bool is_value =
o->mode == Addressing_Variable ||
o->mode == Addressing_Value ||
o->mode == Addressing_Constant;
if (!is_value || is_type_untyped(t)) {
if (!is_operand_value(*o) || is_type_untyped(t)) {
if (ast_node_expect(node, AstNode_UnaryExpr)) {
ast_node(ue, UnaryExpr, node);
gbString str = expr_to_string(ue->expr);
@@ -2536,6 +2531,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
// TODO(bill): This is the rule I need?
if (sel.indirect || operand->mode != Addressing_Value) {
operand->mode = Addressing_Variable;
} else {
operand->mode = Addressing_Value;
}
break;
case Entity_TypeName:
@@ -2645,6 +2642,31 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = make_type_slice(c->allocator, type);
} break;
case BuiltinProc_free: {
// free :: proc(^Type)
// free :: proc([]Type)
// free :: proc(string)
Type *type = operand->type;
bool ok = false;
if (is_type_pointer(type)) {
ok = true;
} else if (is_type_slice(type)) {
ok = true;
} else if (is_type_string(type)) {
ok = true;
}
if (!ok) {
gbString type_str = type_to_string(type);
error_node(operand->expr, "You can only free pointers, slices, and strings, got `%s`", type_str);
gb_string_free(type_str);
return false;
}
operand->mode = Addressing_NoValue;
} break;
case BuiltinProc_size_of: {
// size_of :: proc(Type) -> untyped int
Type *type = check_type(c, ce->args.e[0]);
+5 -3
View File
@@ -5,8 +5,8 @@ typedef enum AddressingMode {
Addressing_Invalid,
Addressing_NoValue,
Addressing_Value, // R-value
Addressing_Variable, // L-value
Addressing_Value,
Addressing_Variable,
Addressing_Constant,
Addressing_Type,
Addressing_Builtin,
@@ -123,6 +123,7 @@ typedef enum BuiltinProcId {
BuiltinProc_new,
BuiltinProc_new_slice,
BuiltinProc_free,
BuiltinProc_size_of,
BuiltinProc_size_of_val,
@@ -165,7 +166,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT(""), 0, false, Expr_Stmt},
{STR_LIT("new"), 1, false, Expr_Expr},
{STR_LIT("new_slice"), 2, false, Expr_Expr},
{STR_LIT("new_slice"), 2, false, Expr_Expr},
{STR_LIT("free"), 1, false, Expr_Stmt},
{STR_LIT("size_of"), 1, false, Expr_Expr},
{STR_LIT("size_of_val"), 1, false, Expr_Expr},
+3 -7
View File
@@ -4819,14 +4819,10 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) {
#else
// TODO(bill): *nix version that's decent
case gbAllocation_Alloc: {
gbAllocationHeader *header;
isize total_size = size + alignment + gb_size_of(gbAllocationHeader);
ptr = malloc(total_size);
header = cast(gbAllocationHeader *)ptr;
ptr = gb_align_forward(header+1, alignment);
gb_allocation_header_fill(header, ptr, size);
if (flags & gbAllocatorFlag_ClearToZero)
ptr = aligned_alloc(alignment, size);
if (flags & gbAllocatorFlag_ClearToZero) {
gb_zero_size(ptr, size);
}
} break;
case gbAllocation_Free: {
+31
View File
@@ -2909,6 +2909,37 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
return ir_emit_load(proc, slice);
} break;
case BuiltinProc_free: {
ir_emit_comment(proc, str_lit("free"));
gbAllocator allocator = proc->module->allocator;
AstNode *node = ce->args.e[0];
TypeAndValue tav = *type_and_value_of_expression(proc->module->info, node);
Type *type = base_type(tav.type);
irValue *val = ir_build_expr(proc, node);
irValue *ptr = NULL;
if (is_type_pointer(type)) {
ptr = val;
} else if (is_type_slice(type)) {
ptr = ir_slice_elem(proc, val);
} else if (is_type_string(type)) {
ptr = ir_string_elem(proc, val);
} else {
GB_PANIC("Invalid type to `free`");
}
if (ptr == NULL) {
return NULL;
}
ptr = ir_emit_conv(proc, ptr, t_rawptr);
irValue **args = gb_alloc_array(allocator, irValue *, 1);
args[0] = ptr;
return ir_emit_global_call(proc, "free_ptr", args, 1);
} break;
case BuiltinProc_assert: {
ir_emit_comment(proc, str_lit("assert"));
irValue *cond = ir_build_expr(proc, ce->args.e[0]);
+12 -5
View File
@@ -149,7 +149,7 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
AST_NODE_KIND(DemaybeExpr, "demaybe expression", struct { Token op; AstNode *expr; }) \
AST_NODE_KIND(SliceExpr, "slice expression", struct { \
AstNode *expr; \
Token open, close; \
Token open, close, interval; \
AstNode *low, *high; \
}) \
AST_NODE_KIND(CallExpr, "call expression", struct { \
@@ -716,11 +716,12 @@ AstNode *make_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open,
}
AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, AstNode *low, AstNode *high) {
AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, Token interval, AstNode *low, AstNode *high) {
AstNode *result = make_node(f, AstNode_SliceExpr);
result->SliceExpr.expr = expr;
result->SliceExpr.open = open;
result->SliceExpr.close = close;
result->SliceExpr.interval = interval;
result->SliceExpr.low = low;
result->SliceExpr.high = high;
return result;
@@ -1970,19 +1971,25 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
if (lhs) {
// TODO(bill): Handle this
}
Token open, close;
Token open = {0}, close = {0}, interval = {0};
AstNode *indices[2] = {0};
f->expr_level++;
open = expect_token(f, Token_OpenBracket);
// if (f->curr_token.kind != Token_Ellipsis &&
// f->curr_token.kind != Token_HalfOpenRange) {
if (f->curr_token.kind != Token_Colon) {
indices[0] = parse_expr(f, false);
}
bool is_index = true;
if (allow_token(f, Token_Colon)) {
// if (f->curr_token.kind == Token_Ellipsis ||
// f->curr_token.kind == Token_HalfOpenRange) {
if (f->curr_token.kind == Token_Colon) {
is_index = false;
interval = f->curr_token;
next_token(f);
if (f->curr_token.kind != Token_CloseBracket &&
f->curr_token.kind != Token_EOF) {
indices[1] = parse_expr(f, false);
@@ -1995,7 +2002,7 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
if (is_index) {
operand = make_index_expr(f, operand, indices[0], open, close);
} else {
operand = make_slice_expr(f, operand, open, close, indices[0], indices[1]);
operand = make_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
}
} break;
+4 -2
View File
@@ -75,7 +75,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \
TOKEN_KIND(Token_Semicolon, ";"), \
TOKEN_KIND(Token_Period, "."), \
TOKEN_KIND(Token_Comma, ","), \
TOKEN_KIND(Token_Ellipsis, ".."), \
TOKEN_KIND(Token_Ellipsis, "..."), \
TOKEN_KIND(Token_HalfOpenRange, "..<"), \
TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \
\
@@ -847,10 +847,12 @@ Token tokenizer_get_token(Tokenizer *t) {
token.kind = Token_Period; // Default
if (t->curr_rune == '.') { // Could be an ellipsis
advance_to_next_rune(t);
token.kind = Token_Ellipsis;
if (t->curr_rune == '<') {
advance_to_next_rune(t);
token.kind = Token_HalfOpenRange;
} else if (t->curr_rune == '.') {
advance_to_next_rune(t);
token.kind = Token_Ellipsis;
}
}
break;