Remove using in stuff

This commit is contained in:
gingerBill
2018-06-11 17:34:57 +01:00
parent 268491b224
commit 0a99595efe
5 changed files with 37 additions and 262 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ main :: proc() {
- Windows
* x86-64
* MSVC 2015 installed (C++11 support)
* MSVC 2010 installed (C++11 support)
* [LLVM binaries](https://github.com/gingerBill/Odin/releases/tag/llvm-4.0-windows) for `opt.exe` and `llc.exe`
* Requires MSVC's link.exe as the linker
* run `vcvarsall.bat` to setup the path
-147
View File
@@ -1601,153 +1601,6 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
}
case_end;
case_ast_node(uis, UsingInStmt, node);
if (uis->list.count == 0) {
error(node, "Empty 'using' list");
return;
}
AstNode *expr = uis->expr;
Entity *e = nullptr;
Operand o = {};
if (expr->kind == AstNode_Ident) {
e = check_ident(ctx, &o, expr, nullptr, nullptr, true);
} else if (expr->kind == AstNode_SelectorExpr) {
e = check_selector(ctx, &o, expr, nullptr);
}
if (e == nullptr) {
error(expr, "'using' applied to an unknown entity");
return;
}
add_entity_use(ctx, expr, e);
switch (e->kind) {
case Entity_TypeName: {
Type *t = base_type(e->type);
if (t->kind == Type_Enum) {
GB_ASSERT(t->Enum.scope != nullptr);
for_array(list_index, uis->list) {
AstNode *node = uis->list[list_index];
ast_node(ident, Ident, node);
String name = ident->token.string;
Entity *f = scope_lookup(t->Enum.scope, name);
if (f == nullptr || !is_entity_exported(f)) {
if (is_blank_ident(name)) {
error(node, "'_' cannot be used as a value");
} else {
error(node, "Undeclared name in this enumeration: '%.*s'", LIT(name));
}
continue;
}
add_entity_use(ctx, node, f);
add_entity(ctx->checker, ctx->scope, node, f);
}
} else {
error(node, "'using' can be only applied to enum type entities");
}
break;
}
case Entity_ImportName: {
Scope *scope = e->ImportName.scope;
for_array(list_index, uis->list) {
AstNode *node = uis->list[list_index];
ast_node(ident, Ident, node);
String name = ident->token.string;
Entity *f = scope_lookup(scope, name);
if (f == nullptr) {
if (is_blank_ident(name)) {
error(node, "'_' cannot be used as a value");
} else {
error(node, "Undeclared name in this import name: '%.*s'", LIT(name));
}
continue;
}
bool implicit_is_found = ptr_set_exists(&scope->implicit, f);
if (is_entity_exported(f) && !implicit_is_found) {
add_entity_use(ctx, node, f);
add_entity(ctx->checker, ctx->scope, node, f);
} else {
error(node, "'%.*s' is exported from '%.*s'", LIT(f->token.string), LIT(e->token.string));
continue;
}
}
break;
}
case Entity_Variable: {
Type *t = base_type(type_deref(e->type));
if (t->kind == Type_Struct) {
// TODO(bill): Make it work for unions too
Scope *found = scope_of_node(t->Struct.node);
for_array(list_index, uis->list) {
AstNode *node = uis->list[list_index];
ast_node(ident, Ident, node);
String name = ident->token.string;
Entity *f = scope_lookup(found, name);
if (f == nullptr || f->kind != Entity_Variable) {
if (is_blank_ident(name)) {
error(node, "'_' cannot be used as a value");
} else {
error(node, "Undeclared name in this variable: '%.*s'", LIT(name));
}
continue;
}
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type);
uvar->using_expr = expr;
Entity *prev = scope_insert(ctx->scope, uvar);
if (prev != nullptr) {
gbString expr_str = expr_to_string(expr);
error(node, "Namespace collision while using '%s' of: '%.*s'", expr_str, LIT(prev->token.string));
gb_string_free(expr_str);
continue;
}
}
} else {
error(node, "'using' can only be applied to variables of type `struct`");
return;
}
break;
}
case Entity_Constant:
error(node, "'using' cannot be applied to a constant");
break;
case Entity_Procedure:
case Entity_ProcGroup:
case Entity_Builtin:
error(node, "'using' cannot be applied to a procedure");
break;
case Entity_Nil:
error(node, "'using' cannot be applied to 'nil'");
break;
case Entity_Label:
error(node, "'using' cannot be applied to a label");
break;
case Entity_Invalid:
error(node, "'using' cannot be applied to an invalid entity");
break;
default:
GB_PANIC("TODO(bill): 'using' other expressions?");
}
case_end;
case_ast_node(pa, PushContext, node);
Operand op = {};
check_expr(ctx, &op, pa->expr);
+26 -60
View File
@@ -2551,28 +2551,26 @@ void check_add_import_decl(CheckerContext *ctx, AstNodeImportDecl *id) {
}
if (id->using_in_list.count == 0) {
String import_name = id->import_name.string;
if (import_name.len == 0) {
import_name = scope->package->name;
}
if (is_blank_ident(import_name)) {
if (id->is_using) {
// TODO(bill): Should this be a warning?
} else {
error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string));
}
String import_name = id->import_name.string;
if (import_name.len == 0) {
import_name = scope->package->name;
}
if (is_blank_ident(import_name)) {
if (id->is_using) {
// TODO(bill): Should this be a warning?
} else {
GB_ASSERT(id->import_name.pos.line != 0);
id->import_name.string = import_name;
Entity *e = alloc_entity_import_name(parent_scope, id->import_name, t_invalid,
id->fullpath, id->import_name.string,
scope);
error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string));
}
} else {
GB_ASSERT(id->import_name.pos.line != 0);
id->import_name.string = import_name;
Entity *e = alloc_entity_import_name(parent_scope, id->import_name, t_invalid,
id->fullpath, id->import_name.string,
scope);
add_entity(ctx->checker, parent_scope, nullptr, e);
if (id->is_using) {
add_entity_use(ctx, nullptr, e);
}
add_entity(ctx->checker, parent_scope, nullptr, e);
if (id->is_using) {
add_entity_use(ctx, nullptr, e);
}
}
@@ -2583,47 +2581,15 @@ void check_add_import_decl(CheckerContext *ctx, AstNodeImportDecl *id) {
}
// NOTE(bill): Add imported entities to this file's scope
if (id->using_in_list.count > 0) {
for_array(elem_index, scope->elements.entries) {
Entity *e = scope->elements.entries[elem_index].value;
if (e->scope == parent_scope) continue;
for_array(list_index, id->using_in_list) {
AstNode *node = id->using_in_list[list_index];
ast_node(ident, Ident, node);
String name = ident->token.string;
Entity *e = scope_lookup(scope, name);
if (e == nullptr) {
if (is_blank_ident(name)) {
error(node, "'_' cannot be used as a value");
} else {
error(node, "Undeclared name in this importation: '%.*s'", LIT(name));
}
continue;
}
if (e->scope == parent_scope) {
continue;
}
bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
if (is_entity_exported(e) && !implicit_is_found) {
add_entity_use(ctx, node, e);
bool ok = add_entity(ctx->checker, parent_scope, e->identifier, e);
if (ok) ptr_set_add(&parent_scope->implicit, e);
} else {
error(node, "'%.*s' is exported from this scope", LIT(name));
continue;
}
}
} else {
for_array(elem_index, scope->elements.entries) {
Entity *e = scope->elements.entries[elem_index].value;
if (e->scope == parent_scope) continue;
bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
if (is_entity_exported(e) && !implicit_is_found) {
Entity *prev = scope_lookup(parent_scope, e->token.string);
bool ok = add_entity(ctx->checker, parent_scope, e->identifier, e);
if (ok) ptr_set_add(&parent_scope->implicit, e);
}
bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
if (is_entity_exported(e) && !implicit_is_found) {
Entity *prev = scope_lookup(parent_scope, e->token.string);
bool ok = add_entity(ctx->checker, parent_scope, e->identifier, e);
if (ok) ptr_set_add(&parent_scope->implicit, e);
}
}
}
+10 -42
View File
@@ -53,7 +53,6 @@ Token ast_node_token(AstNode *node) {
case AstNode_DeferStmt: return node->DeferStmt.token;
case AstNode_BranchStmt: return node->BranchStmt.token;
case AstNode_UsingStmt: return node->UsingStmt.token;
case AstNode_UsingInStmt: return node->UsingInStmt.using_token;
case AstNode_PushContext: return node->PushContext.token;
case AstNode_BadDecl: return node->BadDecl.begin;
@@ -275,10 +274,6 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
case AstNode_UsingStmt:
n->UsingStmt.list = clone_ast_node_array(a, n->UsingStmt.list);
break;
case AstNode_UsingInStmt:
n->UsingInStmt.list = clone_ast_node_array(a, n->UsingInStmt.list);
n->UsingInStmt.expr = clone_ast_node(a, n->UsingInStmt.expr);
break;
case AstNode_PushContext:
n->PushContext.expr = clone_ast_node(a, n->PushContext.expr);
n->PushContext.body = clone_ast_node(a, n->PushContext.body);
@@ -796,15 +791,6 @@ AstNode *ast_using_stmt(AstFile *f, Token token, Array<AstNode *> list) {
result->UsingStmt.list = list;
return result;
}
AstNode *ast_using_in_stmt(AstFile *f, Token using_token, Array<AstNode *> list, Token in_token, AstNode *expr) {
AstNode *result = alloc_ast_node(f, AstNode_UsingInStmt);
result->UsingInStmt.using_token = using_token;
result->UsingInStmt.list = list;
result->UsingInStmt.in_token = in_token;
result->UsingInStmt.expr = expr;
return result;
}
AstNode *ast_push_context(AstFile *f, Token token, AstNode *expr, AstNode *body) {
AstNode *result = alloc_ast_node(f, AstNode_PushContext);
@@ -3451,7 +3437,6 @@ AstNode *parse_defer_stmt(AstFile *f) {
enum ImportDeclKind {
ImportDecl_Standard,
ImportDecl_Using,
ImportDecl_UsingIn,
};
AstNode *parse_import_decl(AstFile *f, ImportDeclKind kind) {
@@ -3460,19 +3445,17 @@ AstNode *parse_import_decl(AstFile *f, ImportDeclKind kind) {
Token import_name = {};
bool is_using = kind != ImportDecl_Standard;
if (kind != ImportDecl_UsingIn) {
switch (f->curr_token.kind) {
case Token_Ident:
import_name = advance_token(f);
break;
default:
import_name.pos = f->curr_token.pos;
break;
}
switch (f->curr_token.kind) {
case Token_Ident:
import_name = advance_token(f);
break;
default:
import_name.pos = f->curr_token.pos;
break;
}
if (!is_using && is_blank_ident(import_name)) {
syntax_error(import_name, "Illegal import name: '_'");
}
if (!is_using && is_blank_ident(import_name)) {
syntax_error(import_name, "Illegal import name: '_'");
}
Token file_path = expect_token_after(f, Token_String, "import");
@@ -3637,21 +3620,6 @@ AstNode *parse_stmt(AstFile *f) {
return ast_bad_stmt(f, token, f->curr_token);
}
if (f->curr_token.kind == Token_in) {
Token in_token = expect_token(f, Token_in);
if (f->curr_token.kind == Token_import) {
AstNode *import_decl = parse_import_decl(f, ImportDecl_UsingIn);
if (import_decl->kind == AstNode_ImportDecl) {
import_decl->ImportDecl.using_in_list = list;
}
return import_decl;
}
AstNode *expr = parse_expr(f, true);
expect_semicolon(f, expr);
return ast_using_in_stmt(f, token, list, in_token, expr);
}
if (f->curr_token.kind != Token_Colon) {
expect_semicolon(f, list[list.count-1]);
return ast_using_stmt(f, token, list);
-12
View File
@@ -172,11 +172,6 @@ enum StmtAllowFlag {
StmtAllowFlag_Label = 1<<1,
};
// NOTE(bill): This massive define is so it is possible to create a discriminated union (and extra debug info)
// for the AstNode. I personally prefer discriminated unions over subtype polymorphism as I can preallocate
// all the nodes and even memcpy in a different kind of node
#define AST_NODE_KINDS \
AST_NODE_KIND(Ident, "identifier", struct { \
Token token; \
@@ -326,12 +321,6 @@ AST_NODE_KIND(_ComplexStmtBegin, "", struct {}) \
Token token; \
Array<AstNode *> list; \
}) \
AST_NODE_KIND(UsingInStmt, "using in statement", struct { \
Token using_token; \
Array<AstNode *> list; \
Token in_token; \
AstNode *expr; \
}) \
AST_NODE_KIND(PushContext, "context <- statement", struct { \
Token token; \
AstNode *expr; \
@@ -377,7 +366,6 @@ AST_NODE_KIND(_DeclBegin, "", struct {}) \
Token relpath; \
String fullpath; \
Token import_name; \
Array<AstNode *> using_in_list; \
CommentGroup docs; \
CommentGroup comment; \
bool is_using; \