# Klang - The Kaiser language This is the project for Klang - the Kaiser language. # Authors This code was in equal parts developed by `Dennis Kaiser` and `Marvin Kaiser` at the RheinMain University of Applied Sciences for the Compilers course. # Usage Pass source code via stdin example call to print help `java -cp target/klang-1.0-jar-with-dependencies.jar de.hsrm.compiler.Klang.Klang -h` Arguments: - -h Print this help - --evaluate: Evaluates the given source code - --pretty: Pretty print the given source code - --no-compile: Do not compile the source code - --no-main: Do not generate main function, will be generated as 'start'. Useful for testing The makefile can be used to perform various functions more easily: - `make build` simply builds the compiler - `make clean` cleans up all generated output - `make` generates code.s from code.k in root folder - `make pretty` prettifies code.k and writes to pretty.k - `make eval` evaluates code.k - `make test` runs tests from src/test/ - `make cleanTests` cleans files generated from tests # Functionality The KLang compiler supports generation of AMD64 assembly code, as well as prettifying and evaluating the KLang code. ## Simple Expressions The following simple expressions are supported. Expressions need to be put in paranthesis. When using comparison operators, the expressions evaluate to 0 for false and 1 for true. - Addition (+) - Subtraction (-) - Multiplication (*) - Division (/) - Modulo (%) - Equality (==) - Less Than (<) - Less Than Or Equal (<=) - Greater Than (>) - Greater Than Or Equal (>=) - Number Negation (-) ### Examples: ``` (5 + 4) (8 % 2) (8 == 0) ``` ## Functions Functions can be defined and called. A function call can be used like any other expression. Recursion is supported ### Examples ``` function fun(x: int, y: int, z: bool): int { return x; } fun(1, 2, 3); ``` ## Statements Several statements are supported: - if - variable declaration - variable assignment - return - while - do while - for ### Examples ``` function example(x: int, y: int, z: int): int { let a: int; let b: int = 0; if (x == y) { a = y; } else if (x == z) { a = z; } else { return b; } return a; } function whileExample(end: int): int { let x: int = 0; while (x < end) { x = x + 1; } return x; } function doWhileExample(end: int): int { let x: int = 0; do { x = x + 1; } while(x < end); return x; } function forExample(end: int): int { let x: int = 0; for (let i: int = 0; i < end; i = i + 1) { x = x + 1; } return x; } ``` ## Tail Call Optimized Recursive tail calls are optimized at compile time. ## Statically typed KLang statically verifies the integrity of your code. These checks include: - Type checking - Ensuring that variables and functions in use are declared - Ensuring that the arguments of a function call match the function definition - Ensuring that a function returns something - Ensuring that a function only returns data of the correct type ### Data Types - Integer "int" - Boolean "bool" - Floats "float" ### Examples You can declare types for parameters, return values and variables ``` function foo(start: int): boolean { let threshold: int = 10; return threshold < start; } ``` Type annotations are required as per our parsing rules, so this will result in an error while parsing ``` function bar() { return 0; } ``` This will throw an error since a boolean is returned, but int is declared as the return type ``` function baz(): int { return false; } ``` This will throw an error since the function "bam" expects one argument but the call to this function provided none ``` function bam(a: int): int { return a; } bam(); ``` This will throw an error since the first parameter of function "boo" has to be of type bool ``` function boo(a: bool): bool { return a; } boo(100); ```