summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh2
-rw-r--r--cgen.c8
-rw-r--r--eval.c16
-rw-r--r--parse.c27
-rw-r--r--test.toc19
-rw-r--r--tokenizer.c4
-rw-r--r--types.c13
-rw-r--r--types.h10
8 files changed, 80 insertions, 19 deletions
diff --git a/build.sh b/build.sh
index f523a64..865313a 100755
--- a/build.sh
+++ b/build.sh
@@ -22,7 +22,7 @@ else
WARNINGS='-Wall -Wextra -Wpedantic -Wshadow -Wconversion -Wno-pointer-to-int-cast -Wno-unused-parameter'
fi
-DEBUG_FLAGS="-Og -g3 $WARNINGS -std=c11 -DTOC_DEBUG"
+DEBUG_FLAGS="-O0 -g3 $WARNINGS -std=c11 -DTOC_DEBUG"
RELEASE_FLAGS="-O3 -s -DNDEBUG $WARNINGS -std=c11"
if [ "$1" = "release" ]; then
diff --git a/cgen.c b/cgen.c
index daeac3f..0e0a3ce 100644
--- a/cgen.c
+++ b/cgen.c
@@ -1029,6 +1029,14 @@ static bool cgen_expr(CGenerator *g, Expression *e) {
s = "=="; break;
case BINARY_NE:
s = "!="; break;
+ case BINARY_SET_ADD:
+ s = "+="; break;
+ case BINARY_SET_SUB:
+ s = "-="; break;
+ case BINARY_SET_MUL:
+ s = "*="; break;
+ case BINARY_SET_DIV:
+ s = "/="; break;
case BINARY_AT_INDEX:
cgen_write(g, "(");
switch (e->binary.lhs->type.kind) {
diff --git a/eval.c b/eval.c
index 90f29c6..1d893f4 100644
--- a/eval.c
+++ b/eval.c
@@ -1125,6 +1125,22 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) {
case BINARY_SET:
if (!eval_set(ev, e->binary.lhs, &rhs)) return false;
break;
+ case BINARY_SET_ADD:
+ case BINARY_SET_SUB:
+ case BINARY_SET_MUL:
+ case BINARY_SET_DIV: {
+ BinaryOp subop = (BinaryOp)0;
+ switch (e->binary.op) {
+ case BINARY_SET_ADD: subop = BINARY_ADD; break;
+ case BINARY_SET_SUB: subop = BINARY_SUB; break;
+ case BINARY_SET_MUL: subop = BINARY_MUL; break;
+ case BINARY_SET_DIV: subop = BINARY_DIV; break;
+ default: assert(0);
+ }
+ eval_numerical_bin_op(lhs, &e->binary.lhs->type, subop, rhs, &e->binary.rhs->type, v, &e->binary.lhs->type);
+ if (!eval_set(ev, e->binary.lhs, v)) return false;
+ break;
+ } break;
case BINARY_AT_INDEX: {
void *ptr;
Type *type;
diff --git a/parse.c b/parse.c
index b545667..a7ac633 100644
--- a/parse.c
+++ b/parse.c
@@ -52,6 +52,10 @@ static const char *binary_op_to_str(BinaryOp b) {
case BINARY_MUL: return "*";
case BINARY_DIV: return "/";
case BINARY_SET: return "=";
+ case BINARY_SET_ADD: return "+=";
+ case BINARY_SET_SUB: return "-=";
+ case BINARY_SET_MUL: return "*=";
+ case BINARY_SET_DIV: return "/=";
case BINARY_AT_INDEX: return "[]";
case BINARY_LT: return "<";
case BINARY_LE: return "<=";
@@ -869,13 +873,18 @@ static void fprint_expr(FILE *out, Expression *e);
#define NEW_PRECEDENCE 22
static int op_precedence(Keyword op) {
switch (op) {
- case KW_EQ: return 0;
+ case KW_EQ:
+ case KW_PLUS_EQ:
+ case KW_MINUS_EQ:
+ case KW_ASTERISK_EQ:
+ case KW_SLASH_EQ:
+ return 0;
case KW_COMMA: return 1;
case KW_LT: return 3;
case KW_GT: return 3;
case KW_LE: return 3;
case KW_GE: return 3;
- case KW_EQEQ: return 3;
+ case KW_EQ_EQ: return 3;
case KW_NE: return 3;
case KW_PLUS: return 10;
case KW_MINUS: return 20;
@@ -1393,7 +1402,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
case KW_MINUS:
op = BINARY_SUB;
break;
- case KW_EQEQ:
+ case KW_EQ_EQ:
op = BINARY_EQ;
break;
case KW_NE:
@@ -1414,6 +1423,18 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
case KW_EQ:
op = BINARY_SET;
break;
+ case KW_PLUS_EQ:
+ op = BINARY_SET_ADD;
+ break;
+ case KW_MINUS_EQ:
+ op = BINARY_SET_SUB;
+ break;
+ case KW_ASTERISK_EQ:
+ op = BINARY_SET_MUL;
+ break;
+ case KW_SLASH_EQ:
+ op = BINARY_SET_DIV;
+ break;
case KW_ASTERISK:
op = BINARY_MUL;
break;
diff --git a/test.toc b/test.toc
index 689b4fe..d17b226 100644
--- a/test.toc
+++ b/test.toc
@@ -9,20 +9,15 @@ putf @= fn(x: float) {
");
};
-
-sum @= fn() int {
-
-x := 3;
-total := 0;
-each x := 1..10{
- total = total + x;
- total
-}
-
+lsh @= fn(x: int, bits: int) int {
+ each 1..bits {
+ x *= 2;
+ }
+ x
};
main @= fn() {
- puti(sum());
- X @= sum();
+ puti(lsh(2, 15));
+ X @= lsh(2, 15);
puti(X);
};
diff --git a/tokenizer.c b/tokenizer.c
index ab668fc..adbb7b1 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -1,5 +1,7 @@
static const char *keywords[KW_COUNT] =
- {";", ":", "@", ",", "(", ")", "{", "}", "[", "]", "==", "!=", "<=", "<", ">=", ">",
+ {";", ":", "@", ",", "(", ")", "{", "}", "[", "]", "==",
+ "+=", "-=", "*=", "/=",
+ "!=", "<=", "<", ">=", ">",
"+", "-", "*", "!", "&", "/", "..", ".",
"=",
"if", "elif", "else", "while", "each", "return", "fn", "as",
diff --git a/types.c b/types.c
index 0cc7772..4a07afd 100644
--- a/types.c
+++ b/types.c
@@ -1177,10 +1177,13 @@ static bool types_expr(Typer *tr, Expression *e) {
}
switch (o) {
case BINARY_SET:
+ case BINARY_SET_ADD:
+ case BINARY_SET_SUB:
+ case BINARY_SET_MUL:
+ case BINARY_SET_DIV:
if (!expr_must_lval(e->binary.lhs)) {
return false;
}
-
/* fallthrough */
case BINARY_ADD:
case BINARY_SUB:
@@ -1270,6 +1273,14 @@ static bool types_expr(Typer *tr, Expression *e) {
err_print(e->where, "Invalid types to operator %s: %s and %s", op, s1, s2);
return false;
}
+ if (o == BINARY_SET_ADD ||
+ o == BINARY_SET_SUB ||
+ o == BINARY_SET_MUL ||
+ o == BINARY_SET_DIV) {
+ t->kind = TYPE_VOID; /* actually, it's just void */
+ t->flags = 0;
+ }
+
break;
}
case BINARY_AT_INDEX:
diff --git a/types.h b/types.h
index 5222f85..d6143da 100644
--- a/types.h
+++ b/types.h
@@ -164,7 +164,11 @@ typedef enum {
KW_RBRACE,
KW_LSQUARE,
KW_RSQUARE,
- KW_EQEQ,
+ KW_EQ_EQ,
+ KW_PLUS_EQ,
+ KW_MINUS_EQ,
+ KW_ASTERISK_EQ,
+ KW_SLASH_EQ,
KW_NE,
KW_LE,
KW_LT,
@@ -381,6 +385,10 @@ typedef enum {
BINARY_SUB,
BINARY_MUL,
BINARY_DIV,
+ BINARY_SET_ADD, /* e.g. x += y */
+ BINARY_SET_SUB,
+ BINARY_SET_MUL,
+ BINARY_SET_DIV,
BINARY_GT,
BINARY_LT,
BINARY_GE,