mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 01:21:38 -07:00
Remove using in stuff
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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; \
|
||||
|
||||
Reference in New Issue
Block a user