/latte-compiler

Primary LanguageClojureEclipse Public License 1.0EPL-1.0

latte-compiler

A Clojure x86 compiler of an extended version of Latte programming language NOTE: though published (and 1.0'd), the project is far from done. As my first serious-ish Clojure project, the style is, well, bad. I am, however, working on improving it.

Circle CI

Table of Contents generated with DocToc

TODOs:

  • ordering of helper functions by purpose would be nice
  • intermediate representation of compiled code
  • peephole optimization using the former
  • registries mgmt
  • inlining computations (with overflows, proper modulo etc)
  • inlein for shorter startup (after evaluation)
  • TBDs

Extensions

Following extensions have been implemented:

  • arrays with a basic for statement ( for ( int a : array) )
  • arrays are initialized with 0/false for ints and booleans, for all others they're filled up with nulls
  • classes with single extensions (with virtual methods)
  • every class method is considered virtual
  • global functions are prioritized over instance methods
  • self refers to instance inside instance method (and IS assignable, effective in-scope only)
  • overrides' of methods arguments need to be not-lower in class hierarchy than originals (except for the class object itself), reverse for return types; i.e. if class A extends B and class C has a method B doSomething(A thing), then class D extends C may overwrite it with a method A doSomething(B thing)
  • only implicit type casts are allowed, except for null, which has to be cast explicitly

Usage

After calling make the latc_x86, latc and latc_drip binaries are ready to use. Calling latc_x86 foo/bar/baz.lat (or latc foo/bar/baz.lat, or latc_drip foo/bar/baz.lat) will, should code compile, create files baz.s (x86 assembly code) and baz (the executable) in the foo/bar directory.

Works with UNIX line endings only.

3rd party libraries

Project utilizes Leiningen (script provided in lib/) to manage dependencies (requires Internet connection!) Also, since Clojure's really slowing down JVM start time (all core namespaces need to be loaded, which slows down the compilator), drip is provided to be used (optionally, through latc_drip or setting LATC_DRIP_ENABLED envvar to 1). The dependencies include

catalogue structure

  • resources - Clojure resources dir, contains the grammar
  • src - sources (src/latte_compiler - Clojure sources, src/utils.c - helper functions library)
  • lib - directory containing leiningen & drip script
  • project.clj - leiningen config

Slow startup issue

Since Clojure core namespaces load on every execution, the JVM startup is really sluggish. Hence the latc_drip and latc_drip_cleanup binaries. They utilize drip, a small lib keeping the JVM running for another run, so that every second compilation does not have to load all namespaces (the JVM instance is killed after 30 minutes if not used). Note that every recompilation, kill and such may corrupt the classpath loader, and upon such the latc_drip_cleanup script should be called to fix that. latc_drip is to be used instead of latc or latc should be called with LATC_DRIP_ENABLED var set to 1. Note that while that approach is generally faster (up to 2x) for a number of consecutive runs, it may cause problems should the classpath be corrupted and as such, it may be worth to re-run compilation after cleanup or on regular JVM if compilation stalls/weird errors are thrown.