aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c48
-rw-r--r--environment.c8
2 files changed, 38 insertions, 18 deletions
diff --git a/compile.c b/compile.c
index c536e378..bfd23925 100644
--- a/compile.c
+++ b/compile.c
@@ -450,16 +450,31 @@ CORD compile_statement(env_t *env, ast_t *ast)
else
code_err(ast, "I can't do operations between %T and %T", lhs_t, rhs_t);
- if (operand_t->tag != IntType && operand_t->tag != NumType)
- code_err(ast, "I can't do an update assignment with this operator between %T and %T", lhs_t, rhs_t);
-
switch (update->op) {
- case BINOP_MULT: return CORD_all(lhs, " *= ", rhs, ";");
- case BINOP_DIVIDE: return CORD_all(lhs, " /= ", rhs, ";");
- case BINOP_MOD: return CORD_all(lhs, " = ", lhs, " % ", rhs);
- case BINOP_MOD1: return CORD_all(lhs, " = (", lhs, " % ", rhs, ") + 1;");
- case BINOP_PLUS: return CORD_all(lhs, " += ", rhs, ";");
- case BINOP_MINUS: return CORD_all(lhs, " -= ", rhs, ";");
+ case BINOP_MULT:
+ if (operand_t->tag != IntType && operand_t->tag != NumType)
+ code_err(ast, "I can't do a multiply assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " *= ", rhs, ";");
+ case BINOP_DIVIDE:
+ if (operand_t->tag != IntType && operand_t->tag != NumType)
+ code_err(ast, "I can't do a divide assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " /= ", rhs, ";");
+ case BINOP_MOD:
+ if (operand_t->tag != IntType && operand_t->tag != NumType)
+ code_err(ast, "I can't do a mod assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " = ", lhs, " % ", rhs);
+ case BINOP_MOD1:
+ if (operand_t->tag != IntType && operand_t->tag != NumType)
+ code_err(ast, "I can't do a mod assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " = (", lhs, " % ", rhs, ") + 1;");
+ case BINOP_PLUS:
+ if (operand_t->tag != IntType && operand_t->tag != NumType)
+ code_err(ast, "I can't do an addition assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " += ", rhs, ";");
+ case BINOP_MINUS:
+ if (operand_t->tag != IntType && operand_t->tag != NumType)
+ code_err(ast, "I can't do a subtraction assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " -= ", rhs, ";");
case BINOP_POWER: {
if (lhs_t->tag != NumType)
code_err(ast, "'^=' is only supported for Num types");
@@ -468,8 +483,14 @@ CORD compile_statement(env_t *env, ast_t *ast)
else
return CORD_all(lhs, " = pow(", lhs, ", ", rhs, ");");
}
- case BINOP_LSHIFT: return CORD_all(lhs, " <<= ", rhs, ";");
- case BINOP_RSHIFT: return CORD_all(lhs, " >>= ", rhs, ";");
+ case BINOP_LSHIFT:
+ if (operand_t->tag != IntType)
+ code_err(ast, "I can't do a shift assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " <<= ", rhs, ";");
+ case BINOP_RSHIFT:
+ if (operand_t->tag != IntType)
+ code_err(ast, "I can't do a shift assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " >>= ", rhs, ";");
case BINOP_AND: {
if (operand_t->tag == BoolType)
return CORD_all("if (", lhs, ") ", lhs, " = ", rhs, ";");
@@ -486,7 +507,10 @@ CORD compile_statement(env_t *env, ast_t *ast)
else
code_err(ast, "'or=' is not implemented for %T types", operand_t);
}
- case BINOP_XOR: return CORD_all(lhs, " ^= ", rhs, ";");
+ case BINOP_XOR:
+ if (operand_t->tag != IntType && operand_t->tag != BoolType)
+ code_err(ast, "I can't do an xor assignment with this operator between %T and %T", lhs_t, rhs_t);
+ return CORD_all(lhs, " ^= ", rhs, ";");
case BINOP_CONCAT: {
if (operand_t->tag == TextType) {
return CORD_all(lhs, " = CORD_cat(", lhs, ", ", rhs, ");");
diff --git a/environment.c b/environment.c
index dcd852e3..b239dd3c 100644
--- a/environment.c
+++ b/environment.c
@@ -364,12 +364,8 @@ binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name)
code_err(self, "I couldn't get this type");
type_t *cls_type = value_type(self_type);
switch (cls_type->tag) {
- case ArrayType: {
- errx(1, "Array methods not implemented");
- }
- case TableType: {
- errx(1, "Table methods not implemented");
- }
+ case ArrayType: return NULL;
+ case TableType: return NULL;
case BoolType: case IntType: case NumType: {
binding_t *b = get_binding(env, CORD_to_const_char_star(type_to_cord(cls_type)));
assert(b);