Here's a link to the online compiler playground!
- Community
- What is Sage?
- Why Sage?
- How useful is Sage?
- How do I use Sage?
- What does Sage look like?
- Feature Roadmap
- Where can I learn more?
- How do I contribute?
- About the Author
Join the Discord server to chat about Sage! Let us know if you have any thoughts or comments about the language!
Sage is a programming language that tries to be maximally portable, expressive, and intuitive. It borrows some aspects of Rust, C, and Python. It currently has an x86 compiler backend, a C source backend, and a VM interpreter backend which can run on the web.
Sage is licensed under the MIT License, and has been under development since April 2022.
Sage is very portable -- run it on your thermostat! Here's the complete list of core virtual machine instructions and their C equivalents:
Instruction | C Equivalent |
---|---|
while |
while (reg) { |
if |
if (reg) { |
else |
} else { |
end |
} |
set N |
reg = N; |
call |
funs[reg](); |
ret |
return; |
save |
*tape_ptr = reg; |
res |
reg = *tape_ptr; |
move N |
tape_ptr += N; |
where |
reg = tape_ptr; |
deref |
push(tape_ptr); tape_ptr = *tape_ptr; |
refer |
tape_ptr = pop(); |
index |
reg = (cell*)(reg) + *tape_ptr; |
add |
reg += *tape_ptr; |
sub |
reg -= *tape_ptr; |
mul |
reg *= *tape_ptr; |
div |
reg /= *tape_ptr; |
rem |
reg %= *tape_ptr; |
nand |
reg = ~(reg & *tape_ptr); |
gez |
reg = reg >= 0; |
You could fit this instruction set on a T-shirt!
The compiler can target this limited "core" instruction set, with an expanded "standard" instruction set for floating point operations and foreign functions. The core instruction set is designed to be as simple as possible for anyone to implement their own backend. Try to see if you can implement it yourself for your backend of choice!
The virtual machine has some important optimization properties: Although Sage's VM is a very simple zero-address-code representation, it preserves all the information to reconstruct an LLVM-like three-address-code representation of the original higher level IR. This makes the instruction set capable of applying LLVM's optimizations while being much easier to implement. Sage's innovation is in the backend, not the frontend.
This combination of simplicity and capacity for optimization was my motivation for creating Sage. I wanted to create a virtual machine with the largest speed + expression + portability to implementation difficulty ratio, and a high level language that could compile to it. I think Sage is a good solution to this problem.
This project is based on some ideas I had while working on Harbor for a hackathon.
Sage is a very young project, and is not ready for production. It's still possible to write very useful programs in it, though.
SageOS is an operating system with a userspace written in Sage. Its graphical shell and presentation app (both written in Sage) use the FFI to draw to the screen, receive input from the mouse and keyboard, interact with the filesystem, and schedule new processes. You can look at the shell code here.
The presentation app parses PPM image files from the filesystem and renders them to the screen. You can look at the presentation code here.
Sage's foreign function interface is simple and can directly call C functions or backend-specific builtins. Check out the web-demo's foreign function interface example that calls some JavaScript code to draw graphics or alert the user!
To start using sage, install it with cargo:
$ cargo install --git https://github.com/adam-mcdaniel/sage
Then, you can run a sage file with the sage
command:
$ sage examples/frontend/interactive-calculator.sg
You can also compile a sage file to C with the --target
flag:
$ sage examples/frontend/interactive-calculator.sg --target c
$ # Or `-t c` for short
$ sage examples/frontend/interactive-calculator.sg -tc
$ gcc out.c -o out
$ ./out
Check out the code for the web-demo to see how to use Sage in a web page.
Here's an example of a polymorphic linked list in Sage using Rust-like enum
s! It's straightforward to implement operations like map
with just a few lines.
Here's an example of Sage's structural typing: a Rectangle
can be created by concatenating the fields of a Position
and a Size
!
Here's an example of Sage's pattern matching: it's easy to deconstruct a value using match
, if let
, or a simple let
binding. Sage's match
expressions are very powerful!
Go to the web-demo or the examples/frontend folder to see more code examples.
- Compiler Backends
- SIMD vector instruction support
- Static variables and constant expressions
- Conditional compilation
- Polymorphic functions
- Mutability checks
- Rust-like
enum
s - Pattern
match
ing - Structural typing
- Associated constants and methods
- Recursive polymorphic types
- Iterators and list/vector/array comprehensions
- Hindley-Milner type inference
- VSCode extension (syntax highlighting, code completion, etc.)
- Typeclasses
-
no-std
implementation of compiler - Modules
- A standard library
- Type Reflection Module
- Collections Module
- Networking Module
- Filesystem Module
- Graphics Module
- Audio Module
- GUI Module
- WebAssembly Module
- Foreign Function Interface Module (create backend with
.toml
file) - Memory Management Module
- Better frontend parser (switch to Nom?)
- A package manager
- AST Macros
- C frontend (compile C to Sage VM)
- Self-hosting implementation
You can read my blog post (~20 minute read) about the programming language to learn more about the implementation!
Join the Discord server to chat about Sage!
If you want to contribute, you can open an issue or a pull request. Adding backends for other architectures is a great way to contribute! We also need a VSCode syntax highlighting extension!
I'm a 21 year old computer science graduate student at the University of Tennessee, Knoxville🍊. Rust is my favorite language, and I've written many other compilers. This is the last project I started as a teenager, and I was the only author to touch any of the code up to version v0.0.2-alpha
(12/25/2023)! I'm looking for work opportunities for Summer 2024 (after I finish my Masters degree), so if you're interested in hiring me, please reach out to me at amcdan23@vols.utk.edu!