aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2018-08-04 23:14:55 +0100
committergingerBill <bill@gingerbill.org>2018-08-04 23:14:55 +0100
commitcdbf831a7a6d9bc36e3cf76d525c44af88dc0a53 (patch)
treeea6d0be0d032a77f6d7c0303be4dffd31c837412 /src
parent0718f14774c152b84edb747c03ca53b9400407b9 (diff)
Replace `context <- c {}` with `context = c;`. context assignments are scope based
Diffstat (limited to 'src')
-rw-r--r--src/array.cpp9
-rw-r--r--src/check_expr.cpp17
-rw-r--r--src/check_stmt.cpp15
-rw-r--r--src/common.cpp44
-rw-r--r--src/ir.cpp104
-rw-r--r--src/parser.cpp36
-rw-r--r--src/parser.hpp7
7 files changed, 118 insertions, 114 deletions
diff --git a/src/array.cpp b/src/array.cpp
index c28463c1b..1d3ceafed 100644
--- a/src/array.cpp
+++ b/src/array.cpp
@@ -41,6 +41,15 @@ template <typename T> void array_set_capacity (Array<T> *array, isize capaci
template <typename T> Array<T> array_slice (Array<T> const &array, isize lo, isize hi);
template <typename T>
+T *array_end_ptr(Array<T> *array) {
+ if (array->count > 0) {
+ return &array->data[array->count-1];
+ }
+ return nullptr;
+}
+
+
+template <typename T>
gb_inline void array_init(Array<T> *array, gbAllocator const &a) {
isize cap = ARRAY_GROW_FORMULA(0);
array_init(array, a, 0, cap);
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 479103241..163d7f6d0 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -578,7 +578,7 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type
if (is_type_any(dst)) {
if (!is_type_polymorphic(src)) {
- if (operand->mode == Addressing_Immutable && operand->type == t_context) {
+ if (operand->mode == Addressing_Context && operand->type == t_context) {
return -1;
} else {
// NOTE(bill): Anything can cast to 'Any'
@@ -2040,6 +2040,17 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node) {
return;
}
+ if (x->mode == Addressing_Builtin) {
+ x->mode = Addressing_Invalid;
+ error(x->expr, "built-in expression in binary expression");
+ return;
+ }
+ if (y->mode == Addressing_Builtin) {
+ x->mode = Addressing_Invalid;
+ error(y->expr, "built-in expression in binary expression");
+ return;
+ }
+
if (token_is_shift(op.kind)) {
check_shift(c, x, y, node);
return;
@@ -2724,6 +2735,8 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
// TODO(bill): Is this the rule I need?
if (operand->mode == Addressing_Immutable) {
// Okay
+ } else if (operand->mode == Addressing_Context) {
+ operand->mode = Addressing_Value; // TODO(bill): Should this be Value or Immutable?
} else if (sel.indirect || operand->mode != Addressing_Value) {
operand->mode = Addressing_Variable;
} else {
@@ -5211,7 +5224,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
}
init_core_context(c->checker);
- o->mode = Addressing_Immutable;
+ o->mode = Addressing_Context;
o->type = t_context;
break;
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 4a98db600..4a7c6c621 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -167,10 +167,6 @@ bool check_is_terminating(Ast *node) {
}
return has_default;
case_end;
-
- case_ast_node(pc, PushContext, node);
- return check_is_terminating(pc->body);
- case_end;
}
return false;
@@ -306,6 +302,10 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs)
break;
}
+ case Addressing_Context: {
+ break;
+ }
+
default: {
if (lhs->expr->kind == Ast_SelectorExpr) {
// NOTE(bill): Extra error checks
@@ -1597,13 +1597,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
}
case_end;
- case_ast_node(pa, PushContext, node);
- Operand op = {};
- check_expr(ctx, &op, pa->expr);
- check_assignment(ctx, &op, t_context, str_lit("argument to context <-"));
- check_stmt(ctx, pa->body, mod_flags);
- case_end;
-
case_ast_node(fb, ForeignBlockDecl, node);
Ast *foreign_library = fb->foreign_library;
CheckerContext c = *ctx;
diff --git a/src/common.cpp b/src/common.cpp
index e7024ae43..3a9bb874b 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -338,6 +338,7 @@ gb_global bool global_module_path_set = false;
typedef struct Arena {
u8 * ptr;
u8 * end;
+ u8 * prev;
Array<u8 *> blocks;
gbAllocator backing;
isize block_size;
@@ -363,11 +364,11 @@ void arena_grow(Arena *arena, isize min_size) {
isize size = gb_max(arena->block_size, min_size);
size = ALIGN_UP(size, ARENA_MIN_ALIGNMENT);
void *new_ptr = gb_alloc(arena->backing, size);
- arena->ptr = cast(u8 *)new_ptr;
- gb_zero_size(arena->ptr, size);
- GB_ASSERT(arena->ptr == ALIGN_DOWN_PTR(arena->ptr, ARENA_MIN_ALIGNMENT));
- arena->end = arena->ptr + size;
- array_add(&arena->blocks, arena->ptr);
+ arena->ptr = cast(u8 *)new_ptr;
+ gb_zero_size(arena->ptr, size);
+ GB_ASSERT(arena->ptr == ALIGN_DOWN_PTR(arena->ptr, ARENA_MIN_ALIGNMENT));
+ arena->end = arena->ptr + size;
+ array_add(&arena->blocks, arena->ptr);
}
void *arena_alloc(Arena *arena, isize size, isize alignment) {
@@ -376,18 +377,19 @@ void *arena_alloc(Arena *arena, isize size, isize alignment) {
arena->total_used += size;
- if (size > (arena->end - arena->ptr)) {
- arena_grow(arena, size);
- GB_ASSERT(size <= (arena->end - arena->ptr));
- }
+ if (size > (arena->end - arena->ptr)) {
+ arena_grow(arena, size);
+ GB_ASSERT(size <= (arena->end - arena->ptr));
+ }
- isize align = gb_max(alignment, ARENA_MIN_ALIGNMENT);
- void *ptr = arena->ptr;
- arena->ptr = cast(u8 *)ALIGN_UP_PTR(arena->ptr + size, align);
- GB_ASSERT(arena->ptr <= arena->end);
- GB_ASSERT(ptr == ALIGN_DOWN_PTR(ptr, align));
- gb_zero_size(ptr, size);
- return ptr;
+ isize align = gb_max(alignment, ARENA_MIN_ALIGNMENT);
+ void *ptr = arena->ptr;
+ arena->prev = arena->ptr;
+ arena->ptr = cast(u8 *)ALIGN_UP_PTR(arena->ptr + size, align);
+ GB_ASSERT(arena->ptr <= arena->end);
+ GB_ASSERT(ptr == ALIGN_DOWN_PTR(ptr, align));
+ gb_zero_size(ptr, size);
+ return ptr;
}
void arena_free_all(Arena *arena) {
@@ -395,11 +397,11 @@ void arena_free_all(Arena *arena) {
defer (gb_mutex_unlock(&arena->mutex));
for_array(i, arena->blocks) {
- gb_free(arena->backing, arena->blocks[i]);
- }
- array_clear(&arena->blocks);
- arena->ptr = nullptr;
- arena->end = nullptr;
+ gb_free(arena->backing, arena->blocks[i]);
+ }
+ array_clear(&arena->blocks);
+ arena->ptr = nullptr;
+ arena->end = nullptr;
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 274075dfa..535dcc73f 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -113,6 +113,11 @@ struct irDebugLocation {
irDebugInfo *debug_scope;
};
+struct irContextData {
+ irValue *value;
+ i32 scope_index;
+};
+
struct irProcedure {
irProcedure * parent;
Array<irProcedure *> children;
@@ -142,7 +147,7 @@ struct irProcedure {
irTargetList * target_list;
Array<irValue *> referrers;
- Array<irValue *> context_stack;
+ Array<irContextData> context_stack;
Array<irBranchBlocks> branch_blocks;
@@ -443,6 +448,7 @@ enum irAddrKind {
irAddr_Default,
irAddr_Map,
irAddr_BitField,
+ irAddr_Context,
};
struct irAddr {
@@ -473,6 +479,13 @@ irAddr ir_addr_map(irValue *addr, irValue *map_key, Type *map_type, Type *map_re
return v;
}
+
+irAddr ir_addr_context(irValue *addr) {
+ irAddr v = {irAddr_Context, addr};
+ return v;
+}
+
+
irAddr ir_addr_bit_field(irValue *addr, i32 bit_field_value_index) {
irAddr v = {irAddr_BitField, addr};
v.bit_field_value_index = bit_field_value_index;
@@ -1354,7 +1367,10 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
-
+void ir_push_context_onto_stack(irProcedure *proc, irValue *ctx) {
+ irContextData cd = {ctx, proc->scope_index};
+ array_add(&proc->context_stack, cd);
+}
irValue *ir_add_local(irProcedure *proc, Entity *e, Ast *expr, bool zero_initialized) {
irBlock *b = proc->decl_block; // all variables must be in the first block
@@ -1622,7 +1638,7 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index);
irValue *ir_find_or_generate_context_ptr(irProcedure *proc) {
if (proc->context_stack.count > 0) {
- return proc->context_stack[proc->context_stack.count-1];
+ return proc->context_stack[proc->context_stack.count-1].value;
}
irBlock *tmp_block = proc->curr_block;
@@ -1631,7 +1647,7 @@ irValue *ir_find_or_generate_context_ptr(irProcedure *proc) {
defer (proc->curr_block = tmp_block);
irValue *c = ir_add_local_generated(proc, t_context);
- array_add(&proc->context_stack, c);
+ ir_push_context_onto_stack(proc, c);
ir_emit_store(proc, c, ir_emit_load(proc, proc->module->global_default_context));
irValue *ep = ir_emit_struct_ep(proc, c, 0);
@@ -1763,6 +1779,21 @@ void ir_open_scope(irProcedure *proc) {
void ir_close_scope(irProcedure *proc, irDeferExitKind kind, irBlock *block) {
ir_emit_defer_stmts(proc, kind, block);
GB_ASSERT(proc->scope_index > 0);
+
+
+ // NOTE(bill): Remove `context`s made in that scope
+ for (;;) {
+ irContextData *end = array_end_ptr(&proc->context_stack);
+ if (end == nullptr) {
+ break;
+ }
+ if (end->scope_index != proc->scope_index) {
+ break;
+ }
+ array_pop(&proc->context_stack);
+ }
+
+
proc->scope_index--;
}
@@ -1923,6 +1954,7 @@ irValue *ir_emit_source_code_location(irProcedure *proc, String procedure, Token
irValue *ir_emit_source_code_location(irProcedure *proc, Ast *node);
irValue *ir_emit_ptr_offset(irProcedure *proc, irValue *ptr, irValue *offset);
irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *right, Type *type);
+irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel);
irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, Type *map_type,
irValue *map_key, irValue *map_value) {
@@ -1945,12 +1977,13 @@ irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, T
-irValue *ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
+void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
if (addr.addr == nullptr) {
- return nullptr;
+ return;
}
if (addr.kind == irAddr_Map) {
- return ir_insert_dynamic_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
+ ir_insert_dynamic_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value);
+ return;
} else if (addr.kind == irAddr_BitField) {
gbAllocator a = ir_allocator();
@@ -1966,7 +1999,7 @@ irValue *ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
i32 size_in_bytes = next_pow2((size_in_bits+7)/8);
if (size_in_bytes == 0) {
GB_ASSERT(size_in_bits == 0);
- return nullptr;
+ return;
}
Type *int_type = nullptr;
@@ -1994,7 +2027,8 @@ irValue *ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
}
irValue *ptr = ir_emit_conv(proc, bytes, alloc_type_pointer(int_type));
v = ir_emit_arith(proc, Token_Or, ir_emit_load(proc, ptr), v, int_type);
- return ir_emit_store(proc, ptr, v);
+ ir_emit_store(proc, ptr, v);
+ return;
}
@@ -2015,12 +2049,30 @@ irValue *ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
irValue *ptr = ir_emit_conv(proc, ir_emit_ptr_offset(proc, bytes, v_one), alloc_type_pointer(int_type));
irValue *v = ir_emit_arith(proc, Token_Shr, value, shift_amount, int_type);
v = ir_emit_arith(proc, Token_Or, ir_emit_load(proc, ptr), v, int_type);
- return ir_emit_store(proc, ptr, v);
+ ir_emit_store(proc, ptr, v);
+ return;
}
+ } else if (addr.kind == irAddr_Context) {
+ irValue *new_context = ir_emit_conv(proc, value, ir_addr_type(addr));
+
+ irValue *prev = ir_find_or_generate_context_ptr(proc);
+ GB_ASSERT(addr.addr == prev);
+
+ irValue *next = ir_add_local_generated(proc, t_context);
+ ir_emit_store(proc, next, new_context);
+
+ Selection sel = lookup_field(t_context, str_lit("parent"), false);
+ GB_ASSERT(sel.entity != nullptr);
+ irValue *parent_ptr = ir_emit_deep_field_gep(proc, next, sel);
+ ir_emit_store(proc, parent_ptr, prev);
+
+ ir_push_context_onto_stack(proc, next);
+
+ return;
}
irValue *v = ir_emit_conv(proc, value, ir_addr_type(addr));
- return ir_emit_store(proc, addr.addr, v);
+ ir_emit_store(proc, addr.addr, v);
}
irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) {
@@ -5559,7 +5611,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
}
GB_ASSERT(v != nullptr);
- return ir_addr(v);
+ return ir_addr_context(v);
case_end;
case_ast_node(i, Ident, expr);
@@ -7408,32 +7460,6 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
ir_emit_jump(proc, block);
ir_emit_unreachable(proc);
case_end;
-
-
- case_ast_node(pc, PushContext, node);
- ir_emit_comment(proc, str_lit("push_context"));
- irValue *new_context = ir_build_expr(proc, pc->expr);
-
- ir_open_scope(proc);
-
- irValue *prev = ir_find_or_generate_context_ptr(proc);
- irValue *next = ir_add_local_generated(proc, t_context);
- ir_emit_store(proc, next, new_context);
-
- Selection sel = lookup_field(t_context, str_lit("parent"), false);
- GB_ASSERT(sel.entity != nullptr);
- irValue *parent_ptr = ir_emit_deep_field_gep(proc, next, sel);
- ir_emit_store(proc, parent_ptr, prev);
-
- array_add(&proc->context_stack, next);
- defer (array_pop(&proc->context_stack));
-
- ir_build_stmt(proc, pc->body);
-
- ir_close_scope(proc, irDeferExit_Default, nullptr);
- case_end;
-
-
}
}
@@ -7583,7 +7609,7 @@ void ir_begin_procedure_body(irProcedure *proc) {
e->flags |= EntityFlag_NoAlias;
irValue *param = ir_value_param(proc, e, e->type);
ir_module_add_value(proc->module, e, param);
- array_add(&proc->context_stack, param);
+ array_add(&proc->context_stack, {param, proc->scope_index});
}
}
diff --git a/src/parser.cpp b/src/parser.cpp
index 0b0c77bf0..a1f8ff1e1 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -53,7 +53,6 @@ Token ast_token(Ast *node) {
case Ast_DeferStmt: return node->DeferStmt.token;
case Ast_BranchStmt: return node->BranchStmt.token;
case Ast_UsingStmt: return node->UsingStmt.token;
- case Ast_PushContext: return node->PushContext.token;
case Ast_BadDecl: return node->BadDecl.begin;
case Ast_Label: return node->Label.token;
@@ -274,10 +273,6 @@ Ast *clone_ast(Ast *node) {
case Ast_UsingStmt:
n->UsingStmt.list = clone_ast_array(n->UsingStmt.list);
break;
- case Ast_PushContext:
- n->PushContext.expr = clone_ast(n->PushContext.expr);
- n->PushContext.body = clone_ast(n->PushContext.body);
- break;
case Ast_BadDecl: break;
@@ -787,15 +782,6 @@ Ast *ast_using_stmt(AstFile *f, Token token, Array<Ast *> list) {
return result;
}
-Ast *ast_push_context(AstFile *f, Token token, Ast *expr, Ast *body) {
- Ast *result = alloc_ast_node(f, Ast_PushContext);
- result->PushContext.token = token;
- result->PushContext.expr = expr;
- result->PushContext.body = body;
- return result;
-}
-
-
Ast *ast_bad_decl(AstFile *f, Token begin, Token end) {
@@ -1267,7 +1253,6 @@ bool is_semicolon_optional_for_node(AstFile *f, Ast *s) {
case Ast_RangeStmt:
case Ast_SwitchStmt:
case Ast_TypeSwitchStmt:
- case Ast_PushContext:
return true;
case Ast_HelperType:
@@ -2540,25 +2525,6 @@ Ast *parse_simple_stmt(AstFile *f, u32 flags) {
}
}
return parse_value_decl(f, lhs, docs);
-
- case Token_ArrowLeft:
- if ((flags&StmtAllowFlag_Context) && lhs.count == 1) {
- Token arrow = expect_token(f, Token_ArrowLeft);
- Ast *body = nullptr;
- isize prev_level = f->expr_level;
- f->expr_level = -1;
- Ast *expr = parse_expr(f, false);
- f->expr_level = prev_level;
-
- if (allow_token(f, Token_do)) {
- body = convert_stmt_to_body(f, parse_stmt(f));
- } else {
- body = parse_block_stmt(f, false);
- }
-
- return ast_push_context(f, token, expr, body);
- }
- break;
}
if (lhs.count > 1) {
@@ -3548,7 +3514,7 @@ Ast *parse_stmt(AstFile *f) {
case Token_Xor:
case Token_Not:
case Token_And:
- s = parse_simple_stmt(f, StmtAllowFlag_Label|StmtAllowFlag_Context);
+ s = parse_simple_stmt(f, StmtAllowFlag_Label);
expect_semicolon(f, s);
return s;
diff --git a/src/parser.hpp b/src/parser.hpp
index 1020f784f..a9adee8d3 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -11,6 +11,7 @@ enum AddressingMode {
Addressing_NoValue, // no value (void in C)
Addressing_Value, // computed value (rvalue)
Addressing_Immutable, // immutable computed value (const rvalue)
+ Addressing_Context, // context value
Addressing_Variable, // addressable variable (lvalue)
Addressing_Constant, // constant
Addressing_Type, // type
@@ -191,7 +192,6 @@ enum StmtAllowFlag {
StmtAllowFlag_None = 0,
StmtAllowFlag_In = 1<<0,
StmtAllowFlag_Label = 1<<1,
- StmtAllowFlag_Context = 1<<2,
};
#define AST_KINDS \
@@ -343,11 +343,6 @@ AST_KIND(_ComplexStmtBegin, "", bool) \
Token token; \
Array<Ast *> list; \
}) \
- AST_KIND(PushContext, "context <- statement", struct { \
- Token token; \
- Ast *expr; \
- Ast *body; \
- }) \
AST_KIND(_ComplexStmtEnd, "", bool) \
AST_KIND(_StmtEnd, "", bool) \
AST_KIND(_DeclBegin, "", bool) \