Add comparisons

This commit is contained in:
2026-01-21 14:10:34 +11:00
parent e3c8a2f453
commit c728801bc3
2 changed files with 133 additions and 1 deletions

View File

@@ -110,4 +110,8 @@ Supported instructions so far:
* add
* subtract
* multiply
* equal
* inequal
* greater
* lesser
* end

View File

@@ -194,7 +194,7 @@ char* compileGroundProgram(GroundProgram* program) {
}
char* varName= gi.args.args[2].value.refName;
APPEND_ESTR(start, " ; add\n");
APPEND_ESTR(start, " ; multiply\n");
APPEND_ESTR(start, " mov rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[0]));
APPEND_ESTR(start, "\n");
@@ -206,6 +206,134 @@ char* compileGroundProgram(GroundProgram* program) {
APPEND_ESTR(start, "], rax\n");
break;
}
case EQUAL: {
if (gi.args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args for equal instruction", &gi, i);
}
if (gi.args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args for equal instruction", &gi, i);
}
if (gi.args.args[0].type != VALUE && gi.args.args[0].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 1", &gi, i);
}
if (gi.args.args[1].type != VALUE && gi.args.args[1].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 2", &gi, i);
}
if (gi.args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", &gi, i);
}
char* varName= gi.args.args[2].value.refName;
APPEND_ESTR(start, " ; equal\n");
APPEND_ESTR(start, " mov rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[0]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " cmp rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[1]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " sete al\n");
APPEND_ESTR(start, " movzx rax, al\n");
APPEND_ESTR(start, " mov [");
APPEND_ESTR(start, varName);
APPEND_ESTR(start, "], rax\n");
break;
}
case INEQUAL: {
if (gi.args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args for inequal instruction", &gi, i);
}
if (gi.args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args for inequal instruction", &gi, i);
}
if (gi.args.args[0].type != VALUE && gi.args.args[0].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 1", &gi, i);
}
if (gi.args.args[1].type != VALUE && gi.args.args[1].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 2", &gi, i);
}
if (gi.args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", &gi, i);
}
char* varName= gi.args.args[2].value.refName;
APPEND_ESTR(start, " ; inequal\n");
APPEND_ESTR(start, " mov rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[0]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " cmp rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[1]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " setne al\n");
APPEND_ESTR(start, " movzx rax, al\n");
APPEND_ESTR(start, " mov [");
APPEND_ESTR(start, varName);
APPEND_ESTR(start, "], rax\n");
break;
}
case GREATER: {
if (gi.args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args for greater instruction", &gi, i);
}
if (gi.args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args for greater instruction", &gi, i);
}
if (gi.args.args[0].type != VALUE && gi.args.args[0].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 1", &gi, i);
}
if (gi.args.args[1].type != VALUE && gi.args.args[1].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 2", &gi, i);
}
if (gi.args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", &gi, i);
}
char* varName= gi.args.args[2].value.refName;
APPEND_ESTR(start, " ; greater\n");
APPEND_ESTR(start, " mov rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[0]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " cmp rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[1]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " setg al\n");
APPEND_ESTR(start, " movzx rax, al\n");
APPEND_ESTR(start, " mov [");
APPEND_ESTR(start, varName);
APPEND_ESTR(start, "], rax\n");
break;
}
case LESSER: {
if (gi.args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args for lesser instruction", &gi, i);
}
if (gi.args.length > 3) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args for lesser instruction", &gi, i);
}
if (gi.args.args[0].type != VALUE && gi.args.args[0].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 1", &gi, i);
}
if (gi.args.args[1].type != VALUE && gi.args.args[1].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 2", &gi, i);
}
if (gi.args.args[2].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 3", &gi, i);
}
char* varName= gi.args.args[2].value.refName;
APPEND_ESTR(start, " ; lesser\n");
APPEND_ESTR(start, " mov rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[0]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " cmp rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[1]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " setl al\n");
APPEND_ESTR(start, " movzx rax, al\n");
APPEND_ESTR(start, " mov [");
APPEND_ESTR(start, varName);
APPEND_ESTR(start, "], rax\n");
break;
}
case END: {
if (gi.args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg for end instruction", &gi, i);