Tree @construct-callgraph (Download .tar.gz)
README.md @construct-callgraph — view markup · raw · history · blame
Version 0.21. Work-in-progress, everything is subject to change.
SixtyPical is a low-level programming language supporting a sophisticated static analysis. Its reference compiler can generate efficient code for several 6502-based target platforms while catching many common mistakes at compile-time, reducing the time spent in debugging.
Make sure you have Python (2.7 or 3.5+) installed. Then
clone this repository and put its
bin directory on your
executable search path. Then you can run:
If you have the VICE emulator suite installed, you can run
sixtypical --run-on=x64 eg/c64/hearts.60p
and it will compile the hearts.60p source code and
automatically start it in the
x64 emulator, and you should see:
You can try
sixtypical --run-on on other sources in the
tree, which contains more extensive examples, including an entire
game(-like program); see eg/README.md for a listing.
SixtyPical aims to fill this niche:
- You'd use assembly, but you don't want to spend hours debugging (say) a memory overrun that happened because of a ridiculous silly error.
- You'd use C or some other "high-level" language, but you don't want the extra overhead added by the compiler to manage the stack and registers.
SixtyPical gives the programmer a coding regimen on par with assembly language in terms of size and hands-on-ness, but also able to catch many ridiculous silly errors at compile time.
Many of SixtyPical's primitive instructions resemble those of the MOS Technology 6502 — it is in fact intended to be compiled to 6502 machine code. However, it also provides some "higher-level" operations based on common 8-bit machine-language programming idioms, including
- copying values from one register to another (via a third register when there are no underlying instructions that directly support it)
- copying, adding, and comparing 16-bit values (done in two steps)
- explicit tail calls
- indirect subroutine calls
While a programmer will find these constructs convenient, their inclusion in the language is primarily to make programs easier to analyze.
- you forgot to clear carry before adding something to the accumulator
- a subroutine that you called trashes a register you thought it preserved
- you tried to read or write a byte beyond the end of a byte array
- you tried to write the address of something that was not a routine, to a jump vector
Unlike most conventional languages, in SixtyPical the programmer must manage memory very explicitly, selecting the registers and memory locations to store each piece of data in. So, unlike a C compiler such as cc65, a SixtyPical compiler doesn't need to generate code to handle calling conventions or register allocation. This results in smaller (and thus faster) programs.
The flagship demo, a minigame for the Commodore 64, compiles to
The reference implementation can analyze and compile SixtyPical programs to 6502 machine code formats which can run on several 6502-based 8-bit architectures:
For example programs for each of these, see eg/README.md.
SixtyPical is defined by a specification document, a set of test cases, and a reference implementation written in Python.
- SixtyPical specification
- Literate test suite for SixtyPical syntax
- Literate test suite for SixtyPical analysis (operations)
- Literate test suite for SixtyPical analysis (storage)
- Literate test suite for SixtyPical analysis (control flow)
- Literate test suite for SixtyPical compilation
- Literate test suite for SixtyPical fallthru optimization