We wrote a Ghost in assembly (using a very thin assembler to have named labels and simple constants).
For the Lambda-man IA, we wrote a compilator from OCaml to the List
machine. Specifically, we use the OCaml compiler API to get the
"lambda" representation (just after type-checking, inspectable with
ocamlc -dlambda -c foo.ml
on any OCaml sourcefile) to the lisp machine.
We then wrote the Lambda-man IA using OCaml, in the subset that our compiler supports (more on this in the "# Compiler limitations" section). The IA is rather simple.
PS: We spent quite a few hours implementing a simulator (interpreters for Gcc and Ghc, and game rules engine), but we couldn't make much use of it in the end. Time would have been better spent experimenting with the Javascript API directly.
The ghost (readable) assembly are in: solution-source/genius.g solution-source/genius2.g
The lambda-man source is: solution-source/graph_local.ml
We use
In code/
gcc/ contains compiler ./ocamlgcc.native from OCaml (minus records, references, exceptions) to gcc. « make » compiles it.
mlia/ is the IA of lambda man written in OCaml. In this directory do ../gcc/ocamlgcc.native « an_ia.ml » --print --no-exec to get some gcc code
ghc/ contains an assembler ./asm.byte of ghc. « make » compiles it.
ghosts/*.g contains the assembly of our ghost IA. It must go though ../ghc/asm.byte « an_ia.g » to give correct ghc code.
At top-level you can try ocamlbuild -use-ocamlfind main.native to get our not working own game simulator (you’ll need « cmdliner » to compile it)
We wish tuples to be represented exactly as in the Lisp machines, to use the data passed by the game without an axiomatic FFI layer.
For this purpose we had to disallow sum types with (strictly) more than one non-constant constructor. This is in fact not problematic, as any such variant can be turned into a sigma-type using a GADT:
type t = | A | B | Foo of t | Bar of u
can be turned into
type t = T : 'a tag * 'a and 'a tag = | A : unit tag | B : unit tag | Foo : t tag | Bar : u tag
This change is by design (we can neglect the tag of non-constant constructors, giving a lisp representation of (a, b) as (a . b) instead of (0 . (a . b)) with the 0 constructor).
Other limitations are due to a lack of implementation time: