https://github.com/fgeller/gcc
https://github.com/fgeller/gcc
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/fgeller/gcc
- Owner: fgeller
- Created: 2014-07-28T11:52:18.000Z (almost 12 years ago)
- Default Branch: master
- Last Pushed: 2014-08-10T05:51:01.000Z (almost 12 years ago)
- Last Synced: 2023-03-12T04:48:17.204Z (over 3 years ago)
- Language: Clojure
- Size: 215 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# gcc
Small compiler for the other MLISP down to GCC written in Clojure.
Main approach:
1. Use the reader to parse a set of given files into an S-Expression AST.
2. Convert the AST for all top-level `defun`s into GCC instructions with relative and absolute references.
3. Concatenate all instructions, moving a defun with name `main` to the front if given.
4. Replace references with line numbers.
5. Write output to file and STDOUT.
## Implementation details
The main mapping from MLISP to GCC happens in `compile-sexp-to-gcc` based on a big
`cond` statement. Given that the assembly has so support for LISPy
functionality, the mapping from our MLISP to GCC is mostly straight-forward.
There is support for the main primitives `CEQ`, `CGT`, `CGTE`, `CONS`, `CAR`,
`CDR`, `ADD`, `SUB`, `MUL`, `DIV`, `ATOM`, `DBUG`, `BRK` and `true`, `false` and
`nil` are mapped to the respective constants. It adds a couple if built-in
functions with varargs for convenience:
```lisp
(mklist 1 1 2 3 5)
(mktuple 8 13 21 34 55)
```
gcc attempts to find tail calls and produces the respective `TSEL` and `TAP`
instructions automatically.
`defun`, `lambda` and `let` support multiple forms in their bodies.
`let` is implemented via a translation to lambda applications.
## MLISP examples
The top-level defuns are wrapped in a pair of parenthesis for parsing.
```lisp
(
(defun add (lhs rhs) (+ lhs rhs))
)
```
Or more interestingly:
```lisp
(
(defun fold-left (lst acc fun)
(if (atom? lst)
acc
(fold-left (cdr lst)
(fun acc (car lst))
fun)))
(defun reverse (lst)
(fold-left lst nil (lambda (acc next)
(cons next acc))))
)
```
Which compiles to:
LD 0 1 ; $lambda-1
LD 0 0
CONS
RTN
LD 0 0 ; reverse
LDC 0
LDF 0
LDF 10
AP 3
RTN
LD 0 0 ; fold-left
ATOM
TSEL 13 15
LD 0 1
RTN
LD 0 0
CDR
LD 0 1
LD 0 0
CAR
LD 0 2
AP 2
LD 0 2
LDF 10
TAP 3
## Usage
You'll need [leiningen](http://leiningen.org/) to build or run gcc.
Command line:
$ lein uberjar
$ java -jar $PWD/target/gcc-0.1.0-SNAPSHOT-standalone.jar $INPUTFILE1 $INPUTFILE2
Interactively:
$ lein repl
> (use 'gcc.core)
> (gcc '((defun x () 23)))
Run tests for hacking:
$ lein repl
> (use 'midje.repl)
> (autotest)
## License
No restrictions.
This was written for the very fun ICFP Contest 2014, if this can be of any help to you -- happy hacking!