Files
compiler-explorer/examples/sail/bitvectors.sail
Tim Hutt d1d0883a86 Add support for the Sail language (#7304)
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.


![image](https://github.com/user-attachments/assets/2f4fe12c-49b4-4b26-9cb0-7e1666a7b3a2)

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>
2025-04-17 17:22:18 -05:00

49 lines
1.4 KiB
Plaintext

default Order dec
$include <prelude.sail>
$include <vector.sail>
// Sail has excellent support for bit vectors. These have the type `bits(N)`.
let status : bits(32) = 0x11223344
// Bit vector literals are written 0x.. or 0b...
// Leading zeros are significant - the affect the size of the literal.
// This is ok:
register byte0 : bits(8) = 0x01
// This is an error:
// register byte1 : bits(8) = 0x1
function main() -> unit = {
// @ means concatenation. With 'default Order dec' concatenation is written
// in Big Endian order.
assert(0x12 @ 0x34 == 0x1234);
// Individual bits or ranges of bits can be accessed like this.
// Note that the range is inclusive.
assert(status[0] == bitzero);
assert(status[7 .. 0] == 0x44);
// You can update mutable bit vectors like this:
byte0[3 .. 0] = 0b1100;
// Or in immutable function style:
let byte2 = [
byte0 with
3 .. 0 = 0xA,
];
// You can convert a bit vector to a string with `bits_str()`. If it is
// a multiple of 4 bits it will be printed in hex, otherwise binary.
print_endline(bits_str(byte2[2 .. 0]));
// Pattern matching also supports bit vectors.
match byte2 {
upper @ 0b010 => {
print_endline(bits_str(upper));
},
0b10 @ lower => {
print_endline(bits_str(lower));
},
_ => (),
};
}