aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-01-26 17:39:44 +0000
committerGinger Bill <bill@gingerbill.org>2017-01-26 17:39:44 +0000
commitf47f25f9420e094f9eafe68b0844b860033da7cc (patch)
treee47e75c280984db06c03afbf6518921f962b15b2 /src
parente85458919ccdd6330a9e090c49343b00468e5b39 (diff)
Fix pointer differences (issue #11); remove #dll_import
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c13
-rw-r--r--src/check_stmt.c8
-rw-r--r--src/checker.c2
-rw-r--r--src/ir.c10
-rw-r--r--src/ir_print.c6
-rw-r--r--src/parser.c54
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;
diff --git a/src/ir.c b/src/ir.c
index 4f1ca5f9d..f808ac17e 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -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) {