summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-09-20 10:11:34 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-09-20 10:11:34 -0400
commitd0e50fa8fbfc5de2c0d938671a7dab982163409d (patch)
tree541e8bd1e7a82b91dfcbe503d788c406cc56ff6f
parenta3ff9a3526dbc9ed785017835352d83edae8c8ac (diff)
cleaning up stuff; mul & div
-rw-r--r--eval.c10
-rw-r--r--main.c12
-rw-r--r--parse.c52
-rw-r--r--test.toc20
-rw-r--r--tokenizer.c28
-rw-r--r--types.c13
6 files changed, 84 insertions, 51 deletions
diff --git a/eval.c b/eval.c
index c9ecfaa..f14ab79 100644
--- a/eval.c
+++ b/eval.c
@@ -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;
}
}
diff --git a/main.c b/main.c
index 9b0e864..9c62e6b 100644
--- a/main.c
+++ b/main.c
@@ -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) {
diff --git a/parse.c b/parse.c
index f3415cf..e9695e6 100644
--- a/parse.c
+++ b/parse.c
@@ -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, ",");
diff --git a/test.toc b/test.toc
index 115f97b..a89c6fb 100644
--- a/test.toc
+++ b/test.toc
@@ -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 */
diff --git a/types.c b/types.c
index c17aff6..e8a95b3 100644
--- a/types.c
+++ b/types.c
@@ -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 = &params->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(&param_types[i]);
+ if (!type_resolve(&param_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;