diff --git a/README.md b/README.md index e2a35bd..d84216b 100644 --- a/README.md +++ b/README.md @@ -108,4 +108,6 @@ Supported instructions so far: * set * add +* subtract +* multiply * end diff --git a/src/compiler.c b/src/compiler.c index 49e725e..96fb7d5 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -146,6 +146,66 @@ char* compileGroundProgram(GroundProgram* program) { APPEND_ESTR(start, "], rax\n"); break; } + case SUBTRACT: { + if (gi.args.length < 3) { + runtimeError(TOO_FEW_ARGS, "Expecting 2 args for subtract instruction", &gi, i); + } + if (gi.args.length > 3) { + runtimeError(TOO_MANY_ARGS, "Expecting 2 args for subtract 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, " ; subtract\n"); + APPEND_ESTR(start, " mov rax, "); + APPEND_ESTR(start, processValueString(gi.args.args[0])); + APPEND_ESTR(start, "\n"); + APPEND_ESTR(start, " sub rax, "); + APPEND_ESTR(start, processValueString(gi.args.args[1])); + APPEND_ESTR(start, "\n"); + APPEND_ESTR(start, " mov ["); + APPEND_ESTR(start, varName); + APPEND_ESTR(start, "], rax\n"); + break; + } + case MULTIPLY: { + if (gi.args.length < 3) { + runtimeError(TOO_FEW_ARGS, "Expecting 2 args for multiply instruction", &gi, i); + } + if (gi.args.length > 3) { + runtimeError(TOO_MANY_ARGS, "Expecting 2 args for multiply 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, " ; add\n"); + APPEND_ESTR(start, " mov rax, "); + APPEND_ESTR(start, processValueString(gi.args.args[0])); + APPEND_ESTR(start, "\n"); + APPEND_ESTR(start, " imul rax, "); + APPEND_ESTR(start, processValueString(gi.args.args[1])); + APPEND_ESTR(start, "\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);