Implement Explicit context creation #639

This commit is contained in:
gingerBill
2020-05-14 00:13:26 +01:00
parent af1d4d6e72
commit f661d34049
6 changed files with 39 additions and 11 deletions

View File

@@ -125,7 +125,7 @@ bprintf :: proc(buf: []byte, fmt: string, args: ..any) -> string {
}
assertf :: proc "contextless" (condition: bool, fmt: string, args: ..any, loc := #caller_location) -> bool {
assertf :: proc(condition: bool, fmt: string, args: ..any, loc := #caller_location) -> bool {
if !condition {
p := context.assertion_failure_proc;
if p == nil {
@@ -137,7 +137,7 @@ assertf :: proc "contextless" (condition: bool, fmt: string, args: ..any, loc :=
return condition;
}
panicf :: proc "contextless" (fmt: string, args: ..any, loc := #caller_location) {
panicf :: proc(fmt: string, args: ..any, loc := #caller_location) {
p := context.assertion_failure_proc;
if p == nil {
p = runtime.default_assertion_failure_proc;

View File

@@ -440,6 +440,12 @@ default_logger :: proc() -> Logger {
}
default_context :: proc "contextless" () -> Context {
c: Context;
__init_context(&c);
return c;
}
@private
__init_context_from_ptr :: proc "contextless" (c: ^Context, other: ^Context) {
if c == nil do return;

View File

@@ -7724,6 +7724,15 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
return kind;
}
if (unparen_expr(c->assignment_lhs_hint) == node) {
c->scope->flags |= ScopeFlag_ContextDefined;
}
if ((c->scope->flags & ScopeFlag_ContextDefined) == 0) {
error(node, "'context' has not been defined within this scope");
// Continue with value
}
init_core_context(c->checker);
o->mode = Addressing_Context;
o->type = t_context;

View File

@@ -2501,6 +2501,19 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
c->curr_proc_sig = type;
c->in_proc_sig = true;
ProcCallingConvention cc = pt->calling_convention;
if (cc == ProcCC_ForeignBlockDefault) {
cc = ProcCC_CDecl;
if (c->foreign_context.default_cc > 0) {
cc = c->foreign_context.default_cc;
}
}
GB_ASSERT(cc > 0);
if (cc == ProcCC_Odin) {
c->scope->flags |= ScopeFlag_ContextDefined;
}
bool variadic = false;
isize variadic_index = -1;
bool success = true;
@@ -2534,14 +2547,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
}
ProcCallingConvention cc = pt->calling_convention;
if (cc == ProcCC_ForeignBlockDefault) {
cc = ProcCC_CDecl;
if (c->foreign_context.default_cc > 0) {
cc = c->foreign_context.default_cc;
}
}
GB_ASSERT(cc > 0);
bool optional_ok = (pt->tags & ProcTag_optional_ok) != 0;
if (optional_ok) {

View File

@@ -231,6 +231,11 @@ Scope *create_scope(Scope *parent, gbAllocator allocator, isize init_elements_ca
if (parent != nullptr && parent != builtin_pkg->scope) {
DLIST_APPEND(parent->first_child, parent->last_child, s);
}
if (parent != nullptr && parent->flags & ScopeFlag_ContextDefined) {
s->flags |= ScopeFlag_ContextDefined;
}
return s;
}

View File

@@ -158,7 +158,7 @@ struct ProcInfo {
enum ScopeFlag {
enum ScopeFlag : i32 {
ScopeFlag_Pkg = 1<<1,
ScopeFlag_Global = 1<<2,
ScopeFlag_File = 1<<3,
@@ -167,6 +167,8 @@ enum ScopeFlag {
ScopeFlag_Type = 1<<6,
ScopeFlag_HasBeenImported = 1<<10, // This is only applicable to file scopes
ScopeFlag_ContextDefined = 1<<16,
};
struct Scope {