Add control flow

This commit is contained in:
2026-01-21 14:35:48 +11:00
parent c728801bc3
commit 51639e904d
2 changed files with 56 additions and 1 deletions

View File

@@ -114,4 +114,7 @@ Supported instructions so far:
* inequal * inequal
* greater * greater
* lesser * lesser
* jump
* if
* @ (label creation)
* end * end

View File

@@ -90,6 +90,11 @@ char* compileGroundProgram(GroundProgram* program) {
for (size_t i = 0; i < program->size; i++) { for (size_t i = 0; i < program->size; i++) {
GroundInstruction gi = program->instructions[i]; GroundInstruction gi = program->instructions[i];
switch (gi.type) { switch (gi.type) {
case CREATELABEL: {
APPEND_ESTR(start, gi.args.args[0].value.refName);
APPEND_ESTR(start, ":\n");
break;
}
case SET: { case SET: {
if (gi.args.length < 2) { if (gi.args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &gi, i); runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &gi, i);
@@ -100,7 +105,7 @@ char* compileGroundProgram(GroundProgram* program) {
if (gi.args.args[0].type != DIRREF) { if (gi.args.args[0].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", &gi, i); runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 1", &gi, i);
} }
if (gi.args.args[1].type != VALUE) { if (gi.args.args[1].type != VALUE && gi.args.args[1].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", &gi, i); runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value for arg 2", &gi, i);
} }
@@ -116,6 +121,53 @@ char* compileGroundProgram(GroundProgram* program) {
break; break;
} }
case JUMP: {
if (gi.args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", &gi, i);
}
if (gi.args.length > 1) {
runtimeError(TOO_MANY_ARGS, "Expecting 1 arg", &gi, i);
}
if (gi.args.args[0].type != LINEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef", &gi, i);
}
char* labelName = gi.args.args[0].value.refName;
APPEND_ESTR(start, " ; jump\n");
APPEND_ESTR(start, " jmp ");
APPEND_ESTR(start, labelName);
APPEND_ESTR(start, "\n");
break;
}
case IF: {
if (gi.args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &gi, i);
}
if (gi.args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", &gi, i);
}
if (gi.args.args[0].type != VALUE && gi.args.args[0].type != VALREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int (for now) for arg 1", &gi, i);
}
if (gi.args.args[1].type != LINEREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef", &gi, i);
}
char* labelName = gi.args.args[1].value.refName;
APPEND_ESTR(start, " ; if\n");
APPEND_ESTR(start, " mov rax, ");
APPEND_ESTR(start, processValueString(gi.args.args[0]));
APPEND_ESTR(start, "\n");
APPEND_ESTR(start, " test rax, rax\n");
APPEND_ESTR(start, " jnz ");
APPEND_ESTR(start, labelName);
APPEND_ESTR(start, "\n");
break;
}
case ADD: { case ADD: {
if (gi.args.length < 3) { if (gi.args.length < 3) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args for add instruction", &gi, i); runtimeError(TOO_FEW_ARGS, "Expecting 2 args for add instruction", &gi, i);