diff --git a/README.md b/README.md index d84216b..389f882 100644 --- a/README.md +++ b/README.md @@ -110,4 +110,8 @@ Supported instructions so far: * add * subtract * multiply +* equal +* inequal +* greater +* lesser * end diff --git a/src/compiler.c b/src/compiler.c index 96fb7d5..84fac2e 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -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);