mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 08:08:50 +00:00
Remove using in stuff
This commit is contained in:
@@ -70,7 +70,7 @@ main :: proc() {
|
|||||||
|
|
||||||
- Windows
|
- Windows
|
||||||
* x86-64
|
* 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`
|
* [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
|
* Requires MSVC's link.exe as the linker
|
||||||
* run `vcvarsall.bat` to setup the path
|
* run `vcvarsall.bat` to setup the path
|
||||||
|
|||||||
@@ -1601,153 +1601,6 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
case_end;
|
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);
|
case_ast_node(pa, PushContext, node);
|
||||||
Operand op = {};
|
Operand op = {};
|
||||||
check_expr(ctx, &op, pa->expr);
|
check_expr(ctx, &op, pa->expr);
|
||||||
|
|||||||
+26
-60
@@ -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;
|
||||||
String import_name = id->import_name.string;
|
if (import_name.len == 0) {
|
||||||
if (import_name.len == 0) {
|
import_name = scope->package->name;
|
||||||
import_name = scope->package->name;
|
}
|
||||||
}
|
if (is_blank_ident(import_name)) {
|
||||||
if (is_blank_ident(import_name)) {
|
if (id->is_using) {
|
||||||
if (id->is_using) {
|
// TODO(bill): Should this be a warning?
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
GB_ASSERT(id->import_name.pos.line != 0);
|
error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string));
|
||||||
id->import_name.string = import_name;
|
}
|
||||||
Entity *e = alloc_entity_import_name(parent_scope, id->import_name, t_invalid,
|
} else {
|
||||||
id->fullpath, id->import_name.string,
|
GB_ASSERT(id->import_name.pos.line != 0);
|
||||||
scope);
|
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);
|
add_entity(ctx->checker, parent_scope, nullptr, e);
|
||||||
if (id->is_using) {
|
if (id->is_using) {
|
||||||
add_entity_use(ctx, nullptr, e);
|
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
|
// 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) {
|
bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
|
||||||
AstNode *node = id->using_in_list[list_index];
|
if (is_entity_exported(e) && !implicit_is_found) {
|
||||||
ast_node(ident, Ident, node);
|
Entity *prev = scope_lookup(parent_scope, e->token.string);
|
||||||
String name = ident->token.string;
|
bool ok = add_entity(ctx->checker, parent_scope, e->identifier, e);
|
||||||
|
if (ok) ptr_set_add(&parent_scope->implicit, e);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-42
@@ -53,7 +53,6 @@ Token ast_node_token(AstNode *node) {
|
|||||||
case AstNode_DeferStmt: return node->DeferStmt.token;
|
case AstNode_DeferStmt: return node->DeferStmt.token;
|
||||||
case AstNode_BranchStmt: return node->BranchStmt.token;
|
case AstNode_BranchStmt: return node->BranchStmt.token;
|
||||||
case AstNode_UsingStmt: return node->UsingStmt.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_PushContext: return node->PushContext.token;
|
||||||
|
|
||||||
case AstNode_BadDecl: return node->BadDecl.begin;
|
case AstNode_BadDecl: return node->BadDecl.begin;
|
||||||
@@ -275,10 +274,6 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
|||||||
case AstNode_UsingStmt:
|
case AstNode_UsingStmt:
|
||||||
n->UsingStmt.list = clone_ast_node_array(a, n->UsingStmt.list);
|
n->UsingStmt.list = clone_ast_node_array(a, n->UsingStmt.list);
|
||||||
break;
|
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:
|
case AstNode_PushContext:
|
||||||
n->PushContext.expr = clone_ast_node(a, n->PushContext.expr);
|
n->PushContext.expr = clone_ast_node(a, n->PushContext.expr);
|
||||||
n->PushContext.body = clone_ast_node(a, n->PushContext.body);
|
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;
|
result->UsingStmt.list = list;
|
||||||
return result;
|
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 *ast_push_context(AstFile *f, Token token, AstNode *expr, AstNode *body) {
|
||||||
AstNode *result = alloc_ast_node(f, AstNode_PushContext);
|
AstNode *result = alloc_ast_node(f, AstNode_PushContext);
|
||||||
@@ -3451,7 +3437,6 @@ AstNode *parse_defer_stmt(AstFile *f) {
|
|||||||
enum ImportDeclKind {
|
enum ImportDeclKind {
|
||||||
ImportDecl_Standard,
|
ImportDecl_Standard,
|
||||||
ImportDecl_Using,
|
ImportDecl_Using,
|
||||||
ImportDecl_UsingIn,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AstNode *parse_import_decl(AstFile *f, ImportDeclKind kind) {
|
AstNode *parse_import_decl(AstFile *f, ImportDeclKind kind) {
|
||||||
@@ -3460,19 +3445,17 @@ AstNode *parse_import_decl(AstFile *f, ImportDeclKind kind) {
|
|||||||
Token import_name = {};
|
Token import_name = {};
|
||||||
bool is_using = kind != ImportDecl_Standard;
|
bool is_using = kind != ImportDecl_Standard;
|
||||||
|
|
||||||
if (kind != ImportDecl_UsingIn) {
|
switch (f->curr_token.kind) {
|
||||||
switch (f->curr_token.kind) {
|
case Token_Ident:
|
||||||
case Token_Ident:
|
import_name = advance_token(f);
|
||||||
import_name = advance_token(f);
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
import_name.pos = f->curr_token.pos;
|
||||||
import_name.pos = f->curr_token.pos;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_using && is_blank_ident(import_name)) {
|
if (!is_using && is_blank_ident(import_name)) {
|
||||||
syntax_error(import_name, "Illegal import name: '_'");
|
syntax_error(import_name, "Illegal import name: '_'");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Token file_path = expect_token_after(f, Token_String, "import");
|
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);
|
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) {
|
if (f->curr_token.kind != Token_Colon) {
|
||||||
expect_semicolon(f, list[list.count-1]);
|
expect_semicolon(f, list[list.count-1]);
|
||||||
return ast_using_stmt(f, token, list);
|
return ast_using_stmt(f, token, list);
|
||||||
|
|||||||
@@ -172,11 +172,6 @@ enum StmtAllowFlag {
|
|||||||
StmtAllowFlag_Label = 1<<1,
|
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 \
|
#define AST_NODE_KINDS \
|
||||||
AST_NODE_KIND(Ident, "identifier", struct { \
|
AST_NODE_KIND(Ident, "identifier", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
@@ -326,12 +321,6 @@ AST_NODE_KIND(_ComplexStmtBegin, "", struct {}) \
|
|||||||
Token token; \
|
Token token; \
|
||||||
Array<AstNode *> list; \
|
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 { \
|
AST_NODE_KIND(PushContext, "context <- statement", struct { \
|
||||||
Token token; \
|
Token token; \
|
||||||
AstNode *expr; \
|
AstNode *expr; \
|
||||||
@@ -377,7 +366,6 @@ AST_NODE_KIND(_DeclBegin, "", struct {}) \
|
|||||||
Token relpath; \
|
Token relpath; \
|
||||||
String fullpath; \
|
String fullpath; \
|
||||||
Token import_name; \
|
Token import_name; \
|
||||||
Array<AstNode *> using_in_list; \
|
|
||||||
CommentGroup docs; \
|
CommentGroup docs; \
|
||||||
CommentGroup comment; \
|
CommentGroup comment; \
|
||||||
bool is_using; \
|
bool is_using; \
|
||||||
|
|||||||
Reference in New Issue
Block a user