A compiler written in Haskell for the CSC-312 course at Grinnell College during the Spring 2018 semester.
Currently, GrinHC supports only the following grammar:
d ::= data x = [| ci x1 x2 x3 ...]
e ::= n | (e) | e1 + e2 | e1 - e2 | e1 * e2 | e1 / e2
| e1 % e2 | true | false | e1 <= e2 | e1 == e2
| e1 >= e2 | e1 < e2 | e1 > e2 | if e1 then e2 else e3
| f | NaN | x | let x :: t = e1 in e2 | lambda (x::t1)::t2 => e
| fix f (x::t1)::t2 => e | e1 e2 | () | (e1, e2) | fst e | snd e
| [] :: t | e1:e2 | head e | tail e | empty e
| ref e | e1 := e2 | !e | e1 ; e2 | while e1 do e2 end
| case e of [pi -> ( ei )] end
t ::= Int | Bool | Float | Unit | t1 -> t2 | (t1, t2) | [t] | <t> | D
p ::= (x1,x2) | C x1 x2 x3 ...
where n
is an integer literal, x
is a variable identifier of the form
[a-z][a-z A-Z 0-9 ' _]+
f
is a floating point literal of the form
[0-9]+.[0-9]+
and NaN
as defined in IEEE 754.
D
is the type of a ADT declaration
d
is a declaration which currently only supports abstract data type declarations.
p
is a pattern which is a matching over pairs and abstract data types. Lists are forthcoming.
If stack
is not already installed on your system you can install it using:
$ curl -sSL https://get.haskellstack.org/ | sh
If running GNU/Linux you could alternatively install stack
using the package manager associated with your distribution (e.g. pacman
for ArchLinux).
For additional directions on obtaining stack
, see here.
GrinHC makes use of a Haskell linter called hlint
. To install this program using stack, run,
$ stack install hlint
To enable pre-commit hooks, run the following command from the root of the project repository,
$ cd .git/hooks && ln -s ../../githooks/pre-commit
This should enable a git pre-commit hook which will run hlint
on all the source files as well as run the test suite automatically.
The first time you clone the repository, you must run:
$ stack setup
To build the project thereafter:
$ stack build
You may need to run
$ stack init
if prompted to do so by stack. This will initialize the project according to your machine.
To run GrinHC command line arguments:
$ stack exec GrinHC -- foo bar baz
Note: To pass command line arguments to GrinHC instead of stack
the double --
are necessary.
To run the testing suite for GrinHC, run:
$ stack test
- Added ability to declare and instantiate custom algebraic data types
- Added pattern matching over pairs and algebraic data types
- Added a new type,
D
, which signifies the type of an algebraic data type namedD
whereD
is any uppercase identifier - Expanded test suite to test invocations of algebraic data types and pattern matching over pairs and algebraic data types
- Pattern matching over lists does not work correctly right now unless you create a
Lst
algebraic data type
- Added the concept of an environment to keep track of
ref
s (aka state eww). - Augmented the grammar with while loops, sequencing (
e1 ; e2
), stateful assignment (e1 := e2
) and dereferencing (!e
)
- Added a new type,
<t>
which signifies that a variable is aref
and thus is stateful - Expanded test suite to test
ref
s, sequencing, and while loops.
- None
- Added a typechecking phase which executes before evaluation occurs and will print an error message if there is a type error
- Add
()
(unit) language feature to grammar - Add pairs to grammar
- Add lists to grammar
- Expanded test suite to include tests for
()
, pairs, lists, and typechecking - Fixed bug which was required disambiguating parentheses with function application
- None
- Can now define functions, both recursive and not, let-bindings, and function applications
- Added
--step
command line argument to print out all of the evaluation steps - Added
%
,<
,>
,==
, and>=
operators
- Transitioned from Big-Step evaluation to Small-Step evaluation
- Expanded test suite to include tests for new operators, functions, and let-bindings
stack test
will also now test whether the steps taken during evaluation are correct
- Given an expression of the form
5 * f 3
wheref
is a function the parser currently builds the following AST,(5 * f) 3
instead of the correct AST,5 * (f 3)
. As a result, failure to include disambiguating parentheses will result in an evaluation error.
- Error messages new report position information (line,column)
generate_baselines.sh
script added to, well, generate baselines automatically
- Alex and Happy are used instead of a hand-rolled lexer and parser
- Grammar changed from prefix to infix
<=
is non-associative and thus binds the loosest.+
and-
are left-associative and binds tighter than<=
*
and/
are left-associative and binds the tightest of all operations currently in the grammar
- Test suite upgraded
- Tests updated to test infix grammar
stack test
will now test lexing and parsing components of GrinHC as well as evaluation
- None
- Add ability lex and parse basic S-Expressions in a LISP style syntax
- Ability to read in file with code return evaluated code
- Intepret S-Expressions with arithmetic operations, booleans, and floats
- Augment testing suite with tests that cover entire grammar
- Remove
--length
command line option - Remove ability to print command line arguments given back to the user
- Remove old testing suite which tested old features
- None
- Created the project
- Parse command line arguments and spit them back to
stdout
- Add
--length
argument to print out the length of each argument instead - Add infrastructure for testing suite
- Add a git-precommit hook to automatically run
hlint
on all*.hs
files within the project as well as run the test suite.
- N/A
- None