aboutsummaryrefslogtreecommitdiff
path: root/src/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compile.c')
-rw-r--r--src/compile.c47
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);