diff --git a/HISTORY.md b/HISTORY.md index 554a82c..5249b86 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -16,7 +16,7 @@ History of SixtyPical can also be given. * Accessing a `table` through a `pointer` must be done in the context of a `point ... into` block. This allows the - analyzer to check *which* table is being modified. + analyzer to check *which* table is being accessed. * Added `--dump-exit-contexts` option to `sixtypical`. 0.18 diff --git a/README.md b/README.md index fc947c1..1981aa2 100644 --- a/README.md +++ b/README.md @@ -1,60 +1,25 @@ SixtyPical ========== -_Version 0.18. Work-in-progress, everything is subject to change._ +_Version 0.19. Work-in-progress, everything is subject to change._ -**SixtyPical** is a low-level programming language with advanced -static analysis. Many of its primitive instructions resemble -those of the 6502 CPU — in fact it is intended to be compiled to -6502 machine code — but along with these instructions are -constructs which ease structuring and analyzing the code. The -language aims to fill this niche: +**SixtyPical** is a [very low-level](#very-low-level) programming language +supporting a [sophisticated static analysis](#sophisticated-static-analysis). -* 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, such as - -* 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 - -Many of these checks are done with _abstract interpretation_, where we -go through the program step by step, tracking not just the changes that -happen during a _specific_ execution of the program, but _sets_ of changes -that could _possibly_ happen in any run of the program. - -SixtyPical also provides some convenient operations based on -machine-language programming idioms, such as - -* copying values from one register to another (via a third register when - there are no underlying instructions that directly support it); this - includes 16-bit values, which are copied in two steps -* explicit tail calls -* indirect subroutine calls - -SixtyPical is defined by a specification document, a set of test cases, -and a reference implementation written in Python 2. The reference -implementation can analyze and compile SixtyPical programs to 6502 machine -code, which can be run on several 6502-based 8-bit architectures: - -* Commodore 64 -* Commodore VIC-20 -* Atari 2600 VCS -* Apple II +Its reference compiler can generate [efficient code](#efficient-code) for +[several 6502-based platforms](#target-platforms) while catching many +common mistakes at compile-time, reducing the time spent in debugging. Quick Start ----------- -If you have the [VICE][] emulator installed, from this directory, you can run +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 run: + + sixtypical + +If you have the [VICE][] emulator installed, you can run ./loadngo.sh c64 eg/c64/hearts.60p @@ -67,11 +32,80 @@ You can try the `loadngo.sh` script on other sources in the `eg` directory tree, which contains more extensive examples, including an entire game(-like program); see [eg/README.md](eg/README.md) for a listing. -[VICE]: http://vice-emu.sourceforge.net/ +Features +-------- + +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. + +### Very low level + +Many of SixtyPical's primitive instructions resemble +those of the 6502 CPU — in fact it is intended to be compiled to +6502 machine code — but along with these instructions are +constructs which ease structuring and analyzing the code. + +However, SixtyPical also does provide 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. + +### Sophisticated static analysis + +The language defines an [effect system][], and the reference +compiler [abstractly interprets][] the input program to check that +it conforms to it. It can detect common mistakes such as + +* 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 + +### Efficient code + +Unlike most languages, in SixtyPical the programmer must manage memory very +explicitly, selecting the registers and memory locations to store all data in. +So, unlike a C compiler such as [cc65][], a SixtyPical compiler doesn't need +to generate code to handle stack management or register spilling. This results +in smaller (and thus faster) programs. + +The flagship demo, a minigame for the Commodore 64, compiles to +a **930**-byte `.PRG` file. + +### Target platforms + +The reference implementation can analyze and compile SixtyPical programs to +6502 machine code formats which can run on several 6502-based 8-bit architectures: + +* [Commodore 64][] -- examples in [eg/c64/](eg/c64/) +* [Commodore VIC-20][] -- examples in [eg/vic20/](eg/vic20/) +* [Atari 2600][] -- examples in [eg/atari2600/](eg/atari2600/) +* [Apple II series][] -- examples in [eg/apple2/](eg/apple2/) Documentation ------------- +SixtyPical is defined by a specification document, a set of test cases, +and a reference implementation written in Python. + * [Design Goals](doc/Design%20Goals.md) * [SixtyPical specification](doc/SixtyPical.md) * [SixtyPical revision history](HISTORY.md) @@ -82,3 +116,10 @@ Documentation * [6502 Opcodes used/not used in SixtyPical](doc/6502%20Opcodes.md) * [Output formats supported by `sixtypical`](doc/Output%20Formats.md) * [TODO](TODO.md) + +[VICE]: http://vice-emu.sourceforge.net/ +[cc65]: https://cc65.github.io/ +[Commodore 64]: https://en.wikipedia.org/wiki/Commodore_64 +[Commodore VIC-20]: https://en.wikipedia.org/wiki/Commodore_VIC-20 +[Atari 2600]: https://en.wikipedia.org/wiki/Atari_2600 +[Apple II series]: https://en.wikipedia.org/wiki/Apple_II_series diff --git a/TODO.md b/TODO.md index f0b1a6c..7a0913d 100644 --- a/TODO.md +++ b/TODO.md @@ -29,6 +29,14 @@ inner block has finished -- even if there is no `call`.) These holes need to be plugged. +### Reset pointer in `point into` blocks + +We have `point into` blocks, but maybe the action when entering such a +block shouldn't always be to set the given pointer to the start of the given table. + +That is, sometimes we would like to start at some fixed offset. And +sometimes we want to (re)set the pointer, without closing and starting a new block. + ### Pointers associated globally with a table We have `point into` blocks, but we would also like to sometimes pass a pointer