diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-09-20 10:11:34 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-09-20 10:11:34 -0400 |
commit | d0e50fa8fbfc5de2c0d938671a7dab982163409d (patch) | |
tree | 541e8bd1e7a82b91dfcbe503d788c406cc56ff6f | |
parent | a3ff9a3526dbc9ed785017835352d83edae8c8ac (diff) |
cleaning up stuff; mul & div
-rw-r--r-- | eval.c | 10 | ||||
-rw-r--r-- | main.c | 12 | ||||
-rw-r--r-- | parse.c | 52 | ||||
-rw-r--r-- | test.toc | 20 | ||||
-rw-r--r-- | tokenizer.c | 28 | ||||
-rw-r--r-- | types.c | 13 |
6 files changed, 84 insertions, 51 deletions
@@ -41,7 +41,9 @@ static bool eval_expr_as_int(Expression *e, Integer *i) { switch (e->binary.op) { case BINARY_PLUS: - case BINARY_MINUS: { + case BINARY_MINUS: + case BINARY_MUL: + case BINARY_DIV: { Integer lhs, rhs; if (!eval_expr_as_int(e->binary.lhs, &lhs)) return false; if (!eval_expr_as_int(e->binary.rhs, &rhs)) return false; @@ -52,6 +54,12 @@ static bool eval_expr_as_int(Expression *e, Integer *i) { case BINARY_MINUS: *i = lhs - rhs; return true; + case BINARY_MUL: + *i = lhs * rhs; + return true; + case BINARY_DIV: + *i = lhs / rhs; + return true; default: assert(0); return false; } } @@ -1,8 +1,10 @@ -/* TODO: multi-dimensional arrays are flattened in types.c */ -/* TODO: remove all cgen errors */ -/* TODO: don't eval consts in C */ -/* TODO: Functions returning fixed-length arrays */ -/* TODO: improve error for declaring a keyword, e.g. i8: int = 8123; */ +/* +TODO: +blocks anywhere +pointers +don't allow nested functions to capture outer variables (constants are allowed though) +re-do cgen + */ #include "toc.c" int main(int argc, char **argv) { @@ -46,6 +46,8 @@ typedef struct Type { } Type; typedef struct Block { + Location start; + Location end; Array stmts; struct Expression *ret_expr; /* the return expression of this block, e.g. {foo(); 3} => 3 NULL for no expression. */ } Block; @@ -70,6 +72,8 @@ typedef enum { BINARY_SET, /* e.g. x = y */ BINARY_PLUS, BINARY_MINUS, + BINARY_MUL, + BINARY_DIV, BINARY_COMMA, BINARY_AT_INDEX /* e.g. x[i] */ } BinaryOp; @@ -172,6 +176,8 @@ static const char *binary_op_to_str(BinaryOp b) { switch (b) { case BINARY_PLUS: return "+"; case BINARY_MINUS: return "-"; + case BINARY_MUL: return "*"; + case BINARY_DIV: return "/"; case BINARY_SET: return "="; case BINARY_COMMA: return ","; case BINARY_AT_INDEX: return "[]"; @@ -320,16 +326,13 @@ static Expression *parser_new_expr(Parser *p) { #define NOT_AN_OP -1 static int op_precedence(Keyword op) { switch (op) { - case KW_EQ: - return 0; - case KW_COMMA: - return 5; - case KW_PLUS: - return 10; - case KW_MINUS: - return 20; - default: - return NOT_AN_OP; + case KW_EQ: return 0; + case KW_COMMA: return 5; + case KW_PLUS: return 10; + case KW_MINUS: return 20; + case KW_ASTERISK: return 30; + case KW_SLASH: return 40; + default: return NOT_AN_OP; } } @@ -510,6 +513,7 @@ static bool parse_block(Parser *p, Block *b) { tokr_err(t, "Expected '{' to open block."); return false; } + b->start = t->token->where; t->token++; /* move past { */ arr_create(&b->stmts, sizeof(Statement)); bool ret = true; @@ -551,6 +555,7 @@ static bool parse_block(Parser *p, Block *b) { } else { b->ret_expr = NULL; } + b->end = t->token->where; t->token++; /* move past } */ p->block = prev_block; return ret; @@ -911,6 +916,13 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { case KW_COMMA: op = BINARY_COMMA; break; + case KW_ASTERISK: + op = BINARY_MUL; + break; + case KW_SLASH: + op = BINARY_DIV; + break; + default: assert(0); return false; } e->binary.op = op; @@ -953,7 +965,7 @@ static bool parse_single_type_in_decl(Parser *p, Declaration *d, DeclEndType end while (1) { Identifier *ident = arr_add(&d->idents); if (t->token->kind != TOKEN_IDENT) { - tokr_err(t, "Cannot declare non-identifier."); + tokr_err(t, "Cannot declare non-identifier (that's a %s).", token_kind_to_str(t->token->kind)); /* TODO(eventually): an */ return false; } *ident = t->token->ident; @@ -1238,23 +1250,7 @@ static void fprint_expr(FILE *out, Expression *e) { fprint_ident(out, e->ident); break; case EXPR_BINARY_OP: - switch (e->binary.op) { - case BINARY_PLUS: - fprintf(out, "add"); - break; - case BINARY_MINUS: - fprintf(out, "subtract"); - break; - case BINARY_SET: - fprintf(out, "set"); - break; - case BINARY_AT_INDEX: - fprintf(out, "at"); - break; - case BINARY_COMMA: - fprintf(out, "tuple"); - break; - } + fprintf(out, "%s", binary_op_to_str(e->binary.op)); fprintf(out, "("); fprint_expr(out, e->binary.lhs); fprintf(out, ","); @@ -1,13 +1,17 @@ -#C("#include <stdio.h>\n"); - -print_int @= fn(y: int) { - #C("printf(\"%ld\\n\", (long)x);\n"); +N @= 3; +foo_func @= fn(x: int) [N][N]int { + foo : [3]int; + foo[0] = x*1; + foo[1] = x*2; + foo[2] = x*3; + asdf : [3][3]int; + asdf[0] = foo; + asdf[1] = foo; + asdf[2] = foo; + asdf }; - -times2 @= fn(x: int) int { x + x }; - main @= fn() { - print_int(times2(5)); + asdf : [3][3]int = foo_func(5); foo := fn (x, y, z,w : f32, A:f64) {}; foo(3,4,5,3,5); }; diff --git a/tokenizer.c b/tokenizer.c index b821820..63d36ee 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -28,9 +28,11 @@ typedef enum { KW_EQEQ, KW_LT, KW_LE, - KW_MINUS, KW_PLUS, - KW_LAST_SYMBOL = KW_PLUS, /* last one entirely consisting of symbols */ + KW_MINUS, + KW_ASTERISK, + KW_SLASH, + KW_LAST_SYMBOL = KW_SLASH, /* last one entirely consisting of symbols */ KW_FN, KW_INT, KW_I8, @@ -47,8 +49,8 @@ typedef enum { } Keyword; static const char *keywords[KW_COUNT] = - {";", "=", ":", "@", ",", "(", ")", "{", "}", "[", "]", "==", "<", "<=", "-", "+", "fn", - "int", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "f32", "f64"}; + {";", "=", ":", "@", ",", "(", ")", "{", "}", "[", "]", "==", "<", "<=", "+", "-", "*", + "/", "fn", "int", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "f32", "f64"}; static const char *directives[DIRECT_COUNT] = {"C"}; @@ -138,6 +140,22 @@ static inline bool token_is_kw(Token *t, Keyword kw) { return t->kind == TOKEN_KW && t->kw == kw; } + + +static const char *token_kind_to_str(TokenKind t) { + switch (t) { + case TOKEN_KW: return "keyword"; + case TOKEN_IDENT: return "identifier"; + case TOKEN_DIRECT: return "directive"; + case TOKEN_NUM_LITERAL: return "numerical literal"; + case TOKEN_CHAR_LITERAL: return "character literal"; + case TOKEN_STR_LITERAL: return "string literal"; + case TOKEN_EOF: return "end of file"; + } + assert(0); + return ""; +} + static void fprint_token(FILE *out, Token *t) { fprintf(out, "l%lu-", (unsigned long)t->where.line); switch (t->kind) { @@ -459,9 +477,9 @@ static bool tokenize_string(Tokenizer *t, char *str) { if (*t->s == '\'') { /* it's a character literal! */ - tokr_nextchar(t); Token *token = tokr_add(t); tokr_put_location(t, token); + tokr_nextchar(t); char c; if (*t->s == '\\') { /* escape sequence */ @@ -236,14 +236,16 @@ static bool type_of_expr(Expression *e) { t->kind = TYPE_FN; arr_create(&t->fn.types, sizeof(Type)); Type *ret_type = arr_add(&t->fn.types); - type_resolve(&f->ret_type); + if (!type_resolve(&f->ret_type)) + return false; *ret_type = f->ret_type; Declaration *params = &f->params; Type *type = ¶ms->type; Type *param_types = type->kind == TYPE_TUPLE ? type->tuple.data : type; for (size_t i = 0; i < params->idents.len; i++) { Type *param_type = arr_add(&t->fn.types); - type_resolve(¶m_types[i]); + if (!type_resolve(¶m_types[i])) + return false; *param_type = param_types[i]; } } break; @@ -346,7 +348,9 @@ static bool type_of_expr(Expression *e) { if (!expr_must_lval(e->binary.lhs)) return false; /* fallthrough */ case BINARY_PLUS: - case BINARY_MINUS: { + case BINARY_MINUS: + case BINARY_MUL: + case BINARY_DIV: { bool match = true; if (e->binary.op != BINARY_SET) { /* numerical binary ops */ @@ -471,8 +475,9 @@ static bool types_expr(Expression *e) { } else if (ret_type->kind != TYPE_VOID) { /* TODO: this should really be at the closing brace, and not the function declaration */ char *expected = type_to_str(ret_type); - err_print(e->where, "No return value in function which returns %s.", expected); + err_print(f->body.end, "No return value in function which returns %s.", expected); free(expected); + info_print(e->where, "Function was declared here:"); return false; } } break; |