diff --git a/README.md b/README.md index 7cd9ef5..e2a35bd 100644 --- a/README.md +++ b/README.md @@ -98,3 +98,14 @@ Commands: * eval (code): Runs Ground code in the current scope * help: Shows a help message +## Compiler + +CGround now includes an experimental Ground -> x86_64 Linux ASM compiler. You can try it by adding the `-c` flag when running Ground. This will print the generated ASM to the console. + +At present only the `int` data type is supported. + +Supported instructions so far: + +* set +* add +* end diff --git a/src/compiler.c b/src/compiler.c index d0bc121..49e725e 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -105,17 +105,10 @@ char* compileGroundProgram(GroundProgram* program) { } char* varName= gi.args.args[0].value.refName; - GroundValue val = gi.args.args[1].value.value; - if (val.type != INT) { - runtimeError(ARG_TYPE_MISMATCH, "For now only ints are supported", &gi, i); - } - - char valueStr[32]; - snprintf(valueStr, sizeof(valueStr), "%" PRId64, val.data.intVal); APPEND_ESTR(start, " ; set\n") APPEND_ESTR(start, " mov rax, "); - APPEND_ESTR(start, valueStr); + APPEND_ESTR(start, processValueString(gi.args.args[1])); APPEND_ESTR(start, "\n"); APPEND_ESTR(start, " mov ["); APPEND_ESTR(start, varName); @@ -123,6 +116,36 @@ char* compileGroundProgram(GroundProgram* program) { break; } + case ADD: { + if (gi.args.length < 3) { + runtimeError(TOO_FEW_ARGS, "Expecting 2 args for add instruction", &gi, i); + } + if (gi.args.length > 3) { + runtimeError(TOO_MANY_ARGS, "Expecting 2 args for add 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, " add 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);