/clj-compiler-interpreter

Compiler & Interpreter for a few simple languages. Written in Clojure

Primary LanguageClojureEclipse Public License 1.0EPL-1.0

clj-compiler-interpreter

Compiler & Interpreter for a few simple languages. Written in Clojure for a Languages and Compilers course.

Usage

$ lein run

Authors

Kristoffer Ek

Vicent Dolz Martinez (Vicentico22)

Documenation

File structure

+-- src/
| +-- project/
| | +-- addMulCompiler.clj
| | +-- addMulInterpreter.clj
| | +-- addSubCompiler.clj
| | +-- addSubInterpreter.clj
| | +-- arithInterpreter.clj
| | +-- constCompiler.clj
| | +-- constInterpreter.clj
| | +-- core.clj
| | +-- lang0Compiler.clj
| | +-- lang0Interpreter.clj
| | +-- lang1Compiler.clj
| | +-- lang1Interpreter.clj
+-- doc/
+-- project.clj

Languages

  • ConstMod
  • AddSubMod
  • AddMultMod
  • ArithMod
  • ArithExpMod
  • Lang0Mod
  • Lang1Mod

Int -> Long

In order for us to handle big numbers we converted both the interpreter and the compiler to work with the primitive type Long instead of the initial type int. This meant we now parse all numbers in the AST as Longs, changing the method signature of the generated bytecode as well as the operation bytecodes (Opcodes/IADD -> Opcodes/LADD). Another thing we had to modify due to this was the handling of arguments since they were coded as int's and not as long's. Int's only take up one block in memory and long take up 2 blocks. We solved this by adding another increment to where the variable indexes (in local memory) are calculated.

Modulo

The methods for handling the modulo operation is located in constCompiler.clj as well as in constInterpreter.clj. In our language, the modulo operand is represented with a "%". Since the the language should be able to handle very big numbers(more than what long can represent) we choose to create a function called mod-exp to convert the numbers as biginteger and perform modulo on each number separately before we parse the full expresison.

Interpreter mod-parser, mod-interpreter, and mod-eval are the three methods responsible for interpreting the "%". The parser will transform it to the keyword :mod and it then evaluated by using clojure's mod function.

Compiler We use the Opcodes/LREM to perform the remainder, which it works like modulo for positive numbers. For the negatives we create a function called rem-sign which transform a negative result to the correct positive one.

Exponentials

We use a java method called modPow to calculate modulo of big numbers which we use before passing the expression to the parser. In the case of variable name management in the exponential expressions, we didn't succeed to implement it. One possible way to solve this is defining a function in bytecode for exponential calculus.