Compare commits
2 Commits
e3c8a2f453
...
51639e904d
| Author | SHA1 | Date | |
|---|---|---|---|
| 51639e904d | |||
| c728801bc3 |
@@ -110,4 +110,11 @@ Supported instructions so far:
|
||||
* add
|
||||
* subtract
|
||||
* multiply
|
||||
* equal
|
||||
* inequal
|
||||
* greater
|
||||
* lesser
|
||||
* jump
|
||||
* if
|
||||
* @ (label creation)
|
||||
* end
|
||||
|
||||
184
src/compiler.c
184
src/compiler.c
@@ -90,6 +90,11 @@ char* compileGroundProgram(GroundProgram* program) {
|
||||
for (size_t i = 0; i < program->size; i++) {
|
||||
GroundInstruction gi = program->instructions[i];
|
||||
switch (gi.type) {
|
||||
case CREATELABEL: {
|
||||
APPEND_ESTR(start, gi.args.args[0].value.refName);
|
||||
APPEND_ESTR(start, ":\n");
|
||||
break;
|
||||
}
|
||||
case SET: {
|
||||
if (gi.args.length < 2) {
|
||||
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", &gi, i);
|
||||
@@ -100,7 +105,7 @@ char* compileGroundProgram(GroundProgram* program) {
|
||||
if (gi.args.args[0].type != DIRREF) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -116,6 +121,53 @@ char* compileGroundProgram(GroundProgram* program) {
|
||||
|
||||
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: {
|
||||
if (gi.args.length < 3) {
|
||||
runtimeError(TOO_FEW_ARGS, "Expecting 2 args for add instruction", &gi, i);
|
||||
@@ -194,7 +246,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 +258,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);
|
||||
|
||||
Reference in New Issue
Block a user