diff options
Diffstat (limited to 'src/compile.c')
| -rw-r--r-- | src/compile.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/src/compile.c b/src/compile.c index 2fa9ed43..3bc2fa4a 100644 --- a/src/compile.c +++ b/src/compile.c @@ -517,22 +517,22 @@ static CORD compile_update_assignment(env_t *env, ast_t *ast) CORD update_assignment = CORD_EMPTY; switch (ast->tag) { case PlusUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType) update_assignment = CORD_all(lhs, " += ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } case MinusUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType) update_assignment = CORD_all(lhs, " -= ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } case MultiplyUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType) update_assignment = CORD_all(lhs, " *= ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } case DivideUpdate: { - if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType) + if (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType) update_assignment = CORD_all(lhs, " /= ", compile_to_type(env, update.rhs, lhs_t), ";"); break; } @@ -673,12 +673,12 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) return CORD_all("pow(", lhs, ", ", rhs, ")"); } case Multiply: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType && overall_t->tag != DecType) code_err(ast, "Math operations are only supported for values of the same numeric type, not ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); return CORD_all("(", lhs, " * ", rhs, ")"); } case Divide: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType && overall_t->tag != DecType) code_err(ast, "Math operations are only supported for values of the same numeric type, not ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); return CORD_all("(", lhs, " / ", rhs, ")"); } @@ -693,14 +693,14 @@ static CORD compile_binary_op(env_t *env, ast_t *ast) return CORD_all("((((", lhs, ")-1) % (", rhs, ")) + 1)"); } case Plus: { - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType && overall_t->tag != DecType) code_err(ast, "Math operations are only supported for values of the same numeric type, not ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); return CORD_all("(", lhs, " + ", rhs, ")"); } case Minus: { if (overall_t->tag == SetType) return CORD_all("Table$without(", lhs, ", ", rhs, ", ", compile_type_info(overall_t), ")"); - if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType) + if (overall_t->tag != IntType && overall_t->tag != NumType && overall_t->tag != ByteType && overall_t->tag != DecType) code_err(ast, "Math operations are only supported for values of the same numeric type, not ", type_to_str(lhs_t), " and ", type_to_str(rhs_t)); return CORD_all("(", lhs, " - ", rhs, ")"); } @@ -804,6 +804,7 @@ CORD compile_type(type_t *t) case ByteType: return "Byte_t"; case CStringType: return "const char*"; case BigIntType: return "Int_t"; + case DecType: return "Dec_t"; case IntType: return CORD_all("Int", String(Match(t, IntType)->bits), "_t"); case NumType: return Match(t, NumType)->bits == TYPE_NBITS64 ? "Num_t" : CORD_all("Num", String(Match(t, NumType)->bits), "_t"); case TextType: { @@ -846,7 +847,7 @@ CORD compile_type(type_t *t) return compile_type(nonnull); case TextType: return Match(nonnull, TextType)->lang ? compile_type(nonnull) : "OptionalText_t"; - case IntType: case BigIntType: case NumType: case BoolType: case ByteType: + case IntType: case BigIntType: case DecType: case NumType: case BoolType: case ByteType: case ListType: case TableType: case SetType: return CORD_all("Optional", compile_type(nonnull)); case StructType: { @@ -1011,6 +1012,8 @@ CORD check_none(type_t *t, CORD value) return CORD_all("({(", value, ").$tag == 0;})"); else return CORD_all("((", value, ") == 0)"); + } else if (t->tag == DecType) { + return CORD_all("((int64_t)(", value, ") == -1)"); } print_err("Optional check not implemented for: ", type_to_str(t)); return CORD_EMPTY; @@ -1397,28 +1400,28 @@ static CORD _compile_statement(env_t *env, ast_t *ast) case PlusUpdate: { DeclareMatch(update, ast, PlusUpdate); type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) + if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType)) return CORD_all(compile_lvalue(env, update->lhs), " += ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } case MinusUpdate: { DeclareMatch(update, ast, MinusUpdate); type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) + if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType)) return CORD_all(compile_lvalue(env, update->lhs), " -= ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } case MultiplyUpdate: { DeclareMatch(update, ast, MultiplyUpdate); type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) + if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType)) return CORD_all(compile_lvalue(env, update->lhs), " *= ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } case DivideUpdate: { DeclareMatch(update, ast, DivideUpdate); type_t *lhs_t = get_type(env, update->lhs); - if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType)) + if (is_idempotent(update->lhs) && (lhs_t->tag == IntType || lhs_t->tag == NumType || lhs_t->tag == ByteType || lhs_t->tag == DecType)) return CORD_all(compile_lvalue(env, update->lhs), " /= ", compile_to_type(env, update->rhs, lhs_t), ";"); return compile_update_assignment(env, ast); } @@ -2047,7 +2050,7 @@ CORD expr_as_text(CORD expr, type_t *t, CORD color) // NOTE: this cannot use stack(), since bools may actually be bit fields: return CORD_all("Bool$as_text((Bool_t[1]){", expr, "}, ", color, ", &Bool$info)"); case CStringType: return CORD_all("CString$as_text(stack(", expr, "), ", color, ", &CString$info)"); - case BigIntType: case IntType: case ByteType: case NumType: { + case BigIntType: case DecType: case IntType: case ByteType: case NumType: { CORD name = type_to_cord(t); return CORD_all(name, "$as_text(stack(", expr, "), ", color, ", &", name, "$info)"); } @@ -2382,6 +2385,9 @@ CORD compile_int_to_type(env_t *env, ast_t *ast, type_t *target) if (target->tag == BigIntType) return compile(env, ast); + if (target->tag == DecType) + return compile(env, WrapAST(ast, Dec, .str=Match(ast, Int)->str)); + if (target->tag == OptionalType && Match(target, OptionalType)->type) return compile_int_to_type(env, ast, Match(target, OptionalType)->type); @@ -2597,6 +2603,7 @@ CORD compile_none(type_t *t) switch (t->tag) { case BigIntType: return "NONE_INT"; + case DecType: return "NONE_DEC"; case IntType: { switch (Match(t, IntType)->bits) { case TYPE_IBITS8: return "NONE_INT8"; @@ -2640,6 +2647,7 @@ CORD compile_empty(type_t *t) switch (t->tag) { case BigIntType: return "I(0)"; + case DecType: return "0.0DD"; case IntType: { switch (Match(t, IntType)->bits) { case TYPE_IBITS8: return "I8(0)"; @@ -2769,6 +2777,9 @@ CORD compile(env_t *env, ast_t *ast) case Num: { return String(hex_double(Match(ast, Num)->n)); } + case Dec: { + return CORD_all(Match(ast, Dec)->str, strchr(Match(ast, Dec)->str, '.') ? CORD_EMPTY : ".", "DD"); + } case Not: { ast_t *value = Match(ast, Not)->value; type_t *t = get_type(env, value); @@ -2805,7 +2816,7 @@ CORD compile(env_t *env, ast_t *ast) return CORD_all(b->code, "(", compile_arguments(env, ast, fn->args, new(arg_ast_t, .value=value)), ")"); } - if (t->tag == IntType || t->tag == NumType) + if (t->tag == IntType || t->tag == NumType || t->tag == DecType) return CORD_all("-(", compile(env, value), ")"); code_err(ast, "I don't know how to get the negative value of type ", type_to_str(t)); @@ -2862,7 +2873,7 @@ CORD compile(env_t *env, ast_t *ast) switch (operand_t->tag) { case BigIntType: return CORD_all(ast->tag == Equals ? CORD_EMPTY : "!", "Int$equal_value(", lhs, ", ", rhs, ")"); - case BoolType: case ByteType: case IntType: case NumType: case PointerType: case FunctionType: + case BoolType: case ByteType: case IntType: case NumType: case PointerType: case FunctionType: case DecType: return CORD_all("(", lhs, ast->tag == Equals ? " == " : " != ", rhs, ")"); default: return CORD_all(ast->tag == Equals ? CORD_EMPTY : "!", @@ -2898,7 +2909,7 @@ CORD compile(env_t *env, ast_t *ast) switch (operand_t->tag) { case BigIntType: return CORD_all("(Int$compare_value(", lhs, ", ", rhs, ") ", op, " 0)"); - case BoolType: case ByteType: case IntType: case NumType: case PointerType: case FunctionType: + case BoolType: case ByteType: case IntType: case NumType: case PointerType: case FunctionType: case DecType: return CORD_all("(", lhs, " ", op, " ", rhs, ")"); default: return CORD_all("(generic_compare(stack(", lhs, "), stack(", rhs, "), ", @@ -3986,7 +3997,7 @@ CORD compile_type_info(type_t *t) else if (t == PATH_TYPE_TYPE) return "&PathType$info"; switch (t->tag) { - case BoolType: case ByteType: case IntType: case BigIntType: case NumType: case CStringType: + case BoolType: case ByteType: case IntType: case BigIntType: case DecType: case NumType: case CStringType: return CORD_all("&", type_to_cord(t), "$info"); case TextType: { DeclareMatch(text, t, TextType); |
