aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2017-10-29 11:35:21 +0000
committergingerBill <bill@gingerbill.org>2017-10-29 11:35:21 +0000
commita43b89f36e988df8268ee92ea54017806b3226bb (patch)
treeb9db9300453604a565ee3ac7e56c9fe6ad17be08 /src
parent0ed34af19d20aa5ae13c2147bd0f767d68d2e965 (diff)
#alias type declarations; core library additions; `_global` import name for the global scope
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp36
-rw-r--r--src/check_expr.cpp19
-rw-r--r--src/check_type.cpp6
-rw-r--r--src/checker.cpp12
-rw-r--r--src/entity.cpp1
-rw-r--r--src/gb/gb.h2
-rw-r--r--src/ir.cpp10
-rw-r--r--src/ir_print.cpp3
-rw-r--r--src/parser.cpp21
9 files changed, 95 insertions, 15 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 121c10774..0baf43349 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -170,8 +170,26 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
e->Constant.value = operand->value;
}
-void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) {
+AstNode *remove_type_alias(AstNode *node) {
+ for (;;) {
+ if (node == nullptr) {
+ return nullptr;
+ }
+ if (node->kind == AstNode_ParenExpr) {
+ node = node->ParenExpr.expr;
+ } else if (node->kind == AstNode_AliasType) {
+ node = node->AliasType.type;
+ } else {
+ return node;
+ }
+ }
+}
+
+void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, bool is_alias) {
GB_ASSERT(e->type == nullptr);
+ AstNode *te = remove_type_alias(type_expr);
+
+ e->type = t_invalid;
String name = e->token.string;
Type *named = make_type_named(c->allocator, name, nullptr, e);
named->Named.type_name = e;
@@ -180,12 +198,14 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def) {
}
e->type = named;
- // gb_printf_err("%.*s %p\n", LIT(e->token.string), e);
-
- Type *bt = check_type(c, type_expr, named);
+ Type *bt = check_type(c, te, named);
named->Named.base = base_type(bt);
- if (named->Named.base == t_invalid) {
- // gb_printf("check_type_decl: %s\n", type_to_string(named));
+ if (is_alias) {
+ if (is_type_named(bt)) {
+ e->type = bt;
+ } else {
+ warning(type_expr, "Type declaration will not be an alias type");
+ }
}
}
@@ -232,7 +252,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
error(e->token, "A type declaration cannot have an type parameter");
}
d->type_expr = d->init_expr;
- check_type_decl(c, e, d->type_expr, named_type);
+ check_type_decl(c, e, d->type_expr, named_type, false);
return;
}
@@ -673,7 +693,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
check_const_decl(c, e, d->type_expr, d->init_expr, named_type);
break;
case Entity_TypeName:
- check_type_decl(c, e, d->type_expr, named_type);
+ check_type_decl(c, e, d->type_expr, named_type, d->type_expr->kind == AstNode_AliasType);
break;
case Entity_Procedure:
check_proc_decl(c, e, d);
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index cdce6297a..2f3bc4fdf 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -57,7 +57,7 @@ ExprKind check_expr_base (Checker *c, Operand *operand, AstNode *
void check_expr_with_type_hint (Checker *c, Operand *o, AstNode *e, Type *t);
Type * check_type (Checker *c, AstNode *expression, Type *named_type = nullptr);
Type * make_optional_ok_type(gbAllocator a, Type *value);
-void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def);
+void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def, bool alias);
Entity * check_selector (Checker *c, Operand *operand, AstNode *node, Type *type_hint);
Entity * check_ident (Checker *c, Operand *o, AstNode *n, Type *named_type, Type *type_hint, bool allow_import_name);
Entity * find_polymorphic_struct_entity(Checker *c, Type *original_type, isize param_count, Array<Operand> ordered_operands);
@@ -1421,6 +1421,14 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
if (is_type_unsigned(type)) {
precision = cast(i32)(8 * type_size_of(c->allocator, type));
}
+ if (op.kind == Token_Xor && is_type_untyped(type)) {
+ gbString err_str = expr_to_string(node);
+ error(op, "Bitwise not cannot be applied to untyped constants `%s`", err_str);
+ gb_string_free(err_str);
+ o->mode = Addressing_Invalid;
+ return;
+ }
+
o->value = exact_unary_operator_value(op.kind, o->value, precision);
if (is_type_typed(type)) {
@@ -5353,7 +5361,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
for_array(i, cl->elems) {
AstNode *elem = cl->elems[i];
if (elem->kind != AstNode_FieldValue) {
- error(elem, "Mixture of `field = value` and value elements in a structure literal is not allowed");
+ error(elem, "Mixture of `field = value` and value elements in a literal is not allowed");
continue;
}
ast_node(fv, FieldValue, elem);
@@ -5416,7 +5424,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
for_array(index, cl->elems) {
AstNode *elem = cl->elems[index];
if (elem->kind == AstNode_FieldValue) {
- error(elem, "Mixture of `field = value` and value elements in a structure literal is not allowed");
+ error(elem, "Mixture of `field = value` and value elements in a literal is not allowed");
continue;
}
if (index >= field_count) {
@@ -6316,6 +6324,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = write_expr_to_string(str, ht->type);
case_end;
+ case_ast_node(ht, AliasType, node);
+ str = gb_string_appendc(str, "#alias ");
+ str = write_expr_to_string(str, ht->type);
+ case_end;
+
case_ast_node(pt, PolyType, node);
str = gb_string_append_rune(str, '$');
diff --git a/src/check_type.cpp b/src/check_type.cpp
index e6cddf62e..95b876ef8 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -2131,6 +2131,12 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
return check_type_internal(c, ht->type, type, named_type);
case_end;
+ case_ast_node(at, AliasType, e);
+ error(e, "Invalid use of `#alias`");
+ // NOTE(bill): Treat it as a HelperType to remove errors
+ return check_type_internal(c, at->type, type, named_type);
+ case_end;
+
case_ast_node(pt, PolyType, e);
AstNode *ident = pt->type;
if (ident->kind != AstNode_Ident) {
diff --git a/src/checker.cpp b/src/checker.cpp
index f78249b2f..d6bbf754d 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -1716,7 +1716,19 @@ void init_preload(Checker *c) {
t_map_header = e->type;
}
+
+ {
+ String _global = str_lit("_global");
+
+ Entity *e = make_entity_import_name(c->allocator, c->global_scope->parent, make_token_ident(_global), t_invalid,
+ str_lit(""), _global,
+ c->global_scope);
+
+ add_entity(c, c->global_scope, nullptr, e);
+ }
+
c->done_preload = true;
+
}
diff --git a/src/entity.cpp b/src/entity.cpp
index e03adeab8..de0922650 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -156,6 +156,7 @@ bool is_entity_exported(Entity *e) {
return name[0] != '_';
}
+
gb_global u64 global_entity_id = 0;
Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
diff --git a/src/gb/gb.h b/src/gb/gb.h
index 48da7ae41..dfd701b8d 100644
--- a/src/gb/gb.h
+++ b/src/gb/gb.h
@@ -7954,7 +7954,7 @@ gbFileTime gb_file_last_write_time(char const *filepath) {
time_t result = 0;
struct stat file_stat;
- if (stat(filepath, &file_stat)) {
+ if (stat(filepath, &file_stat) == 0) {
result = file_stat.st_mtime;
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 853960d08..9b018a2ea 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -119,6 +119,7 @@ struct irProcedure {
u64 tags;
bool is_foreign;
bool is_export;
+ bool is_entry_point;
irValue * return_ptr;
Array<irValue *> params;
@@ -3743,6 +3744,12 @@ void ir_check_type_and_gen_for_proc_lit(irModule *m, String prefix_name, Type *t
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
if (e->type == nullptr) return;
+ if (e->kind == Entity_TypeName && e->type->kind == Type_Named) {
+ if (e != e->type->Named.type_name) {
+ // NOTE(bill): Is alias
+ return;
+ }
+ }
Type *bt = base_type(e->type);
@@ -8267,7 +8274,6 @@ void ir_gen_tree(irGen *s) {
switch (e->kind) {
case Entity_TypeName:
- GB_ASSERT(e->type->kind == Type_Named);
ir_gen_global_type_name(m, e, name);
break;
@@ -8374,6 +8380,7 @@ void ir_gen_tree(irGen *s) {
irProcedure *proc = &p->Proc;
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
+ proc->is_entry_point = true;
e->Procedure.link_name = name;
ir_begin_procedure_body(proc);
@@ -8444,6 +8451,7 @@ void ir_gen_tree(irGen *s) {
irProcedure *proc = &p->Proc;
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
+ proc->is_entry_point = true;
e->Procedure.link_name = name;
ir_begin_procedure_body(proc);
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index f60764b94..edf2665c7 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -1678,6 +1678,9 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
ir_write_string(f, "dllexport ");
}
}
+ // if (!proc->is_export && !proc->is_foreign && !proc->is_entry_point) {
+ // ir_write_string(f, "internal ");
+ // }
}
TypeProc *proc_type = &proc->type->Proc;
diff --git a/src/parser.cpp b/src/parser.cpp
index 56e768bc3..94a4e7585 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -407,6 +407,10 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
Token token; \
AstNode *type; \
}) \
+ AST_NODE_KIND(AliasType, "alias type", struct { \
+ Token token; \
+ AstNode *type; \
+ }) \
AST_NODE_KIND(PolyType, "polymorphic type", struct { \
Token token; \
AstNode *type; \
@@ -611,6 +615,7 @@ Token ast_node_token(AstNode *node) {
case AstNode_TypeType: return node->TypeType.token;
case AstNode_HelperType: return node->HelperType.token;
+ case AstNode_AliasType: return node->AliasType.token;
case AstNode_PolyType: return node->PolyType.token;
case AstNode_ProcType: return node->ProcType.token;
case AstNode_PointerType: return node->PointerType.token;
@@ -857,6 +862,9 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
case AstNode_HelperType:
n->HelperType.type = clone_ast_node(a, n->HelperType.type);
break;
+ case AstNode_AliasType:
+ n->AliasType.type = clone_ast_node(a, n->AliasType.type);
+ break;
case AstNode_ProcType:
n->ProcType.params = clone_ast_node(a, n->ProcType.params);
n->ProcType.results = clone_ast_node(a, n->ProcType.results);
@@ -1411,6 +1419,13 @@ AstNode *ast_helper_type(AstFile *f, Token token, AstNode *type) {
return result;
}
+AstNode *ast_alias_type(AstFile *f, Token token, AstNode *type) {
+ AstNode *result = make_ast_node(f, AstNode_AliasType);
+ result->AliasType.token = token;
+ result->AliasType.type = type;
+ return result;
+}
+
AstNode *ast_poly_type(AstFile *f, Token token, AstNode *type, AstNode *specialization) {
AstNode *result = make_ast_node(f, AstNode_PolyType);
@@ -2256,8 +2271,10 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
if (allow_token(f, Token_type)) {
return ast_helper_type(f, token, parse_type(f));
}
- Token name = expect_token(f, Token_Ident);
- if (name.string == "run") {
+ Token name = expect_token(f, Token_Ident);
+ if (name.string == "alias") {
+ return ast_alias_type(f, token, parse_type(f));
+ } else if (name.string == "run") {
AstNode *expr = parse_expr(f, false);
operand = ast_run_expr(f, token, name, expr);
if (unparen_expr(expr)->kind != AstNode_CallExpr) {