mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-01-23 10:30:16 +00:00
Update docs.
This commit is contained in:
parent
8d6e5e090d
commit
21a187a105
@ -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
|
||||
|
139
README.md
139
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
|
||||
|
8
TODO.md
8
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user