23

A Pascal compiler in Haskell that compiles to LLVM

 4 years ago
source link: https://github.com/sam46/Paskell
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Paskell

A (reduced) Pascal compiler in Haskell that compiles to LLVM

Features

  • Declarations: var, type (aliases)
  • Types: integer, boolean, string, char, real
  • Control Flow: if, while, for
  • Functions/Procedures
  • Pass by reference
  • Basic Typecasting
  • Nested Functions/Procedures (Not finished yet)
  • I/O: Write/Writeln

Progress

Usage

Once the executable is built, it can be used to compile Pascal source files to llvm-ir, or internal IR used by the compiler:

paskell -c src compile to llvm-ir

paskell -c src dest compile to llvm-ir and save in dest

paskell -ir src produce internal IR

paskell -x src execute pascal source. Equivalent to paskell -c src | lli

paskell -h (for help)

Demo:

The compiler is complemented with the llvm utilities

$ paskell -c fib.pas fib.ll

Since the output is llvm-ir, we can leverage the many tools LLVM provide to:

  • execute it using the llvm interpreter
    $ lli fib.ll
  • convert it to bitcode llvm assembly (.bc)
    $ llvm-as fib.ll -o fib.bc
  • optimize the code using various settings, for example
    $ opt -mem2reg fib.bc
  • translate it to a native assembly executable of a specific architecture (x86, ARM, etc)
    $ llc -march=x86-64 fib.bc -o fib.s
  • link many modules into one program

Building

With docker

$ make bash

to build the compiler and launch a shell session where the compiler and llvm utitlies are in $PATH and ready out-of-the-box.

Alternatively

$ make build

will build the same image tagged paskell which can be used with docker run and volumes. For example:

$ docker run -v /path/to/original_file.pas:/path/to/file.pas paskell paskell -c /path/to/file.pas

Without docker

You need to have llvm installed

$ sudo apt-get install llvm-5.0

lli should be in $PATH to be able to execute Pascal programs

Then, you can use Cabal or Stack.

To build using Cabal:

$ cd Paskell/
$ cabal install -j

this will install all dependencies and produce an executable in dist/build/Paskell/

You can also build using Stack.

Tests

$ make test

to run the test suite using docker.

Implementation

This is a 4-pass compiler:

pass 1: lex/parsing

pass 2: type checking

pass 3: constructing IR: type-annotation, type resolution, (future: identifier-renaming, nested-function extraction)

pass 4: code generation

TODO

  • finish nested functions/procedures:
    this only requires pulling nested functions to global scope
    and renaming them during the type-annotation pass
  • constants: trivial to implement
  • Read/Readln IO statements
  • records
  • arrays
  • case statements
  • forward declaration

Contributions

Bug reports, added features, etc are welcome

References


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK