diff options
| author | gingerBill <bill@gingerbill.org> | 2017-10-29 11:35:21 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2017-10-29 11:35:21 +0000 |
| commit | a43b89f36e988df8268ee92ea54017806b3226bb (patch) | |
| tree | b9db9300453604a565ee3ac7e56c9fe6ad17be08 /src | |
| parent | 0ed34af19d20aa5ae13c2147bd0f767d68d2e965 (diff) | |
#alias type declarations; core library additions; `_global` import name for the global scope
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_decl.cpp | 36 | ||||
| -rw-r--r-- | src/check_expr.cpp | 19 | ||||
| -rw-r--r-- | src/check_type.cpp | 6 | ||||
| -rw-r--r-- | src/checker.cpp | 12 | ||||
| -rw-r--r-- | src/entity.cpp | 1 | ||||
| -rw-r--r-- | src/gb/gb.h | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 10 | ||||
| -rw-r--r-- | src/ir_print.cpp | 3 | ||||
| -rw-r--r-- | src/parser.cpp | 21 |
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) { |