mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 09:23:52 -05:00
This adds support for the [Sail language](https://github.com/rems-project/sail) - a DSL for defining ISAs. It's not quite ready but I need some help. These are the main remaining issues: 1. When you "link to binary" it does disassemble the binary properly, but the syntax highlighting and line numbers are broken.  2. If you try to execute the code without a `function main() -> unit = ...` then it gives this error in the compiler output: ``` Internal Compiler Explorer error: Error: spawn /tmp/compiler-explorer-compiler2025025-31052-c8gern.pf8t/model.c EACCES at ChildProcess._handle.onexit (node:internal/child_process:285:19) at onErrorNT (node:internal/child_process:483:16) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) Compiler returned: -1 ``` This is weird - it should give a linker with an undefined reference to `zmain`. 3. Sail compiles to C, and then I added extra steps to compile that to binary (if you select `Execute the code`), but as you can see I had to move the binary back over the C file, so in this case `model.c` is actually an ELF file. It works but that seems very weird. There is a `getExecutableFilename()` method I could override, but doing that seems to make it even more confused. 4. I also had to have a fake flag for `binary` because the `filters` don't seem to get set correctly when passed to `runCompiler()`. E.g. `buildExecutable()` doesn't pass them at all. Not sure what is going on there. Seems to work though. Any help appreciated! PS: Sail is a cool language. It has lightweight dependent type for integers and bit vectors, which I haven't demonstrated in the examples yet, but they're neat. --------- Co-authored-by: Matt Godbolt <matt@godbolt.org>
53 lines
1.3 KiB
Plaintext
53 lines
1.3 KiB
Plaintext
default Order dec
|
|
|
|
$include <option.sail>
|
|
$include <string.sail>
|
|
|
|
// Sail has pattern matching similar to Rust, OCaml and other functional languages.
|
|
// A notable difference is that it doesn't support combining identical branches.
|
|
|
|
function suit_name(suit : range(0, 3)) -> string =
|
|
match suit {
|
|
0 => "hearts",
|
|
1 => "diamonds",
|
|
2 => "clubs",
|
|
3 => "spaces",
|
|
}
|
|
|
|
// _ is a wildcard
|
|
|
|
function map_add(a : option(int), b : option(int)) -> option(int) =
|
|
match (a, b) {
|
|
(Some(a), Some(b)) => Some(a + b),
|
|
_ => None(),
|
|
}
|
|
|
|
// Sail copies a minor footgun from other functional languages.
|
|
|
|
function ordinal(x : nat) -> string =
|
|
match x {
|
|
0 => "zeroth",
|
|
1 => "first",
|
|
2 => "second",
|
|
3 => "third",
|
|
other => concat_str(dec_str(other), "th"),
|
|
}
|
|
|
|
// Here `other` creates a new variable bound to `x`.
|
|
// Unfortunately it can catch you out. The following code appears correct and
|
|
// will compile (with warnings), but actually the function always returns 2.
|
|
// Rust and OCaml also suffer from this flaw.
|
|
|
|
let ONE = 1
|
|
let TWO = 2
|
|
let THREE = 3
|
|
|
|
function add_one(x : range(1, 3)) -> range(2, 4) =
|
|
match x {
|
|
ONE => 2,
|
|
TWO => 3,
|
|
THREE => 4,
|
|
}
|
|
|
|
function main() -> unit = ()
|