diff --git a/editors/micro_callisto.yaml b/editors/micro_callisto.yaml index e92e2c8..428a184 100644 --- a/editors/micro_callisto.yaml +++ b/editors/micro_callisto.yaml @@ -6,7 +6,7 @@ detect: rules: - statement: "\\b(func|end|begin|asm|include|inline|if|then|elseif|else|while|do)\\b" - statement: "\\b(let|enable|requires|struct|version|return|const|enum|restrict)\\b" - - statement: "\\b(continue|break|union|alias)\\b" + - statement: "\\b(continue|break|union|alias|overwrite|error)\\b" - type: "\\b(addr|void|u8|i8|u16|i16|u32|i32|u64|i64|size|usize|cell|array)\\b" - constant.string: diff --git a/examples/error.cal b/examples/error.cal new file mode 100644 index 0000000..0a82299 --- /dev/null +++ b/examples/error.cal @@ -0,0 +1,10 @@ +include "cores/select.cal" +include "std/io.cal" + +# will print Hello, world! on RM86, will error on Linux86 + +version Linux86 + error +end + +"Hello, world!" printlstr diff --git a/source/app.d b/source/app.d index ee91a56..a7796d7 100644 --- a/source/app.d +++ b/source/app.d @@ -27,6 +27,8 @@ Flags: -na - Disables the -a flag --version - Shows the callisto version -dp - Prints parser output + -es - Export all Callisto symbols (and add util functions for interacting + with the Callisto stack) Backends: rm86 - Real mode x86 and MS-DOS @@ -54,6 +56,7 @@ int main(string[] args) { CompilerBackend backend = new BackendLinux86(); bool doDebug; bool debugParser; + bool exportSymbols; for (size_t i = 1; i < args.length; ++ i) { if (args[i][0] == '-') { @@ -158,6 +161,10 @@ int main(string[] args) { debugParser = true; break; } + case "-es": { + exportSymbols = true; + break; + } default: { stderr.writefln("Unknown flag '%s'", args[i]); return 1; @@ -190,11 +197,12 @@ int main(string[] args) { return 0; } - auto compiler = new Compiler(); - compiler.backend = backend; - compiler.backend.org = org; - compiler.backend.orgSet = orgSet; - compiler.backend.useDebug = doDebug; + auto compiler = new Compiler(); + compiler.backend = backend; + compiler.backend.org = org; + compiler.backend.orgSet = orgSet; + compiler.backend.useDebug = doDebug; + compiler.backend.exportSymbols = exportSymbols; versions ~= compiler.backend.GetVersions(); diff --git a/source/backends/linux86.d b/source/backends/linux86.d index aecca9b..f601c33 100644 --- a/source/backends/linux86.d +++ b/source/backends/linux86.d @@ -160,6 +160,21 @@ class BackendLinux86 : CompilerBackend { // copy static array constants output ~= "call __copy_arrays\n"; + // create functions for interop + if (exportSymbols) { + output ~= " + global cal_push + cal_push: + mov [r15], rdi + add r15, 8 + ret + cal_pop: + sub r15, 8 + mov rax, [r15] + ret + "; + } + // jump to main output ~= "jmp __calmain\n"; } @@ -186,10 +201,18 @@ class BackendLinux86 : CompilerBackend { foreach (name, var ; globals) { output ~= format("__global_%s: resb %d\n", name.Sanitise(), var.Size()); + + if (exportSymbols) { + output ~= format("global __global_%s\n", name.Sanitise()); + } } foreach (i, ref array ; arrays) { output ~= format("__array_%d: resb %d\n", i, array.Size()); + + if (exportSymbols) { + output ~= format("global __array_%d\n", i); + } } // create array source @@ -280,6 +303,10 @@ class BackendLinux86 : CompilerBackend { words[node.name] = Word(false, []); + if (exportSymbols) { + output ~= format("global __func__%s\n", node.name.Sanitise()); + } + output ~= format("__func__%s:\n", node.name.Sanitise()); foreach (ref inode ; node.nodes) { diff --git a/source/compiler.d b/source/compiler.d index 459c521..25371e6 100644 --- a/source/compiler.d +++ b/source/compiler.d @@ -16,6 +16,7 @@ class CompilerBackend { bool orgSet; Compiler compiler; bool useDebug; + bool exportSymbols; abstract string[] GetVersions(); abstract string[] FinalCommands(); @@ -80,6 +81,7 @@ class Compiler { case "return": backend.CompileReturn(node); break; case "continue": backend.CompileContinue(node); break; case "break": backend.CompileBreak(node); break; + case "error": backend.Error(node.error, "Error thrown by code"); break; default: backend.CompileWord(node); } break;