diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-02-26 00:44:26 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-02-26 00:44:26 +0000 |
| commit | c59f6b7d0b582131bed4450bbb9aa1a71d5a01af (patch) | |
| tree | 34957d43fa0241ffb6678302cae8e77fb7f8488b /src/check_stmt.c | |
| parent | 67ed8a9a4ab8fdcfc77036c827b7dfa98025bc8b (diff) | |
++ -- statements; add strconv.odin (and replace some of the fmt procs); Fix ~ on 64 bit constants; Fix integer casts from smaller to larger size
Diffstat (limited to 'src/check_stmt.c')
| -rw-r--r-- | src/check_stmt.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/src/check_stmt.c b/src/check_stmt.c index 90cb6ff61..9c0b0c187 100644 --- a/src/check_stmt.c +++ b/src/check_stmt.c @@ -421,6 +421,49 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { check_stmt(c, ts->stmt, flags); case_end; + case_ast_node(s, IncDecStmt, node); + TokenKind op = s->op.kind; + switch (op) { + case Token_Inc: op = Token_Add; break; + case Token_Dec: op = Token_Sub; break; + default: + error_node(node, "Invalid inc/dec operation"); + return; + } + + Operand x = {0}; + check_expr(c, &x, s->expr); + if (x.mode == Addressing_Invalid) { + return; + } + if (!is_type_integer(x.type) && !is_type_float(x.type)) { + gbString e = expr_to_string(s->expr); + gbString t = type_to_string(x.type); + error_node(node, "%s%.*s used on non-numeric type %s", e, LIT(s->op.string), t); + gb_string_free(t); + gb_string_free(e); + return; + } + AstNode *left = s->expr; + AstNode *right = gb_alloc_item(c->allocator, AstNode); + right->kind = AstNode_BasicLit; + right->BasicLit.pos = s->op.pos; + right->BasicLit.kind = Token_Integer; + right->BasicLit.string = str_lit("1"); + + AstNode *be = gb_alloc_item(c->allocator, AstNode); + be->kind = AstNode_BinaryExpr; + be->BinaryExpr.op = s->op; + be->BinaryExpr.op.kind = op; + be->BinaryExpr.left = left; + be->BinaryExpr.right = right; + check_binary_expr(c, &x, be); + if (x.mode == Addressing_Invalid) { + return; + } + check_assignment_variable(c, &x, left); + case_end; + case_ast_node(as, AssignStmt, node); switch (as->op.kind) { case Token_Eq: { @@ -591,8 +634,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { if (fs->post != NULL) { check_stmt(c, fs->post, 0); - if (fs->post->kind != AstNode_AssignStmt) { - error_node(fs->post, "`for` statement post statement must be an assignment"); + if (fs->post->kind != AstNode_AssignStmt && + fs->post->kind != AstNode_IncDecStmt) { + error_node(fs->post, "`for` statement post statement must be a simple statement"); } } check_stmt(c, fs->body, new_flags); |