summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base_cgen.c8
-rw-r--r--cgen.c3
-rw-r--r--eval.c4
-rw-r--r--out.c4
-rw-r--r--parse.c19
-rw-r--r--test.toc4
-rw-r--r--types.c14
7 files changed, 45 insertions, 11 deletions
diff --git a/base_cgen.c b/base_cgen.c
index 537f1c5..1ddf83a 100644
--- a/base_cgen.c
+++ b/base_cgen.c
@@ -106,9 +106,11 @@ static bool cgen_ident(CGenerator *g, Identifier i, Location *where) {
return false;
}
Declaration *decl = id_decl->decl;
- if (decl->expr.kind == EXPR_FN) {
- cgen_fn_name(g, &decl->expr.fn, NULL);
- return true;
+ if (decl->flags & DECL_FLAG_HAS_EXPR) {
+ if (decl->expr.kind == EXPR_FN) {
+ cgen_fn_name(g, &decl->expr.fn, NULL);
+ return true;
+ }
}
}
cgen_indent(g);
diff --git a/cgen.c b/cgen.c
index 2802886..4fa6bcb 100644
--- a/cgen.c
+++ b/cgen.c
@@ -29,6 +29,9 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
case BINARY_MINUS:
cgen_write(g, "-");
break;
+ case BINARY_SET:
+ cgen_write(g, "=");
+ break;
}
if (!cgen_expr(g, e->binary.rhs)) return false;
cgen_write(g, ")");
diff --git a/eval.c b/eval.c
index d8402c6..2384661 100644
--- a/eval.c
+++ b/eval.c
@@ -52,8 +52,12 @@ static bool eval_expr_as_int(Expression *e, Integer *i) {
case BINARY_MINUS:
*i = lhs - rhs;
return true;
+ default: assert(0); return false;
}
}
+ case BINARY_SET:
+ err_print(e->where, "Expected operator which returns an integer, but got %s", binary_op_to_str(e->binary.op));
+ return false;
}
} break;
case EXPR_IDENT: {
diff --git a/out.c b/out.c
index 19ee285..a38f208 100644
--- a/out.c
+++ b/out.c
@@ -6,7 +6,9 @@ void main__(void) {
int64_t const FOO = 1928;
int64_t const BAR = 5;
int64_t foo[1935];
- int64_t bar[11];
+ int64_t bar[77];
+ int64_t x;
+ (x=13);
}
int main(void) {
diff --git a/parse.c b/parse.c
index afb36ef..82f75e7 100644
--- a/parse.c
+++ b/parse.c
@@ -75,6 +75,7 @@ typedef enum {
} UnaryOp;
typedef enum {
+ BINARY_SET, /* e.g. x = y */
BINARY_PLUS,
BINARY_MINUS
} BinaryOp;
@@ -145,6 +146,16 @@ typedef struct {
Block *block; /* which block are we in? NULL = file scope */
} Parser;
+static const char *binary_op_to_str(BinaryOp b) {
+ switch (b) {
+ case BINARY_PLUS: return "+";
+ case BINARY_MINUS: return "-";
+ case BINARY_SET: return "=";
+ }
+ assert(0);
+ return "";
+}
+
static bool type_builtin_is_integer(BuiltinType b) {
switch (b) {
case BUILTIN_I8:
@@ -266,6 +277,8 @@ 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_PLUS:
return 10;
case KW_MINUS:
@@ -776,6 +789,9 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
case KW_MINUS:
op = BINARY_MINUS;
break;
+ case KW_EQ:
+ op = BINARY_SET;
+ break;
default: assert(0); break;
}
e->binary.op = op;
@@ -1040,6 +1056,9 @@ static void fprint_expr(FILE *out, Expression *e) {
case BINARY_MINUS:
fprintf(out, "subtract");
break;
+ case BINARY_SET:
+ fprintf(out, "set");
+ break;
}
fprintf(out, "(");
fprint_expr(out, e->binary.lhs);
diff --git a/test.toc b/test.toc
index 6dc6678..37d1ea4 100644
--- a/test.toc
+++ b/test.toc
@@ -3,5 +3,7 @@ main @= fn() {
FOO @= 1928;
BAR @= 5;
foo : [N+FOO-3--BAR]int;
- bar : [fn(){}]int;
+ bar : [77]int;
+ x : int;
+ x = 13;
};
diff --git a/types.c b/types.c
index 50815ac..2bdbd8c 100644
--- a/types.c
+++ b/types.c
@@ -185,7 +185,8 @@ static bool type_of_expr(Expression *e, Type *t) {
case EXPR_BINARY_OP: {
switch (e->binary.op) {
case BINARY_PLUS:
- case BINARY_MINUS: {
+ case BINARY_MINUS:
+ case BINARY_SET: {
Type *lhs_type = &e->binary.lhs->type;
Type *rhs_type = &e->binary.rhs->type;
if (!type_of_expr(e->binary.lhs, lhs_type)
@@ -199,6 +200,11 @@ static bool type_of_expr(Expression *e, Type *t) {
} else if (!type_builtin_is_numerical(lhs_type->builtin) || !type_builtin_is_numerical(rhs_type->builtin)) {
match = false;
} else {
+ if (e->binary.op == BINARY_SET) {
+ /* type of x = y is always void */
+ t->kind = TYPE_VOID;
+ return true;
+ }
int lhs_is_flexible = lhs_type->flags & TYPE_FLAG_FLEXIBLE;
int rhs_is_flexible = rhs_type->flags & TYPE_FLAG_FLEXIBLE;
if (lhs_is_flexible && rhs_is_flexible) {
@@ -218,11 +224,7 @@ static bool type_of_expr(Expression *e, Type *t) {
char s1[128], s2[128];
type_to_str(lhs_type, s1, sizeof s1);
type_to_str(rhs_type, s2, sizeof s2);
- const char *op;
- switch (e->binary.op) {
- case BINARY_PLUS: op = "+"; break;
- case BINARY_MINUS: op = "-"; break;
- }
+ const char *op = binary_op_to_str(e->binary.op);
err_print(e->where, "Mismatched types to operator %s: %s and %s", op, s1, s2);
return false;
}