This project has been put on hold. The work ended at implementing different kinds of arrays.
I'm using Swift because I feel comfortable with it. This is my very first experience in compiler development, therefore, I'm not taking any criticism and not reading any tutorials.
I want to stumble into as many mistakes and problems as I can, and solve them on my own.
- use LLVM to parse manually-written IR (part 1)
- generate IR from some manually written and pre-typed AST
- develop lexer (tokenizer)
- parse code into AST
- hook up to IR generation
- second pass type inference
- testing AST and IR generation
- IR generation for more complicated things (part 2)
- static analyzer (all paths return a value, unused values)
Declaration
a : Int = 0; // variable
b : Float : 0.1; // constant
a := 1; // variable
b :: 2; // constant
Pointer type
a := 3;
b := *a; // *Int
Procedure declaration
func printf(_ format: String, _ arguments: Int32, ...) #foreign;
func entry_point() -> Int32 #main { ... }
Array Literals
a : Int[3] = [0, 1, 2];
b : Float[3] = [0, 1, 2]
c := [0, 1, 2] // Int[3]
d := [0.1, 1, 2] // Float[3]
enum Values { A, B, C };
value := Values.A;
name := switch (value) {
case A: #provide "A";
case B: #provide "B";
case C: #provide "C";
}
description := if (name == Values.B) {
#provide "The name is B."
}
else {
#provide "The name is not B."
}
// name == "A"
// description == "The name is not B."
Use dot syntax for calling procedures where first argument is (pointer to) an instance of this structure. Sort of like namespacing, but it will require procedure overloading to resolve collisions.
func append(list: List*, value: Int) -> Node*;
list.append(1);
/* instead of: */ list_append(list, 1);
func array_add(_ array: *($T[]), _ element: T);
a := [1, 2, 3, 4, ...] // use varargs as syntax for dynamic array
Also:
- Procedures overloading