diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-01-26 17:39:44 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-01-26 17:39:44 +0000 |
| commit | f47f25f9420e094f9eafe68b0844b860033da7cc (patch) | |
| tree | e47e75c280984db06c03afbf6518921f962b15b2 /src | |
| parent | e85458919ccdd6330a9e090c49343b00468e5b39 (diff) | |
Fix pointer differences (issue #11); remove #dll_import
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.c | 13 | ||||
| -rw-r--r-- | src/check_stmt.c | 8 | ||||
| -rw-r--r-- | src/checker.c | 2 | ||||
| -rw-r--r-- | src/ir.c | 10 | ||||
| -rw-r--r-- | src/ir_print.c | 6 | ||||
| -rw-r--r-- | src/parser.c | 54 |
6 files changed, 59 insertions, 34 deletions
diff --git a/src/check_expr.c b/src/check_expr.c index dd92fc38e..65850a03b 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -3882,6 +3882,19 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint o->value = make_exact_value_from_basic_literal(*bl); case_end; + case_ast_node(bd, BasicDirective, node); + if (str_eq(bd->name, str_lit("file"))) { + o->type = t_untyped_string; + o->value = make_exact_value_string(bd->token.pos.file); + } else if (str_eq(bd->name, str_lit("line"))) { + o->type = t_untyped_integer; + o->value = make_exact_value_integer(bd->token.pos.line); + } else { + GB_PANIC("Unknown basic basic directive"); + } + o->mode = Addressing_Constant; + case_end; + case_ast_node(pl, ProcLit, node); Type *type = check_type(c, pl->type); if (type == NULL || !is_type_proc(type)) { diff --git a/src/check_stmt.c b/src/check_stmt.c index be364559d..fd8e22908 100644 --- a/src/check_stmt.c +++ b/src/check_stmt.c @@ -527,7 +527,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { case_ast_node(rs, ReturnStmt, node); GB_ASSERT(c->proc_stack.count > 0); - if (c->in_defer) { + if (c->context.in_defer) { error(rs->token, "You cannot `return` within a defer statement"); // TODO(bill): Should I break here? break; @@ -1046,10 +1046,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { if (is_ast_node_decl(ds->stmt)) { error(ds->token, "You cannot defer a declaration"); } else { - bool out_in_defer = c->in_defer; - c->in_defer = true; + bool out_in_defer = c->context.in_defer; + c->context.in_defer = true; check_stmt(c, ds->stmt, 0); - c->in_defer = out_in_defer; + c->context.in_defer = out_in_defer; } case_end; diff --git a/src/checker.c b/src/checker.c index 983198f38..c4a5f8cba 100644 --- a/src/checker.c +++ b/src/checker.c @@ -250,6 +250,7 @@ typedef struct CheckerContext { Scope * scope; DeclInfo * decl; u32 stmt_state_flags; + bool in_defer; // TODO(bill): Actually handle correctly } CheckerContext; // NOTE(bill): Symbol tables @@ -288,7 +289,6 @@ typedef struct Checker { CheckerContext context; Array(Type *) proc_stack; - bool in_defer; // TODO(bill): Actually handle correctly bool done_preload; } Checker; @@ -1479,12 +1479,13 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * return ir_emit_ptr_offset(proc, ptr, offset); } else if (is_type_pointer(t_left) && is_type_pointer(t_right)) { GB_ASSERT(is_type_integer(type)); - Type *ptr_type = t_left; irModule *m = proc->module; + Type *ptr_type = base_type(t_left); + GB_ASSERT(!is_type_rawptr(ptr_type)); + irValue *elem_size = ir_make_const_int(m->allocator, type_size_of(m->sizes, m->allocator, ptr_type->Pointer.elem)); irValue *x = ir_emit_conv(proc, left, type); irValue *y = ir_emit_conv(proc, right, type); irValue *diff = ir_emit_arith(proc, op, x, y, type); - irValue *elem_size = ir_make_const_int(m->allocator, type_size_of(m->sizes, m->allocator, ptr_type)); return ir_emit_arith(proc, Token_Quo, diff, elem_size, type); } } @@ -2547,6 +2548,11 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv GB_PANIC("Non-constant basic literal %.*s(%td:%td) - %.*s", LIT(pos.file), pos.line, pos.column, LIT(token_strings[bl->kind])); case_end; + case_ast_node(bd, BasicDirective, expr); + TokenPos pos = bd->token.pos; + GB_PANIC("Non-constant basic literal %.*s(%td:%td) - %.*s", LIT(pos.file), pos.line, pos.column, LIT(bd->name)); + case_end; + case_ast_node(i, Ident, expr); Entity *e = *map_entity_get(&proc->module->info->uses, hash_pointer(expr)); if (e->kind == Entity_Builtin) { diff --git a/src/ir_print.c b/src/ir_print.c index 7a3032367..11d46deb7 100644 --- a/src/ir_print.c +++ b/src/ir_print.c @@ -1235,9 +1235,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { if (proc->body == NULL) { ir_fprintf(f, "declare "); - if (proc->tags & ProcTag_dll_import) { - ir_fprintf(f, "dllimport "); - } + // if (proc->tags & ProcTag_dll_import) { + // ir_fprintf(f, "dllimport "); + // } } else { ir_fprintf(f, "\n"); ir_fprintf(f, "define "); diff --git a/src/parser.c b/src/parser.c index 7549245f4..10f2275f7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -70,7 +70,7 @@ typedef enum ProcTag { ProcTag_link_name = 1<<12, ProcTag_inline = 1<<13, ProcTag_no_inline = 1<<14, - ProcTag_dll_import = 1<<15, + // ProcTag_dll_import = 1<<15, // ProcTag_dll_export = 1<<16, } ProcTag; @@ -113,9 +113,13 @@ AstNodeArray make_ast_node_array(AstFile *f) { #define AST_NODE_KINDS \ - AST_NODE_KIND(BasicLit, "basic literal", Token) \ - AST_NODE_KIND(Ident, "identifier", Token) \ - AST_NODE_KIND(Ellipsis, "ellipsis", struct { \ + AST_NODE_KIND(Ident, "identifier", Token) \ + AST_NODE_KIND(BasicLit, "basic literal", Token) \ + AST_NODE_KIND(BasicDirective, "basic directive", struct { \ + Token token; \ + String name; \ + }) \ + AST_NODE_KIND(Ellipsis, "ellipsis", struct { \ Token token; \ AstNode *expr; \ }) \ @@ -420,10 +424,12 @@ gb_inline bool is_ast_node_when_stmt(AstNode *node) { Token ast_node_token(AstNode *node) { switch (node->kind) { - case AstNode_BasicLit: - return node->BasicLit; case AstNode_Ident: return node->Ident; + case AstNode_BasicLit: + return node->BasicLit; + case AstNode_BasicDirective: + return node->BasicDirective.token; case AstNode_ProcLit: return ast_node_token(node->ProcLit.type); case AstNode_CompoundLit: @@ -741,15 +747,22 @@ AstNode *make_interval_expr(AstFile *f, Token op, AstNode *left, AstNode *right) +AstNode *make_ident(AstFile *f, Token token) { + AstNode *result = make_node(f, AstNode_Ident); + result->Ident = token; + return result; +} + AstNode *make_basic_lit(AstFile *f, Token basic_lit) { AstNode *result = make_node(f, AstNode_BasicLit); result->BasicLit = basic_lit; return result; } -AstNode *make_ident(AstFile *f, Token token) { - AstNode *result = make_node(f, AstNode_Ident); - result->Ident = token; +AstNode *make_basic_directive(AstFile *f, Token token, String name) { + AstNode *result = make_node(f, AstNode_BasicDirective); + result->BasicDirective.token = token; + result->BasicDirective.name = name; return result; } @@ -1543,7 +1556,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n ELSE_IF_ADD_TAG(no_bounds_check) ELSE_IF_ADD_TAG(inline) ELSE_IF_ADD_TAG(no_inline) - ELSE_IF_ADD_TAG(dll_import) + // ELSE_IF_ADD_TAG(dll_import) // ELSE_IF_ADD_TAG(dll_export) else if (str_eq(tag_name, str_lit("cc_odin"))) { if (cc == ProcCC_Invalid) { @@ -1570,7 +1583,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n syntax_error_node(tag_expr, "Multiple calling conventions for procedure type"); } } else { - syntax_error_node(tag_expr, "Unknown procedure tag"); + syntax_error_node(tag_expr, "Unknown procedure tag #%.*s\n", LIT(tag_name)); } #undef ELSE_IF_ADD_TAG @@ -1752,17 +1765,9 @@ AstNode *parse_operand(AstFile *f, bool lhs) { Token token = expect_token(f, Token_Hash); Token name = expect_token(f, Token_Ident); if (str_eq(name.string, str_lit("file"))) { - Token token = name; - token.kind = Token_String; - token.string = token.pos.file; - return make_basic_lit(f, token); + return make_basic_directive(f, token, name.string); } else if (str_eq(name.string, str_lit("line"))) { - Token token = name; - token.kind = Token_Integer; - char *str = gb_alloc_array(gb_arena_allocator(&f->arena), char, 20); - gb_i64_to_str(token.pos.line, str, 10); - token.string = make_string_c(str); - return make_basic_lit(f, token); + return make_basic_directive(f, token, name.string); } else if (str_eq(name.string, str_lit("run"))) { AstNode *expr = parse_expr(f, false); operand = make_run_expr(f, token, name, expr); @@ -3077,20 +3082,21 @@ AstNode *parse_defer_stmt(AstFile *f) { } Token token = expect_token(f, Token_defer); - AstNode *statement = parse_stmt(f); - switch (statement->kind) { + AstNode *stmt = parse_stmt(f); + switch (stmt->kind) { case AstNode_EmptyStmt: syntax_error(token, "Empty statement after defer (e.g. `;`)"); break; case AstNode_DeferStmt: syntax_error(token, "You cannot defer a defer statement"); + stmt = stmt->DeferStmt.stmt; break; case AstNode_ReturnStmt: syntax_error(token, "You cannot a return statement"); break; } - return make_defer_stmt(f, token, statement); + return make_defer_stmt(f, token, stmt); } AstNode *parse_asm_stmt(AstFile *f) { |