diff --git a/README.md b/README.md index 389f882..9aad1e8 100644 --- a/README.md +++ b/README.md @@ -114,4 +114,7 @@ Supported instructions so far: * inequal * greater * lesser +* jump +* if +* @ (label creation) * end diff --git a/src/compiler.c b/src/compiler.c index 84fac2e..8e31730 100644 --- a/src/compiler.c +++ b/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);