This report summarizes the Boppi language and default implementation. It describes the features of the languages both in terms of usage and in terms of formal requirements. The Java implementation of the compiler chain is elaborated as well as the standard libraries written in ILOC. Together with the discussion of problems encountered during the project, these give a thorough insight into the process of making this project and the end result.\\
Boppi features a basic expression language, variables, closures and arrays. The addition of closures added a lot of value to both Boppi and the understanding of programming languages. Moreover, together with string (character array) input and output, the language can be used for rudimentary programs.

\section{Future work}
\label{future-work}
The compiler can be improved by separating ANTLR's abstract syntax tree from type checking and code generation. For the latter this reduces code duplication and allows more insight into what data is necessary for a set of instructions. Because tree rewriting is not possible in ANTLR 4, this seems to be the optimal way. The binary size can also be improved by combining jump targets, by not generating unreachable code and by jumping to functional instructions rather than generating NOP instructions. The last may be accomplished by annotating the AST with the entry point of a node.\\

Furthermore, the compiler can be improved by separating call frames from their closure. While closures are in general a graph, call frames always form a stack. Keeping the call frames on the stack may improve readability of the Java code and the ILOC code and state of the machine while debugging.\\

The language can be improved with type inference, notably using the Hindley-Milner (\emph{HM}) type system. The inference mechanism for HM runs in linear time and is relatively easy to implement, especially with the \verb|checkConstraint| method already in place. However, it requires the implementation of variables on the type level. Moreover, it has to give meaningful errors if a unification fails or if free types are left after checking. This feature goes hand in hand with polymorphism because of these type variables.\\

The language can be improved with polymorphism. This could be done best by boxing all values by default and only unboxing (primitive) values through an optimization pass. Moreover, it would be good practice to include type information during runtime to support polymorphic recursion and to simplify code generation for all forms of polymorphism.\\

The garbage collector can be improved by checking for cycles in references. A function reference and its enclosing function reference each other, so they may continue to exist after the enclosing function has ended even after nothing can access the function's local variables. One approach is to periodically recursively iterate over all references starting at the global scope marking them all, then for each object in memory delete it if it is unmarked or simply unmark it if it was marked. (\emph{tracing garbage collector}) If most references are non-circular, it makes sense to use both the current garbage collector and a tracing garbage collector side by side.\\

Moreover, the deallocation of reference types (both variables and closures) ought to be implemented as a small subroutine rather than as inlined code at every occurence. This would improve the size of the binary and improve the correctness of the garbage collection. Currently, the garbage collector can either leak memory and handle closures correctly, or it can eagerly deallocate memory and break closures. Also, the garbage collector does not collect refernce types within arrays.\\

Lastly, the \emph{memlib} can be improved by adding the ability to change the \verb|brk| value dynamically. Or, when there is too little memory available, to signal the VM to resize the memory and retry allocating. Also, the library can be improved by providing a reallocation and a copy function.
