From fa92a157746ae17f295d31b7a047dfeb99624a13 Mon Sep 17 00:00:00 2001 From: Baitinq Date: Wed, 11 Jun 2025 00:16:17 +0200 Subject: Misc: Rename lang --- README.md | 7 +- examples/-1.pry | 14 ++ examples/-1.src | 14 -- examples/0.pry | 19 ++ examples/0.src | 19 -- examples/1.5.pry | 25 ++ examples/1.5.src | 25 -- examples/1.pry | 19 ++ examples/1.src | 19 -- examples/10.pry | 37 +++ examples/10.src | 37 --- examples/11.pry | 26 +++ examples/11.src | 26 --- examples/12.pry | 51 ++++ examples/12.src | 51 ---- examples/13.pry | 44 ++++ examples/13.src | 44 ---- examples/14.pry | 19 ++ examples/14.src | 19 -- examples/15.pry | 22 ++ examples/15.src | 22 -- examples/16.pry | 21 ++ examples/16.src | 21 -- examples/17.pry | 24 ++ examples/17.src | 24 -- examples/18.pry | 30 +++ examples/18.src | 30 --- examples/19.pry | 33 +++ examples/19.src | 33 --- examples/2.pry | 21 ++ examples/2.src | 21 -- examples/20.pry | 49 ++++ examples/20.src | 49 ---- examples/21.pry | 78 +++++++ examples/21.src | 78 ------- examples/22.pry | 45 ++++ examples/22.src | 45 ---- examples/23.pry | 40 ++++ examples/23.src | 40 ---- examples/24.pry | 48 ++++ examples/24.src | 48 ---- examples/3.pry | 21 ++ examples/3.src | 21 -- examples/4.pry | 25 ++ examples/4.src | 25 -- examples/5.pry | 31 +++ examples/5.src | 31 --- examples/6.5.pry | 19 ++ examples/6.5.src | 19 -- examples/6.pry | 25 ++ examples/6.src | 25 -- examples/7.pry | 28 +++ examples/7.src | 28 --- examples/8.pry | 27 +++ examples/8.src | 27 --- examples/9.pry | 28 +++ examples/9.src | 28 --- src/bootstrap/codegen.pry | 187 +++++++++++++++ src/bootstrap/codegen.src | 187 --------------- src/bootstrap/llvm.pry | 289 +++++++++++++++++++++++ src/bootstrap/llvm.src | 289 ----------------------- src/bootstrap/main.pry | 69 ++++++ src/bootstrap/main.src | 69 ------ src/bootstrap/parser.pry | 530 ++++++++++++++++++++++++++++++++++++++++++ src/bootstrap/parser.src | 530 ------------------------------------------ src/bootstrap/tokenizer.pry | 553 ++++++++++++++++++++++++++++++++++++++++++++ src/bootstrap/tokenizer.src | 553 -------------------------------------------- std/mem.pry | 29 +++ std/mem.src | 29 --- std/stdlib.pry | 83 +++++++ std/stdlib.src | 83 ------- 71 files changed, 2613 insertions(+), 2612 deletions(-) create mode 100644 examples/-1.pry delete mode 100644 examples/-1.src create mode 100644 examples/0.pry delete mode 100644 examples/0.src create mode 100644 examples/1.5.pry delete mode 100644 examples/1.5.src create mode 100644 examples/1.pry delete mode 100644 examples/1.src create mode 100644 examples/10.pry delete mode 100644 examples/10.src create mode 100644 examples/11.pry delete mode 100644 examples/11.src create mode 100644 examples/12.pry delete mode 100644 examples/12.src create mode 100644 examples/13.pry delete mode 100644 examples/13.src create mode 100644 examples/14.pry delete mode 100644 examples/14.src create mode 100644 examples/15.pry delete mode 100644 examples/15.src create mode 100644 examples/16.pry delete mode 100644 examples/16.src create mode 100644 examples/17.pry delete mode 100644 examples/17.src create mode 100644 examples/18.pry delete mode 100644 examples/18.src create mode 100644 examples/19.pry delete mode 100644 examples/19.src create mode 100644 examples/2.pry delete mode 100644 examples/2.src create mode 100644 examples/20.pry delete mode 100644 examples/20.src create mode 100644 examples/21.pry delete mode 100644 examples/21.src create mode 100644 examples/22.pry delete mode 100644 examples/22.src create mode 100644 examples/23.pry delete mode 100644 examples/23.src create mode 100644 examples/24.pry delete mode 100644 examples/24.src create mode 100644 examples/3.pry delete mode 100644 examples/3.src create mode 100644 examples/4.pry delete mode 100644 examples/4.src create mode 100644 examples/5.pry delete mode 100644 examples/5.src create mode 100644 examples/6.5.pry delete mode 100644 examples/6.5.src create mode 100644 examples/6.pry delete mode 100644 examples/6.src create mode 100644 examples/7.pry delete mode 100644 examples/7.src create mode 100644 examples/8.pry delete mode 100644 examples/8.src create mode 100644 examples/9.pry delete mode 100644 examples/9.src create mode 100644 src/bootstrap/codegen.pry delete mode 100644 src/bootstrap/codegen.src create mode 100644 src/bootstrap/llvm.pry delete mode 100644 src/bootstrap/llvm.src create mode 100644 src/bootstrap/main.pry delete mode 100644 src/bootstrap/main.src create mode 100644 src/bootstrap/parser.pry delete mode 100644 src/bootstrap/parser.src create mode 100644 src/bootstrap/tokenizer.pry delete mode 100644 src/bootstrap/tokenizer.src create mode 100644 std/mem.pry delete mode 100644 std/mem.src create mode 100644 std/stdlib.pry delete mode 100644 std/stdlib.src diff --git a/README.md b/README.md index a6e18d3..3e5ef9a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ -# Programming Language +# Pry Programming Language -Simple statically typed and compiled programming language implemented in Zig, with support for variables, control flow, functions, and code generation using LLVM. +Pry is a simple, elegant, statically typed and compiled programming language implemented in Zig, with support for variables, control flow, functions, and code generation using LLVM. ## Building and Running 1. Ensure you have Zig and LLVM installed on your system. 2. Run the compiler on an example file: ``` - zig build run -- examples/8.src compile + zig build run -- examples/8.pry ``` 3. Link the generated object file to create an executable: ``` @@ -25,6 +25,7 @@ Simple statically typed and compiled programming language implemented in Zig, wi - **Functions**: Supports function declarations with parameters and return types. - **Expressions**: Includes additive, multiplicative, equality, and unary expressions. - **Code Generation with LLVM**: Translates AST to LLVM IR and generates object files for native execution. +- **Import System**: Allows importing libraries and other Pry files. ## Example Program diff --git a/examples/-1.pry b/examples/-1.pry new file mode 100644 index 0000000..4b77e10 --- /dev/null +++ b/examples/-1.pry @@ -0,0 +1,14 @@ +/* HELLO! Welcome to the unnamed language */ + +let main = () => i64 { + return 7; +}; + +/* + +Expected stdout: + +Expected return: 7 + +*/ + diff --git a/examples/-1.src b/examples/-1.src deleted file mode 100644 index 4b77e10..0000000 --- a/examples/-1.src +++ /dev/null @@ -1,14 +0,0 @@ -/* HELLO! Welcome to the unnamed language */ - -let main = () => i64 { - return 7; -}; - -/* - -Expected stdout: - -Expected return: 7 - -*/ - diff --git a/examples/0.pry b/examples/0.pry new file mode 100644 index 0000000..90a6861 --- /dev/null +++ b/examples/0.pry @@ -0,0 +1,19 @@ +/* HELLO! Welcome to the unnamed language */ + +import "!stdlib.pry"; + +let main = (argc: i64, argv: *i64) => i64 { + printf("%d\n", argc); + + return 2; +}; + +/* + +Expected stdout: + +1 + +Expected return: 2 + +*/ diff --git a/examples/0.src b/examples/0.src deleted file mode 100644 index 56b540e..0000000 --- a/examples/0.src +++ /dev/null @@ -1,19 +0,0 @@ -/* HELLO! Welcome to the unnamed language */ - -import "!stdlib.src"; - -let main = (argc: i64, argv: *i64) => i64 { - printf("%d\n", argc); - - return 2; -}; - -/* - -Expected stdout: - -1 - -Expected return: 2 - -*/ diff --git a/examples/1.5.pry b/examples/1.5.pry new file mode 100644 index 0000000..375e2d5 --- /dev/null +++ b/examples/1.5.pry @@ -0,0 +1,25 @@ +import "!stdlib.pry"; + +let x = () => i64 { + printf("%d\n", 22); + return 11; +}; + +let main = () => i64 { + let i = 4; + + printf("%d\n", i); + + return x(); +}; + +/* + +Expected stdout: + +4 +22 + +Expected return: 11 + +*/ diff --git a/examples/1.5.src b/examples/1.5.src deleted file mode 100644 index 6997d74..0000000 --- a/examples/1.5.src +++ /dev/null @@ -1,25 +0,0 @@ -import "!stdlib.src"; - -let x = () => i64 { - printf("%d\n", 22); - return 11; -}; - -let main = () => i64 { - let i = 4; - - printf("%d\n", i); - - return x(); -}; - -/* - -Expected stdout: - -4 -22 - -Expected return: 11 - -*/ diff --git a/examples/1.pry b/examples/1.pry new file mode 100644 index 0000000..c497dc4 --- /dev/null +++ b/examples/1.pry @@ -0,0 +1,19 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let s = "hello"; + + printf("%s\n", s); + + return 0; +}; + +/* + +Expected stdout: + +hello + +Expected return: 0 + +*/ diff --git a/examples/1.src b/examples/1.src deleted file mode 100644 index 6fef25a..0000000 --- a/examples/1.src +++ /dev/null @@ -1,19 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let s = "hello"; - - printf("%s\n", s); - - return 0; -}; - -/* - -Expected stdout: - -hello - -Expected return: 0 - -*/ diff --git a/examples/10.pry b/examples/10.pry new file mode 100644 index 0000000..a11608d --- /dev/null +++ b/examples/10.pry @@ -0,0 +1,37 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let counter = 0; + + while counter < 10 { + printf("%d\n", counter); + counter = counter + 1; + }; + + while true { + if counter == 10 { + return counter; + }; + }; + + return 1; +}; + +/* + +Expected stdout: + +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 + +Expected return: 10 + +*/ diff --git a/examples/10.src b/examples/10.src deleted file mode 100644 index d8dde60..0000000 --- a/examples/10.src +++ /dev/null @@ -1,37 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let counter = 0; - - while counter < 10 { - printf("%d\n", counter); - counter = counter + 1; - }; - - while true { - if counter == 10 { - return counter; - }; - }; - - return 1; -}; - -/* - -Expected stdout: - -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 - -Expected return: 10 - -*/ diff --git a/examples/11.pry b/examples/11.pry new file mode 100644 index 0000000..2349f10 --- /dev/null +++ b/examples/11.pry @@ -0,0 +1,26 @@ +import "!stdlib.pry"; + +let id = (a: i64) => i64 { + printf("%d\n", a); + printf("%d\n", 12); + return a; +}; + +let main = () => i64 { + let y = (f: (i64) => i64, x: i64) => i64 { + return f(x); + }; + + return y(id, 2); +}; + +/* + +Expected stdout: + +2 +12 + +Expected return: 2 + +*/ diff --git a/examples/11.src b/examples/11.src deleted file mode 100644 index 5c2acad..0000000 --- a/examples/11.src +++ /dev/null @@ -1,26 +0,0 @@ -import "!stdlib.src"; - -let id = (a: i64) => i64 { - printf("%d\n", a); - printf("%d\n", 12); - return a; -}; - -let main = () => i64 { - let y = (f: (i64) => i64, x: i64) => i64 { - return f(x); - }; - - return y(id, 2); -}; - -/* - -Expected stdout: - -2 -12 - -Expected return: 2 - -*/ diff --git a/examples/12.pry b/examples/12.pry new file mode 100644 index 0000000..34519e6 --- /dev/null +++ b/examples/12.pry @@ -0,0 +1,51 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let factorial = (n: i64) => i64 { + let f = (acc: i64, n: i64) => i64 { + if n == 0 { + return acc; + }; + return f(acc * n, n - 1); + }; + return f(1, n); + }; + + let is_even = (n: i64) => bool { + if n % 2 == 0 { + return true; + }; + return false; + }; + + let sum_if = (predicate: (i64) => bool, limit: i64) => i64 { + let sum = 0; + let i = 0; + while i < limit { + if predicate(i) { + sum = sum + i; + }; + i = i + 1; + }; + return sum; + }; + + let fact_val = factorial(6); + printf("%d\n", fact_val); + + let even_sum = sum_if(is_even, 20); + printf("%d\n", even_sum); + + return 0; +}; + +/* + +Expected stdout: + +720 +90 + +Expected return: 0 + +*/ diff --git a/examples/12.src b/examples/12.src deleted file mode 100644 index 1193e4c..0000000 --- a/examples/12.src +++ /dev/null @@ -1,51 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let factorial = (n: i64) => i64 { - let f = (acc: i64, n: i64) => i64 { - if n == 0 { - return acc; - }; - return f(acc * n, n - 1); - }; - return f(1, n); - }; - - let is_even = (n: i64) => bool { - if n % 2 == 0 { - return true; - }; - return false; - }; - - let sum_if = (predicate: (i64) => bool, limit: i64) => i64 { - let sum = 0; - let i = 0; - while i < limit { - if predicate(i) { - sum = sum + i; - }; - i = i + 1; - }; - return sum; - }; - - let fact_val = factorial(6); - printf("%d\n", fact_val); - - let even_sum = sum_if(is_even, 20); - printf("%d\n", even_sum); - - return 0; -}; - -/* - -Expected stdout: - -720 -90 - -Expected return: 0 - -*/ diff --git a/examples/13.pry b/examples/13.pry new file mode 100644 index 0000000..839caef --- /dev/null +++ b/examples/13.pry @@ -0,0 +1,44 @@ +import "!stdlib.pry"; + +let main = () => i64 { + /* Iterative Fibonacci using while loop. */ + let fibonacci_iter = (n: i64) => i64 { + let a = 0; + let b = 1; + let i = 0; + while i < n { + let temp = b; + b = a + b; + a = temp; + i = i + 1; + }; + return a; + }; + + /* Recursive GCD using Euclid's algorithm. */ + let gcd = (a: i64, b: i64) => i64 { + if b == 0 { + return a; + }; + return gcd(b, a % b); + }; + + let fib_val = fibonacci_iter(10); + printf("%d\n", fib_val); + + let gcd_val = gcd(48, 18); + printf("%d\n", gcd_val); + + return 0; +}; + +/* + +Expected stdout: + +55 +6 + +Expected return: 0 + +*/ diff --git a/examples/13.src b/examples/13.src deleted file mode 100644 index 9de55ac..0000000 --- a/examples/13.src +++ /dev/null @@ -1,44 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - /* Iterative Fibonacci using while loop. */ - let fibonacci_iter = (n: i64) => i64 { - let a = 0; - let b = 1; - let i = 0; - while i < n { - let temp = b; - b = a + b; - a = temp; - i = i + 1; - }; - return a; - }; - - /* Recursive GCD using Euclid's algorithm. */ - let gcd = (a: i64, b: i64) => i64 { - if b == 0 { - return a; - }; - return gcd(b, a % b); - }; - - let fib_val = fibonacci_iter(10); - printf("%d\n", fib_val); - - let gcd_val = gcd(48, 18); - printf("%d\n", gcd_val); - - return 0; -}; - -/* - -Expected stdout: - -55 -6 - -Expected return: 0 - -*/ diff --git a/examples/14.pry b/examples/14.pry new file mode 100644 index 0000000..9792530 --- /dev/null +++ b/examples/14.pry @@ -0,0 +1,19 @@ +let main = () => i64 { + let fn = () => () => i64 { + return () => i64 { + return 4; + }; + }; + + let x = fn(); + + return x(); +}; + +/* + +Expected stdout: + +Expected return: 4 + +*/ diff --git a/examples/14.src b/examples/14.src deleted file mode 100644 index 9792530..0000000 --- a/examples/14.src +++ /dev/null @@ -1,19 +0,0 @@ -let main = () => i64 { - let fn = () => () => i64 { - return () => i64 { - return 4; - }; - }; - - let x = fn(); - - return x(); -}; - -/* - -Expected stdout: - -Expected return: 4 - -*/ diff --git a/examples/15.pry b/examples/15.pry new file mode 100644 index 0000000..a5aac79 --- /dev/null +++ b/examples/15.pry @@ -0,0 +1,22 @@ +extern putchar = (i64) => i64; + +let main = () => i64 { + putchar(72); + putchar(101); + putchar(108); + putchar(108); + putchar(111); + putchar(10); + return 0; +}; + +/* + +Expected stdout: + +Hello + +Expected return: 0 + +*/ + diff --git a/examples/15.src b/examples/15.src deleted file mode 100644 index a5aac79..0000000 --- a/examples/15.src +++ /dev/null @@ -1,22 +0,0 @@ -extern putchar = (i64) => i64; - -let main = () => i64 { - putchar(72); - putchar(101); - putchar(108); - putchar(108); - putchar(111); - putchar(10); - return 0; -}; - -/* - -Expected stdout: - -Hello - -Expected return: 0 - -*/ - diff --git a/examples/16.pry b/examples/16.pry new file mode 100644 index 0000000..3fb29f7 --- /dev/null +++ b/examples/16.pry @@ -0,0 +1,21 @@ +extern SDL_CreateWindow = (*i8, i64, i64, i64, i64, i64) => i64; +extern SDL_Init = (i64) => i64; + +let main = () => i64 { + SDL_Init(1); + SDL_CreateWindow("hello world!", 0, 0, 400, 400, 0); + + while true { + + }; + + return 0; +}; + +/* + +Expected stdout: + +Expected return: 0 + +*/ diff --git a/examples/16.src b/examples/16.src deleted file mode 100644 index 3fb29f7..0000000 --- a/examples/16.src +++ /dev/null @@ -1,21 +0,0 @@ -extern SDL_CreateWindow = (*i8, i64, i64, i64, i64, i64) => i64; -extern SDL_Init = (i64) => i64; - -let main = () => i64 { - SDL_Init(1); - SDL_CreateWindow("hello world!", 0, 0, 400, 400, 0); - - while true { - - }; - - return 0; -}; - -/* - -Expected stdout: - -Expected return: 0 - -*/ diff --git a/examples/17.pry b/examples/17.pry new file mode 100644 index 0000000..c320044 --- /dev/null +++ b/examples/17.pry @@ -0,0 +1,24 @@ +extern malloc = (i64) => *i64; +extern free = (*i64) => void; + +import "!stdlib.pry"; + +let main = () => i64 { + let x = malloc(8); + *x = 10; + printf("%p\n", x); + printf("%d\n", *x); + free(x); + return 0; +}; + +/* + +Expected stdout: + +${SOMEPOINTER} +10 + +Expected return: 0 + +*/ diff --git a/examples/17.src b/examples/17.src deleted file mode 100644 index 93a313f..0000000 --- a/examples/17.src +++ /dev/null @@ -1,24 +0,0 @@ -extern malloc = (i64) => *i64; -extern free = (*i64) => void; - -import "!stdlib.src"; - -let main = () => i64 { - let x = malloc(8); - *x = 10; - printf("%p\n", x); - printf("%d\n", *x); - free(x); - return 0; -}; - -/* - -Expected stdout: - -${SOMEPOINTER} -10 - -Expected return: 0 - -*/ diff --git a/examples/18.pry b/examples/18.pry new file mode 100644 index 0000000..32b2d1a --- /dev/null +++ b/examples/18.pry @@ -0,0 +1,30 @@ +extern malloc = (i64) => *void; +extern free = (*void) => void; + +import "!stdlib.pry"; + +let main = () => i64 { + let x = cast(*i8, malloc(24)); + (*(x+cast(*i8, 0))) = 10; + (*(x+cast(*i8, 1))) = 20; + (*(x+cast(*i8, 2))) = 40; + printf("%p\n", x); + printf("%d\n", *(x+cast(*i8, 0))); + printf("%d\n", *(x+cast(*i8, 1))); + printf("%d\n", *(x+cast(*i8, 2))); + free(cast(*void, x)); + return 0; +}; + +/* + +Expected stdout: + +${SOMEPOINTER} +10 +20 +40 + +Expected return: 0 + +*/ diff --git a/examples/18.src b/examples/18.src deleted file mode 100644 index 741a460..0000000 --- a/examples/18.src +++ /dev/null @@ -1,30 +0,0 @@ -extern malloc = (i64) => *void; -extern free = (*void) => void; - -import "!stdlib.src"; - -let main = () => i64 { - let x = cast(*i8, malloc(24)); - (*(x+cast(*i8, 0))) = 10; - (*(x+cast(*i8, 1))) = 20; - (*(x+cast(*i8, 2))) = 40; - printf("%p\n", x); - printf("%d\n", *(x+cast(*i8, 0))); - printf("%d\n", *(x+cast(*i8, 1))); - printf("%d\n", *(x+cast(*i8, 2))); - free(cast(*void, x)); - return 0; -}; - -/* - -Expected stdout: - -${SOMEPOINTER} -10 -20 -40 - -Expected return: 0 - -*/ diff --git a/examples/19.pry b/examples/19.pry new file mode 100644 index 0000000..2ae1973 --- /dev/null +++ b/examples/19.pry @@ -0,0 +1,33 @@ +extern printf = (*i8, varargs) => void; +extern malloc = (i64) => *void; +extern free = (*void) => void; + +let main = () => i64 { + let buf = cast(*i8, malloc(sizeof(i8) * 13)); + (*(buf+cast(*i8, 0))) = 'h'; + (*(buf+cast(*i8, 1))) = 'e'; + (*(buf+cast(*i8, 2))) = 'l'; + (*(buf+cast(*i8, 3))) = 'l'; + (*(buf+cast(*i8, 4))) = 'o'; + (*(buf+cast(*i8, 5))) = ' '; + (*(buf+cast(*i8, 6))) = 'w'; + (*(buf+cast(*i8, 7))) = 'o'; + (*(buf+cast(*i8, 8))) = 'r'; + (*(buf+cast(*i8, 9))) = 'l'; + (*(buf+cast(*i8, 10))) = 'd'; + (*(buf+cast(*i8, 11))) = '\n'; + (*(buf+cast(*i8, 12))) = '\0'; + printf("%s", buf); + free(cast(*void, buf)); + return 0; +}; + +/* + +Expected stdout: + +hello world! + +Expected return: 0 + +*/ diff --git a/examples/19.src b/examples/19.src deleted file mode 100644 index 2ae1973..0000000 --- a/examples/19.src +++ /dev/null @@ -1,33 +0,0 @@ -extern printf = (*i8, varargs) => void; -extern malloc = (i64) => *void; -extern free = (*void) => void; - -let main = () => i64 { - let buf = cast(*i8, malloc(sizeof(i8) * 13)); - (*(buf+cast(*i8, 0))) = 'h'; - (*(buf+cast(*i8, 1))) = 'e'; - (*(buf+cast(*i8, 2))) = 'l'; - (*(buf+cast(*i8, 3))) = 'l'; - (*(buf+cast(*i8, 4))) = 'o'; - (*(buf+cast(*i8, 5))) = ' '; - (*(buf+cast(*i8, 6))) = 'w'; - (*(buf+cast(*i8, 7))) = 'o'; - (*(buf+cast(*i8, 8))) = 'r'; - (*(buf+cast(*i8, 9))) = 'l'; - (*(buf+cast(*i8, 10))) = 'd'; - (*(buf+cast(*i8, 11))) = '\n'; - (*(buf+cast(*i8, 12))) = '\0'; - printf("%s", buf); - free(cast(*void, buf)); - return 0; -}; - -/* - -Expected stdout: - -hello world! - -Expected return: 0 - -*/ diff --git a/examples/2.pry b/examples/2.pry new file mode 100644 index 0000000..2367212 --- /dev/null +++ b/examples/2.pry @@ -0,0 +1,21 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let test = 1922; + + let uwu = test; + + printf("%d\n", uwu); + + return 0; +}; + +/* + +Expected stdout: + +1922 + +Expected return: 0 + +*/ diff --git a/examples/2.src b/examples/2.src deleted file mode 100644 index d6a81b8..0000000 --- a/examples/2.src +++ /dev/null @@ -1,21 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let test = 1922; - - let uwu = test; - - printf("%d\n", uwu); - - return 0; -}; - -/* - -Expected stdout: - -1922 - -Expected return: 0 - -*/ diff --git a/examples/20.pry b/examples/20.pry new file mode 100644 index 0000000..0cae122 --- /dev/null +++ b/examples/20.pry @@ -0,0 +1,49 @@ + +extern malloc = (i64) => *void; +extern free = (*void) => void; + +import "!stdlib.pry"; + +let init_array = (n: i64, arr: *i64) => i64 { + let i = 0; + while i < n { + (*(arr + cast(*i64, i))) = i; + i = i + 1; + }; + return 0; +}; + +let main = () => i64 { + let n = 10; + let arr = cast(*i64, malloc(n * 8)); + init_array(n, arr); + + let i = 0; + while i < n { + printf("%d\n", *(arr + cast(*i64, i))); + i = i + 1; + }; + + free(cast(*void, arr)); + + return 0; +}; + +/* + +Expected stdout: + +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 + +Expected return: 0 + +*/ diff --git a/examples/20.src b/examples/20.src deleted file mode 100644 index 6acabc8..0000000 --- a/examples/20.src +++ /dev/null @@ -1,49 +0,0 @@ - -extern malloc = (i64) => *void; -extern free = (*void) => void; - -import "!stdlib.src"; - -let init_array = (n: i64, arr: *i64) => i64 { - let i = 0; - while i < n { - (*(arr + cast(*i64, i))) = i; - i = i + 1; - }; - return 0; -}; - -let main = () => i64 { - let n = 10; - let arr = cast(*i64, malloc(n * 8)); - init_array(n, arr); - - let i = 0; - while i < n { - printf("%d\n", *(arr + cast(*i64, i))); - i = i + 1; - }; - - free(cast(*void, arr)); - - return 0; -}; - -/* - -Expected stdout: - -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 - -Expected return: 0 - -*/ diff --git a/examples/21.pry b/examples/21.pry new file mode 100644 index 0000000..fb30960 --- /dev/null +++ b/examples/21.pry @@ -0,0 +1,78 @@ +extern rand = () => i64; +extern malloc = (i64) => *void; +extern free = (*void) => void; + +import "!stdlib.pry"; + +let init_array = (n: i64, arr: *i64) => void { + let i = 0; + while i < n { + (*(arr + cast(*i64, i))) = rand(); + i = i + 1; + }; + return; +}; + +let print_array = (n: i64, arr: *i64) => void { + let i = 0; + while i < n { + printf("%d\n", *(arr + cast(*i64, i))); + i = i + 1; + }; + return; +}; + +let sort_array = (n: i64, arr: *i64) => void { + let i = 0; + let j = 0; + + while i < n { + j = i + 1; + while j < n { + let x = *(arr + cast(*i64, i)); + let y = *(arr + cast(*i64, j)); + + if x > y { + let tmp = *(arr + cast(*i64, i)); + (*(arr + cast(*i64, i))) = *(arr + cast(*i64, j)); + (*(arr + cast(*i64, j))) = tmp; + }; + + j = j + 1; + }; + i = i + 1; + }; + + return; +}; + +let main = () => i64 { + let n = 10; + let arr = cast(*i64, malloc(n * 8)); + init_array(n, arr); + + printf("Pre-sorted:\n"); + print_array(n, arr); + + sort_array(n, arr); + + printf("Sorted:\n"); + print_array(n, arr); + + free(cast(*void, arr)); + + return 0; +}; + +/* + +Expected stdout: + +Pre-sorted: +${UNSORTED_LIST} +Sorted: +${SORTED_LIST} + +Expected return: 0 + +*/ diff --git a/examples/21.src b/examples/21.src deleted file mode 100644 index 804b242..0000000 --- a/examples/21.src +++ /dev/null @@ -1,78 +0,0 @@ -extern rand = () => i64; -extern malloc = (i64) => *void; -extern free = (*void) => void; - -import "!stdlib.src"; - -let init_array = (n: i64, arr: *i64) => void { - let i = 0; - while i < n { - (*(arr + cast(*i64, i))) = rand(); - i = i + 1; - }; - return; -}; - -let print_array = (n: i64, arr: *i64) => void { - let i = 0; - while i < n { - printf("%d\n", *(arr + cast(*i64, i))); - i = i + 1; - }; - return; -}; - -let sort_array = (n: i64, arr: *i64) => void { - let i = 0; - let j = 0; - - while i < n { - j = i + 1; - while j < n { - let x = *(arr + cast(*i64, i)); - let y = *(arr + cast(*i64, j)); - - if x > y { - let tmp = *(arr + cast(*i64, i)); - (*(arr + cast(*i64, i))) = *(arr + cast(*i64, j)); - (*(arr + cast(*i64, j))) = tmp; - }; - - j = j + 1; - }; - i = i + 1; - }; - - return; -}; - -let main = () => i64 { - let n = 10; - let arr = cast(*i64, malloc(n * 8)); - init_array(n, arr); - - printf("Pre-sorted:\n"); - print_array(n, arr); - - sort_array(n, arr); - - printf("Sorted:\n"); - print_array(n, arr); - - free(cast(*void, arr)); - - return 0; -}; - -/* - -Expected stdout: - -Pre-sorted: -${UNSORTED_LIST} -Sorted: -${SORTED_LIST} - -Expected return: 0 - -*/ diff --git a/examples/22.pry b/examples/22.pry new file mode 100644 index 0000000..b57d7c9 --- /dev/null +++ b/examples/22.pry @@ -0,0 +1,45 @@ +extern malloc = (i64) => *void; + +import "!stdlib.pry"; + +/* declare new struct type */ +let test = struct { + x: i64, + y: *i8, + z: bool +}; + +let main = () => i64 { + /* instanciate new struct. instanciating fields isn't supported here */ + let inst = test{}; + + inst.x = 2; + inst.z = true; + inst.y = malloc(1); + (*(inst.y)) = 5; + + let x = 0; + + printf("Inst x: %d\n", inst.x); + printf("Inst y: %d\n", *(inst.y)); + + if inst.z { + x = 1; + }; + + printf("Test: %d\n", x); + + return 0; +}; + +/* + +Expected stdout: + +Inst x: 2 +Inst y: 5 +Test: 1 + +Expected return: 0 + +*/ diff --git a/examples/22.src b/examples/22.src deleted file mode 100644 index cc367bf..0000000 --- a/examples/22.src +++ /dev/null @@ -1,45 +0,0 @@ -extern malloc = (i64) => *void; - -import "!stdlib.src"; - -/* declare new struct type */ -let test = struct { - x: i64, - y: *i8, - z: bool -}; - -let main = () => i64 { - /* instanciate new struct. instanciating fields isn't supported here */ - let inst = test{}; - - inst.x = 2; - inst.z = true; - inst.y = malloc(1); - (*(inst.y)) = 5; - - let x = 0; - - printf("Inst x: %d\n", inst.x); - printf("Inst y: %d\n", *(inst.y)); - - if inst.z { - x = 1; - }; - - printf("Test: %d\n", x); - - return 0; -}; - -/* - -Expected stdout: - -Inst x: 2 -Inst y: 5 -Test: 1 - -Expected return: 0 - -*/ diff --git a/examples/23.pry b/examples/23.pry new file mode 100644 index 0000000..65b3279 --- /dev/null +++ b/examples/23.pry @@ -0,0 +1,40 @@ +extern malloc = (i64) => *void; + +import "!stdlib.pry"; + +let test = struct { + x: i64, + y: *i8, +}; + +let print_struct = (s: test) => void { + printf("X: %d\n", s.x); + printf("Y: %s\n", s.y); + return; +}; + +let main = () => i64 { + let inst = cast(*test, malloc(sizeof(test))); + + print_struct(*inst); + + (*inst).x = 4; + (*inst).y = "hi"; + + print_struct(*inst); + + return 0; +}; + +/* + +Expected stdout: + +X: 0 +Y: (null) +X: 4 +Y: hi + +Expected return: 0 + +*/ diff --git a/examples/23.src b/examples/23.src deleted file mode 100644 index 31277c9..0000000 --- a/examples/23.src +++ /dev/null @@ -1,40 +0,0 @@ -extern malloc = (i64) => *void; - -import "!stdlib.src"; - -let test = struct { - x: i64, - y: *i8, -}; - -let print_struct = (s: test) => void { - printf("X: %d\n", s.x); - printf("Y: %s\n", s.y); - return; -}; - -let main = () => i64 { - let inst = cast(*test, malloc(sizeof(test))); - - print_struct(*inst); - - (*inst).x = 4; - (*inst).y = "hi"; - - print_struct(*inst); - - return 0; -}; - -/* - -Expected stdout: - -X: 0 -Y: (null) -X: 4 -Y: hi - -Expected return: 0 - -*/ diff --git a/examples/24.pry b/examples/24.pry new file mode 100644 index 0000000..f30a7fc --- /dev/null +++ b/examples/24.pry @@ -0,0 +1,48 @@ +extern malloc = (i64) => *void; + +import "!stdlib.pry"; + +let test = struct { + x: i64, + y: *i8, + z: *test, +}; + +let print_struct = (s: *test) => void { + printf("X: %d\n", (*s).x); + printf("Y: %s\n", (*s).y); + if (*s).z != cast(*test, null) { + print_struct((*s).z); + }; + return; +}; + +let main = () => i64 { + let inst = cast(*test, malloc(sizeof(test))); + let inst2 = cast(*test, malloc(sizeof(test))); + + print_struct(inst); + + (*inst).x = 4; + (*inst).y = "hi"; + (*inst).z = inst2; + + (*inst2).y = "bye"; + + print_struct(inst); + + return 0; +}; + +/* + +Expected stdout: + +X: 0 +Y: (null) +X: 4 +Y: hi + +Expected return: 0 + +*/ diff --git a/examples/24.src b/examples/24.src deleted file mode 100644 index 7349906..0000000 --- a/examples/24.src +++ /dev/null @@ -1,48 +0,0 @@ -extern malloc = (i64) => *void; - -import "!stdlib.src"; - -let test = struct { - x: i64, - y: *i8, - z: *test, -}; - -let print_struct = (s: *test) => void { - printf("X: %d\n", (*s).x); - printf("Y: %s\n", (*s).y); - if (*s).z != cast(*test, null) { - print_struct((*s).z); - }; - return; -}; - -let main = () => i64 { - let inst = cast(*test, malloc(sizeof(test))); - let inst2 = cast(*test, malloc(sizeof(test))); - - print_struct(inst); - - (*inst).x = 4; - (*inst).y = "hi"; - (*inst).z = inst2; - - (*inst2).y = "bye"; - - print_struct(inst); - - return 0; -}; - -/* - -Expected stdout: - -X: 0 -Y: (null) -X: 4 -Y: hi - -Expected return: 0 - -*/ diff --git a/examples/3.pry b/examples/3.pry new file mode 100644 index 0000000..c7b2347 --- /dev/null +++ b/examples/3.pry @@ -0,0 +1,21 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let seventeen = 10 + 2 + 4; + + seventeen = seventeen + 1; + + printf("%d\n", seventeen); + + return seventeen; +}; + +/* + +Expected stdout: + +17 + +Expected return: 17 + +*/ diff --git a/examples/3.src b/examples/3.src deleted file mode 100644 index f10f05c..0000000 --- a/examples/3.src +++ /dev/null @@ -1,21 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let seventeen = 10 + 2 + 4; - - seventeen = seventeen + 1; - - printf("%d\n", seventeen); - - return seventeen; -}; - -/* - -Expected stdout: - -17 - -Expected return: 17 - -*/ diff --git a/examples/4.pry b/examples/4.pry new file mode 100644 index 0000000..b8c48d2 --- /dev/null +++ b/examples/4.pry @@ -0,0 +1,25 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let print_one = () => i64 { + printf("%d\n", 1); + return 4; + }; + + let y = print_one() + 2; + + printf("%d\n", y); + + return y; +}; + +/* + +Expected stdout: + +1 +6 + +Expected return: 6 + +*/ diff --git a/examples/4.src b/examples/4.src deleted file mode 100644 index 7787593..0000000 --- a/examples/4.src +++ /dev/null @@ -1,25 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let print_one = () => i64 { - printf("%d\n", 1); - return 4; - }; - - let y = print_one() + 2; - - printf("%d\n", y); - - return y; -}; - -/* - -Expected stdout: - -1 -6 - -Expected return: 6 - -*/ diff --git a/examples/5.pry b/examples/5.pry new file mode 100644 index 0000000..f12fbae --- /dev/null +++ b/examples/5.pry @@ -0,0 +1,31 @@ +/* As you see, the language supports variable scopes */ + +import "!stdlib.pry"; + +let x = 18; + +let foo = () => i64 { + let x = 1; + printf("%d\n", x); + return x; +}; + +let main = () => i64 { + printf("%d\n", x); + let x = 2; + let y = foo(); + printf("%d\n", x); + return x + y; +}; + +/* + +Expected stdout: + +18 +1 +2 + +Expected return: 3 + +*/ diff --git a/examples/5.src b/examples/5.src deleted file mode 100644 index f6b2e62..0000000 --- a/examples/5.src +++ /dev/null @@ -1,31 +0,0 @@ -/* As you see, the language supports variable scopes */ - -import "!stdlib.src"; - -let x = 18; - -let foo = () => i64 { - let x = 1; - printf("%d\n", x); - return x; -}; - -let main = () => i64 { - printf("%d\n", x); - let x = 2; - let y = foo(); - printf("%d\n", x); - return x + y; -}; - -/* - -Expected stdout: - -18 -1 -2 - -Expected return: 3 - -*/ diff --git a/examples/6.5.pry b/examples/6.5.pry new file mode 100644 index 0000000..057181f --- /dev/null +++ b/examples/6.5.pry @@ -0,0 +1,19 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let x = !(1 == 1); + if !x { + printf("Condition\n"); + }; + return 0; +}; + +/* + +Expected stdout: + +Condition + +Expected return: 0 + +*/ diff --git a/examples/6.5.src b/examples/6.5.src deleted file mode 100644 index f7d6229..0000000 --- a/examples/6.5.src +++ /dev/null @@ -1,19 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let x = !(1 == 1); - if !x { - printf("Condition\n"); - }; - return 0; -}; - -/* - -Expected stdout: - -Condition - -Expected return: 0 - -*/ diff --git a/examples/6.pry b/examples/6.pry new file mode 100644 index 0000000..008ecd9 --- /dev/null +++ b/examples/6.pry @@ -0,0 +1,25 @@ +import "!stdlib.pry"; + +let print_input = (input_a: i64, input_b: i64) => i64 { + printf("%d\n", input_a); + printf("%d\n", input_b); + return input_a + input_b; +}; + +let main = () => i64 { + let i = print_input(1,4); + return print_input(7, 2) + i; +}; + +/* + +Expected stdout: + +1 +4 +7 +2 + +Expected return: 14 + +*/ diff --git a/examples/6.src b/examples/6.src deleted file mode 100644 index 3793f24..0000000 --- a/examples/6.src +++ /dev/null @@ -1,25 +0,0 @@ -import "!stdlib.src"; - -let print_input = (input_a: i64, input_b: i64) => i64 { - printf("%d\n", input_a); - printf("%d\n", input_b); - return input_a + input_b; -}; - -let main = () => i64 { - let i = print_input(1,4); - return print_input(7, 2) + i; -}; - -/* - -Expected stdout: - -1 -4 -7 -2 - -Expected return: 14 - -*/ diff --git a/examples/7.pry b/examples/7.pry new file mode 100644 index 0000000..5867c4e --- /dev/null +++ b/examples/7.pry @@ -0,0 +1,28 @@ +import "!stdlib.pry"; + +let ten = () => i64 { + return () => i64 { + return 10; + }(); +}; + +let main = () => i64 { + let i = 4; + + if (1 - -1 * 2) == 5 - (-1 + 1 + ten() / 2) + 3 { + printf("%d\n", i); + return i; + }; + + return 1; +}; + +/* + +Expected stdout: + +4 + +Expected return: 4 + +*/ diff --git a/examples/7.src b/examples/7.src deleted file mode 100644 index a94891d..0000000 --- a/examples/7.src +++ /dev/null @@ -1,28 +0,0 @@ -import "!stdlib.src"; - -let ten = () => i64 { - return () => i64 { - return 10; - }(); -}; - -let main = () => i64 { - let i = 4; - - if (1 - -1 * 2) == 5 - (-1 + 1 + ten() / 2) + 3 { - printf("%d\n", i); - return i; - }; - - return 1; -}; - -/* - -Expected stdout: - -4 - -Expected return: 4 - -*/ diff --git a/examples/8.pry b/examples/8.pry new file mode 100644 index 0000000..51953d0 --- /dev/null +++ b/examples/8.pry @@ -0,0 +1,27 @@ +import "!stdlib.pry"; + +let main = () => i64 { + let fib = (n: i64) => i64 { + if n == 0 { + return 0; + }; + if n == 1 { + return 1; + }; + return fib(n-2) + fib(n-1); + }; + + let result = fib(30); + printf("%d\n", result); + return result; +}; + +/* + +Expected stdout: + +832040 + +Expected return: 832040 + +*/ diff --git a/examples/8.src b/examples/8.src deleted file mode 100644 index 671640b..0000000 --- a/examples/8.src +++ /dev/null @@ -1,27 +0,0 @@ -import "!stdlib.src"; - -let main = () => i64 { - let fib = (n: i64) => i64 { - if n == 0 { - return 0; - }; - if n == 1 { - return 1; - }; - return fib(n-2) + fib(n-1); - }; - - let result = fib(30); - printf("%d\n", result); - return result; -}; - -/* - -Expected stdout: - -832040 - -Expected return: 832040 - -*/ diff --git a/examples/9.pry b/examples/9.pry new file mode 100644 index 0000000..bbe4b50 --- /dev/null +++ b/examples/9.pry @@ -0,0 +1,28 @@ +import "!stdlib.pry"; + +let print_boolean = (b: bool) => i64 { + printf("%d\n", b); + return 0; +}; + +let main = () => i64 { + let i = true; + i = !i; + + if !i { + print_boolean(!i); + return 1; + }; + + return 0; +}; + +/* + +Expected stdout: + +1 + +Expected return: 1 + +*/ diff --git a/examples/9.src b/examples/9.src deleted file mode 100644 index ae586c2..0000000 --- a/examples/9.src +++ /dev/null @@ -1,28 +0,0 @@ -import "!stdlib.src"; - -let print_boolean = (b: bool) => i64 { - printf("%d\n", b); - return 0; -}; - -let main = () => i64 { - let i = true; - i = !i; - - if !i { - print_boolean(!i); - return 1; - }; - - return 0; -}; - -/* - -Expected stdout: - -1 - -Expected return: 1 - -*/ diff --git a/src/bootstrap/codegen.pry b/src/bootstrap/codegen.pry new file mode 100644 index 0000000..7293c09 --- /dev/null +++ b/src/bootstrap/codegen.pry @@ -0,0 +1,187 @@ +import "llvm.pry"; + +let codegen = struct { + llvm_module: LLVMModuleRef, + llvm_context: LLVMContextRef, + builder: LLVMBuilderRef, + arena: *arena, +}; + +let codegen_init = (alloc: *arena) => *codegen { + LLVMInitializeAllTargetInfos(); + LLVMInitializeAllTargetMCs(); + LLVMInitializeAllTargets(); + LLVMInitializeAllAsmPrinters(); + LLVMInitializeAllAsmParsers(); + + let module = LLVMModuleCreateWithName("module"); + let context = LLVMGetGlobalContext(); + let builder = LLVMCreateBuilder(); + + let c = cast(*codegen, arena_alloc(alloc, sizeof(codegen))); + + (*c).llvm_module = module; + (*c).llvm_context = context; + (*c).builder = builder; + (*c).arena = alloc; + + return c; +}; + +let create_node = (c: *codegen, n: Node) => *Node { + let res = cast(*Node, arena_alloc((*c).arena, sizeof(Node))); + *res = n; + return res; +}; + +let Variable = struct { + value: LLVMValueRef, + type: LLVMTypeRef, + node: *Node, + node_type: *Node, + stack_level: *i64, +}; + +let codegen_create_variable = (c: *codegen, variable: Variable) => *Variable { + let v = cast(*Variable, arena_alloc((*c).arena, sizeof(Variable))); + *v = variable; + return v; +}; + +let codegen_generate_literal = (c: *codegen, literal_val: LLVMValueRef, name: *i8, node: *Node, node_type: *Node) => *Variable { + /* TODO: Global */ + let v = Variable{}; + v.value = literal_val; + v.type = cast(LLVMTypeRef, null); + v.stack_level = cast(*i64, null); + v.node = node; + v.node_type = node_type; + return codegen_create_variable(c, v); +}; + +let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: *i8) => *Variable { + if ((*expression).type == NODE_PRIMARY_EXPRESSION_NUMBER) { + let n = (*cast(*NODE_PRIMARY_EXPRESSION_NUMBER_DATA, (*expression).data)).value; + + printf("X: %d\n", n); + + let node_type = Node{}; + node_type.type = NODE_TYPE_SIMPLE_TYPE; + + let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*c).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA))); + (*d).name = "i64"; + (*d).underlying_type = cast(*Node, null); + node_type.data = cast(*void, d); + + return codegen_generate_literal(c, LLVMConstInt(LLVMInt64Type(), n, 0), name, expression, create_node(c, node_type)); + }; + + if ((*expression).type == NODE_FUNCTION_DEFINITION) { + printf("ASS %d\n", (*expression).type); + assert(false); /* TODO */ + printf("ERT\n"); + }; + + assert(false); + + return cast(*Variable, null); +}; + +let codegen_generate_assignment_statement = (c: *codegen, stmt: *NODE_ASSIGNMENT_STATEMENT_DATA) => i64 { + let lhs = *((*stmt).lhs); + let prhs = (*stmt).rhs; + + if (lhs.type == NODE_PRIMARY_EXPRESSION_IDENTIFIER) { + let identifier = (*cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, lhs.data)).name; + printf("XX %s\n", identifier); + let variable = codegen_generate_expression_value(c, prhs, identifier); + assert(variable != cast(*Variable, null)); + return 0; + }; + + assert(false); + return 0; +}; + +let codegen_generate_statement = (c: *codegen, statement: *Node) => i64 { + let stmt = *statement; + assert(stmt.type == NODE_ASSIGNMENT_STATEMENT); /* TODO: generate other node types */ + + let res = codegen_generate_assignment_statement(c, cast(*NODE_ASSIGNMENT_STATEMENT_DATA, stmt.data)); + if res != 0 { + return 1; + }; + printf("STMT: %d\n", stmt.type); + return 0; +}; + +let codegen_generate = (c: *codegen, ast: *Node) => i64 { + assert((*ast).type == NODE_PROGRAM); + + let program = *cast(*NODE_PROGRAM_DATA, (*ast).data); + + let i = 0; + while i < program.statements_len { + let stmt = *(program.statements + cast(**Node, i)); + + let res = codegen_generate_statement(c, stmt); + if res != 0 { + return 1; + }; + + i = i + 1; + }; + + return 0; +}; + +let codegen_compile = (c: *codegen) => i64 { + /* Dump module */ + LLVMDumpModule((*c).llvm_module); + + /* Generate code */ + let triple = LLVMGetDefaultTargetTriple(); + let target_ref = cast(*LLVMTargetRef, arena_alloc((*c).arena, sizeof(*LLVMTargetRef))); + let message = cast(**i8, null); + let result = LLVMGetTargetFromTriple(triple, target_ref, message); + if result != 0 { + printf("Target output: %s\n", *message); + LLVMDisposeMessage(*message); + }; + let target_machine = LLVMCreateTargetMachine( + *target_ref, + triple, + "", + "", + LLVMCodeGenLevelDefault, + LLVMRelocDefault, + LLVMCodeModelDefault, + ); + LLVMDisposeMessage(triple); + result = LLVMVerifyModule((*c).llvm_module, LLVMAbortProcessAction, message); + if result != 0 { + printf("Verification output: %s\n", *message); + LLVMDisposeMessage(*message); + }; + + /* Generate the object file */ + let filename = "bootstrap_output.o"; + LLVMTargetMachineEmitToFile( + target_machine, + (*c).llvm_module, + filename, + LLVMObjectFile, + cast(**i8, null), + ); + LLVMDisposeTargetMachine(target_machine); + printf("Object file generated: %s\n", filename); + + return 0; +}; + +let codegen_deinit = (c: *codegen) => void { + LLVMDisposeModule((*c).llvm_module); + LLVMShutdown(); + LLVMDisposeBuilder((*c).builder); + return; +}; diff --git a/src/bootstrap/codegen.src b/src/bootstrap/codegen.src deleted file mode 100644 index 7059508..0000000 --- a/src/bootstrap/codegen.src +++ /dev/null @@ -1,187 +0,0 @@ -import "llvm.src"; - -let codegen = struct { - llvm_module: LLVMModuleRef, - llvm_context: LLVMContextRef, - builder: LLVMBuilderRef, - arena: *arena, -}; - -let codegen_init = (alloc: *arena) => *codegen { - LLVMInitializeAllTargetInfos(); - LLVMInitializeAllTargetMCs(); - LLVMInitializeAllTargets(); - LLVMInitializeAllAsmPrinters(); - LLVMInitializeAllAsmParsers(); - - let module = LLVMModuleCreateWithName("module"); - let context = LLVMGetGlobalContext(); - let builder = LLVMCreateBuilder(); - - let c = cast(*codegen, arena_alloc(alloc, sizeof(codegen))); - - (*c).llvm_module = module; - (*c).llvm_context = context; - (*c).builder = builder; - (*c).arena = alloc; - - return c; -}; - -let create_node = (c: *codegen, n: Node) => *Node { - let res = cast(*Node, arena_alloc((*c).arena, sizeof(Node))); - *res = n; - return res; -}; - -let Variable = struct { - value: LLVMValueRef, - type: LLVMTypeRef, - node: *Node, - node_type: *Node, - stack_level: *i64, -}; - -let codegen_create_variable = (c: *codegen, variable: Variable) => *Variable { - let v = cast(*Variable, arena_alloc((*c).arena, sizeof(Variable))); - *v = variable; - return v; -}; - -let codegen_generate_literal = (c: *codegen, literal_val: LLVMValueRef, name: *i8, node: *Node, node_type: *Node) => *Variable { - /* TODO: Global */ - let v = Variable{}; - v.value = literal_val; - v.type = cast(LLVMTypeRef, null); - v.stack_level = cast(*i64, null); - v.node = node; - v.node_type = node_type; - return codegen_create_variable(c, v); -}; - -let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: *i8) => *Variable { - if ((*expression).type == NODE_PRIMARY_EXPRESSION_NUMBER) { - let n = (*cast(*NODE_PRIMARY_EXPRESSION_NUMBER_DATA, (*expression).data)).value; - - printf("X: %d\n", n); - - let node_type = Node{}; - node_type.type = NODE_TYPE_SIMPLE_TYPE; - - let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*c).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA))); - (*d).name = "i64"; - (*d).underlying_type = cast(*Node, null); - node_type.data = cast(*void, d); - - return codegen_generate_literal(c, LLVMConstInt(LLVMInt64Type(), n, 0), name, expression, create_node(c, node_type)); - }; - - if ((*expression).type == NODE_FUNCTION_DEFINITION) { - printf("ASS %d\n", (*expression).type); - assert(false); /* TODO */ - printf("ERT\n"); - }; - - assert(false); - - return cast(*Variable, null); -}; - -let codegen_generate_assignment_statement = (c: *codegen, stmt: *NODE_ASSIGNMENT_STATEMENT_DATA) => i64 { - let lhs = *((*stmt).lhs); - let prhs = (*stmt).rhs; - - if (lhs.type == NODE_PRIMARY_EXPRESSION_IDENTIFIER) { - let identifier = (*cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, lhs.data)).name; - printf("XX %s\n", identifier); - let variable = codegen_generate_expression_value(c, prhs, identifier); - assert(variable != cast(*Variable, null)); - return 0; - }; - - assert(false); - return 0; -}; - -let codegen_generate_statement = (c: *codegen, statement: *Node) => i64 { - let stmt = *statement; - assert(stmt.type == NODE_ASSIGNMENT_STATEMENT); /* TODO: generate other node types */ - - let res = codegen_generate_assignment_statement(c, cast(*NODE_ASSIGNMENT_STATEMENT_DATA, stmt.data)); - if res != 0 { - return 1; - }; - printf("STMT: %d\n", stmt.type); - return 0; -}; - -let codegen_generate = (c: *codegen, ast: *Node) => i64 { - assert((*ast).type == NODE_PROGRAM); - - let program = *cast(*NODE_PROGRAM_DATA, (*ast).data); - - let i = 0; - while i < program.statements_len { - let stmt = *(program.statements + cast(**Node, i)); - - let res = codegen_generate_statement(c, stmt); - if res != 0 { - return 1; - }; - - i = i + 1; - }; - - return 0; -}; - -let codegen_compile = (c: *codegen) => i64 { - /* Dump module */ - LLVMDumpModule((*c).llvm_module); - - /* Generate code */ - let triple = LLVMGetDefaultTargetTriple(); - let target_ref = cast(*LLVMTargetRef, arena_alloc((*c).arena, sizeof(*LLVMTargetRef))); - let message = cast(**i8, null); - let result = LLVMGetTargetFromTriple(triple, target_ref, message); - if result != 0 { - printf("Target output: %s\n", *message); - LLVMDisposeMessage(*message); - }; - let target_machine = LLVMCreateTargetMachine( - *target_ref, - triple, - "", - "", - LLVMCodeGenLevelDefault, - LLVMRelocDefault, - LLVMCodeModelDefault, - ); - LLVMDisposeMessage(triple); - result = LLVMVerifyModule((*c).llvm_module, LLVMAbortProcessAction, message); - if result != 0 { - printf("Verification output: %s\n", *message); - LLVMDisposeMessage(*message); - }; - - /* Generate the object file */ - let filename = "bootstrap_output.o"; - LLVMTargetMachineEmitToFile( - target_machine, - (*c).llvm_module, - filename, - LLVMObjectFile, - cast(**i8, null), - ); - LLVMDisposeTargetMachine(target_machine); - printf("Object file generated: %s\n", filename); - - return 0; -}; - -let codegen_deinit = (c: *codegen) => void { - LLVMDisposeModule((*c).llvm_module); - LLVMShutdown(); - LLVMDisposeBuilder((*c).builder); - return; -}; diff --git a/src/bootstrap/llvm.pry b/src/bootstrap/llvm.pry new file mode 100644 index 0000000..8cd600f --- /dev/null +++ b/src/bootstrap/llvm.pry @@ -0,0 +1,289 @@ +extern LLVMInitializeAArch64TargetInfo = () => void; +extern LLVMInitializeAMDGPUTargetInfo = () => void; +extern LLVMInitializeARMTargetInfo = () => void; +extern LLVMInitializeAVRTargetInfo = () => void; +extern LLVMInitializeBPFTargetInfo = () => void; +extern LLVMInitializeHexagonTargetInfo = () => void; +extern LLVMInitializeLanaiTargetInfo = () => void; +extern LLVMInitializeLoongArchTargetInfo = () => void; +extern LLVMInitializeMipsTargetInfo = () => void; +extern LLVMInitializeMSP430TargetInfo = () => void; +extern LLVMInitializeNVPTXTargetInfo = () => void; +extern LLVMInitializePowerPCTargetInfo = () => void; +extern LLVMInitializeRISCVTargetInfo = () => void; +extern LLVMInitializeSparcTargetInfo = () => void; +extern LLVMInitializeSystemZTargetInfo = () => void; +extern LLVMInitializeVETargetInfo = () => void; +extern LLVMInitializeWebAssemblyTargetInfo = () => void; +extern LLVMInitializeX86TargetInfo = () => void; +extern LLVMInitializeXCoreTargetInfo = () => void; + +let LLVMInitializeAllTargetInfos = () => void { + LLVMInitializeAArch64TargetInfo(); + LLVMInitializeAMDGPUTargetInfo(); + LLVMInitializeARMTargetInfo(); + LLVMInitializeAVRTargetInfo(); + LLVMInitializeBPFTargetInfo(); + LLVMInitializeHexagonTargetInfo(); + LLVMInitializeLanaiTargetInfo(); + LLVMInitializeLoongArchTargetInfo(); + LLVMInitializeMipsTargetInfo(); + LLVMInitializeMSP430TargetInfo(); + LLVMInitializeNVPTXTargetInfo(); + LLVMInitializePowerPCTargetInfo(); + LLVMInitializeRISCVTargetInfo(); + LLVMInitializeSparcTargetInfo(); + LLVMInitializeSystemZTargetInfo(); + LLVMInitializeVETargetInfo(); + LLVMInitializeWebAssemblyTargetInfo(); + LLVMInitializeX86TargetInfo(); + LLVMInitializeXCoreTargetInfo(); + return; +}; + +extern LLVMInitializeAArch64Target = () => void; +extern LLVMInitializeAMDGPUTarget = () => void; +extern LLVMInitializeARMTarget = () => void; +extern LLVMInitializeAVRTarget = () => void; +extern LLVMInitializeBPFTarget = () => void; +extern LLVMInitializeHexagonTarget = () => void; +extern LLVMInitializeLanaiTarget = () => void; +extern LLVMInitializeLoongArchTarget = () => void; +extern LLVMInitializeMipsTarget = () => void; +extern LLVMInitializeMSP430Target = () => void; +extern LLVMInitializeNVPTXTarget = () => void; +extern LLVMInitializePowerPCTarget = () => void; +extern LLVMInitializeRISCVTarget = () => void; +extern LLVMInitializeSparcTarget = () => void; +extern LLVMInitializeSystemZTarget = () => void; +extern LLVMInitializeVETarget = () => void; +extern LLVMInitializeWebAssemblyTarget = () => void; +extern LLVMInitializeX86Target = () => void; +extern LLVMInitializeXCoreTarget = () => void; + +let LLVMInitializeAllTargets = () => void { + LLVMInitializeAArch64Target(); + LLVMInitializeAMDGPUTarget(); + LLVMInitializeARMTarget(); + LLVMInitializeAVRTarget(); + LLVMInitializeBPFTarget(); + LLVMInitializeHexagonTarget(); + LLVMInitializeLanaiTarget(); + LLVMInitializeLoongArchTarget(); + LLVMInitializeMipsTarget(); + LLVMInitializeMSP430Target(); + LLVMInitializeNVPTXTarget(); + LLVMInitializePowerPCTarget(); + LLVMInitializeRISCVTarget(); + LLVMInitializeSparcTarget(); + LLVMInitializeSystemZTarget(); + LLVMInitializeVETarget(); + LLVMInitializeWebAssemblyTarget(); + LLVMInitializeX86Target(); + LLVMInitializeXCoreTarget(); + return; +}; + +extern LLVMInitializeAArch64TargetMC = () => void; +extern LLVMInitializeAMDGPUTargetMC = () => void; +extern LLVMInitializeARMTargetMC = () => void; +extern LLVMInitializeAVRTargetMC = () => void; +extern LLVMInitializeBPFTargetMC = () => void; +extern LLVMInitializeHexagonTargetMC = () => void; +extern LLVMInitializeLanaiTargetMC = () => void; +extern LLVMInitializeLoongArchTargetMC = () => void; +extern LLVMInitializeMipsTargetMC = () => void; +extern LLVMInitializeMSP430TargetMC = () => void; +extern LLVMInitializeNVPTXTargetMC = () => void; +extern LLVMInitializePowerPCTargetMC = () => void; +extern LLVMInitializeRISCVTargetMC = () => void; +extern LLVMInitializeSparcTargetMC = () => void; +extern LLVMInitializeSystemZTargetMC = () => void; +extern LLVMInitializeVETargetMC = () => void; +extern LLVMInitializeWebAssemblyTargetMC = () => void; +extern LLVMInitializeX86TargetMC = () => void; +extern LLVMInitializeXCoreTargetMC = () => void; + +let LLVMInitializeAllTargetMCs = () => void { + LLVMInitializeAArch64TargetMC(); + LLVMInitializeAMDGPUTargetMC(); + LLVMInitializeARMTargetMC(); + LLVMInitializeAVRTargetMC(); + LLVMInitializeBPFTargetMC(); + LLVMInitializeHexagonTargetMC(); + LLVMInitializeLanaiTargetMC(); + LLVMInitializeLoongArchTargetMC(); + LLVMInitializeMipsTargetMC(); + LLVMInitializeMSP430TargetMC(); + LLVMInitializeNVPTXTargetMC(); + LLVMInitializePowerPCTargetMC(); + LLVMInitializeRISCVTargetMC(); + LLVMInitializeSparcTargetMC(); + LLVMInitializeSystemZTargetMC(); + LLVMInitializeVETargetMC(); + LLVMInitializeWebAssemblyTargetMC(); + LLVMInitializeX86TargetMC(); + LLVMInitializeXCoreTargetMC(); + return; +}; + +extern LLVMInitializeAArch64AsmPrinter = () => void; +extern LLVMInitializeAMDGPUAsmPrinter = () => void; +extern LLVMInitializeARMAsmPrinter = () => void; +extern LLVMInitializeAVRAsmPrinter = () => void; +extern LLVMInitializeBPFAsmPrinter = () => void; +extern LLVMInitializeHexagonAsmPrinter = () => void; +extern LLVMInitializeLanaiAsmPrinter = () => void; +extern LLVMInitializeLoongArchAsmPrinter = () => void; +extern LLVMInitializeMipsAsmPrinter = () => void; +extern LLVMInitializeMSP430AsmPrinter = () => void; +extern LLVMInitializeNVPTXAsmPrinter = () => void; +extern LLVMInitializePowerPCAsmPrinter = () => void; +extern LLVMInitializeRISCVAsmPrinter = () => void; +extern LLVMInitializeSparcAsmPrinter = () => void; +extern LLVMInitializeSystemZAsmPrinter = () => void; +extern LLVMInitializeVEAsmPrinter = () => void; +extern LLVMInitializeWebAssemblyAsmPrinter = () => void; +extern LLVMInitializeX86AsmPrinter = () => void; +extern LLVMInitializeXCoreAsmPrinter = () => void; + +let LLVMInitializeAllAsmPrinters = () => void { + LLVMInitializeAArch64AsmPrinter(); + LLVMInitializeAMDGPUAsmPrinter(); + LLVMInitializeARMAsmPrinter(); + LLVMInitializeAVRAsmPrinter(); + LLVMInitializeBPFAsmPrinter(); + LLVMInitializeHexagonAsmPrinter(); + LLVMInitializeLanaiAsmPrinter(); + LLVMInitializeLoongArchAsmPrinter(); + LLVMInitializeMipsAsmPrinter(); + LLVMInitializeMSP430AsmPrinter(); + LLVMInitializeNVPTXAsmPrinter(); + LLVMInitializePowerPCAsmPrinter(); + LLVMInitializeRISCVAsmPrinter(); + LLVMInitializeSparcAsmPrinter(); + LLVMInitializeSystemZAsmPrinter(); + LLVMInitializeVEAsmPrinter(); + LLVMInitializeWebAssemblyAsmPrinter(); + LLVMInitializeX86AsmPrinter(); + LLVMInitializeXCoreAsmPrinter(); + return; +}; + +extern LLVMInitializeAArch64AsmParser = () => void; +extern LLVMInitializeAMDGPUAsmParser = () => void; +extern LLVMInitializeARMAsmParser = () => void; +extern LLVMInitializeAVRAsmParser = () => void; +extern LLVMInitializeBPFAsmParser = () => void; +extern LLVMInitializeHexagonAsmParser = () => void; +extern LLVMInitializeLanaiAsmParser = () => void; +extern LLVMInitializeLoongArchAsmParser = () => void; +extern LLVMInitializeMipsAsmParser = () => void; +extern LLVMInitializeMSP430AsmParser = () => void; +extern LLVMInitializePowerPCAsmParser = () => void; +extern LLVMInitializeRISCVAsmParser = () => void; +extern LLVMInitializeSparcAsmParser = () => void; +extern LLVMInitializeSystemZAsmParser = () => void; +extern LLVMInitializeVEAsmParser = () => void; +extern LLVMInitializeWebAssemblyAsmParser = () => void; +extern LLVMInitializeX86AsmParser = () => void; + +let LLVMInitializeAllAsmParsers = () => void { + LLVMInitializeAArch64AsmParser(); + LLVMInitializeAMDGPUAsmParser(); + LLVMInitializeARMAsmParser(); + LLVMInitializeAVRAsmParser(); + LLVMInitializeBPFAsmParser(); + LLVMInitializeHexagonAsmParser(); + LLVMInitializeLanaiAsmParser(); + LLVMInitializeLoongArchAsmParser(); + LLVMInitializeMipsAsmParser(); + LLVMInitializeMSP430AsmParser(); + LLVMInitializePowerPCAsmParser(); + LLVMInitializeRISCVAsmParser(); + LLVMInitializeSparcAsmParser(); + LLVMInitializeSystemZAsmParser(); + LLVMInitializeVEAsmParser(); + LLVMInitializeWebAssemblyAsmParser(); + LLVMInitializeX86AsmParser(); + return; +}; + +extern LLVMInitializeAArch64Disassembler = () => void; +extern LLVMInitializeAMDGPUDisassembler = () => void; +extern LLVMInitializeARMDisassembler = () => void; +extern LLVMInitializeAVRDisassembler = () => void; +extern LLVMInitializeBPFDisassembler = () => void; +extern LLVMInitializeHexagonDisassembler = () => void; +extern LLVMInitializeLanaiDisassembler = () => void; +extern LLVMInitializeLoongArchDisassembler = () => void; +extern LLVMInitializeMipsDisassembler = () => void; +extern LLVMInitializeMSP430Disassembler = () => void; +extern LLVMInitializePowerPCDisassembler = () => void; +extern LLVMInitializeRISCVDisassembler = () => void; +extern LLVMInitializeSparcDisassembler = () => void; +extern LLVMInitializeSystemZDisassembler = () => void; +extern LLVMInitializeVEDisassembler = () => void; +extern LLVMInitializeWebAssemblyDisassembler = () => void; +extern LLVMInitializeX86Disassembler = () => void; +extern LLVMInitializeXCoreDisassembler = () => void; + +let LLVMInitializeAllDisassemblers = () => void { + LLVMInitializeAArch64Disassembler(); + LLVMInitializeAMDGPUDisassembler(); + LLVMInitializeARMDisassembler(); + LLVMInitializeAVRDisassembler(); + LLVMInitializeBPFDisassembler(); + LLVMInitializeHexagonDisassembler(); + LLVMInitializeLanaiDisassembler(); + LLVMInitializeLoongArchDisassembler(); + LLVMInitializeMipsDisassembler(); + LLVMInitializeMSP430Disassembler(); + LLVMInitializePowerPCDisassembler(); + LLVMInitializeRISCVDisassembler(); + LLVMInitializeSparcDisassembler(); + LLVMInitializeSystemZDisassembler(); + LLVMInitializeVEDisassembler(); + LLVMInitializeWebAssemblyDisassembler(); + LLVMInitializeX86Disassembler(); + LLVMInitializeXCoreDisassembler(); + return; +}; + +let LLVMBuilderRef = newtype *void; +let LLVMModuleRef = newtype *void; +let LLVMTargetMachineRef = newtype *void; +let LLVMContextRef = newtype *void; +let LLVMTargetRef = newtype *void; + +let LLVMValueRef = newtype *void; +let LLVMTypeRef = newtype *void; + +extern LLVMConstInt = (LLVMTypeRef, i64, i64) => LLVMValueRef; +extern LLVMInt64Type = () => LLVMTypeRef; + +extern LLVMModuleCreateWithName = (*i8) => LLVMModuleRef; +extern LLVMGetGlobalContext = () => LLVMContextRef; +extern LLVMCreateBuilder = () => LLVMBuilderRef; +extern LLVMDisposeModule = (LLVMModuleRef) => void; +extern LLVMShutdown = () => void; +extern LLVMDisposeBuilder = (LLVMBuilderRef) => void; + +extern LLVMDumpModule = (LLVMModuleRef) => void; +extern LLVMGetDefaultTargetTriple = () => *i8; +extern LLVMGetTargetFromTriple = (*i8, *LLVMTargetRef, **i8) => i64; +extern LLVMDisposeMessage = (*i8) => void; +extern LLVMCreateTargetMachine = (LLVMTargetRef, *i8, *i8, *i8, i64, i64, i64) => LLVMTargetMachineRef; +extern LLVMDisposeTargetMachine = (LLVMTargetMachineRef) => void; + +let LLVMCodeGenLevelDefault = 2; +let LLVMRelocDefault = 0; +let LLVMCodeModelDefault = 0; + +extern LLVMVerifyModule = (LLVMModuleRef, i64, **i8) => i64; + +let LLVMAbortProcessAction = 0; + +extern LLVMTargetMachineEmitToFile = (LLVMTargetMachineRef, LLVMModuleRef, *i8, i64, **i8) => i64; + +let LLVMObjectFile = 1; diff --git a/src/bootstrap/llvm.src b/src/bootstrap/llvm.src deleted file mode 100644 index 8cd600f..0000000 --- a/src/bootstrap/llvm.src +++ /dev/null @@ -1,289 +0,0 @@ -extern LLVMInitializeAArch64TargetInfo = () => void; -extern LLVMInitializeAMDGPUTargetInfo = () => void; -extern LLVMInitializeARMTargetInfo = () => void; -extern LLVMInitializeAVRTargetInfo = () => void; -extern LLVMInitializeBPFTargetInfo = () => void; -extern LLVMInitializeHexagonTargetInfo = () => void; -extern LLVMInitializeLanaiTargetInfo = () => void; -extern LLVMInitializeLoongArchTargetInfo = () => void; -extern LLVMInitializeMipsTargetInfo = () => void; -extern LLVMInitializeMSP430TargetInfo = () => void; -extern LLVMInitializeNVPTXTargetInfo = () => void; -extern LLVMInitializePowerPCTargetInfo = () => void; -extern LLVMInitializeRISCVTargetInfo = () => void; -extern LLVMInitializeSparcTargetInfo = () => void; -extern LLVMInitializeSystemZTargetInfo = () => void; -extern LLVMInitializeVETargetInfo = () => void; -extern LLVMInitializeWebAssemblyTargetInfo = () => void; -extern LLVMInitializeX86TargetInfo = () => void; -extern LLVMInitializeXCoreTargetInfo = () => void; - -let LLVMInitializeAllTargetInfos = () => void { - LLVMInitializeAArch64TargetInfo(); - LLVMInitializeAMDGPUTargetInfo(); - LLVMInitializeARMTargetInfo(); - LLVMInitializeAVRTargetInfo(); - LLVMInitializeBPFTargetInfo(); - LLVMInitializeHexagonTargetInfo(); - LLVMInitializeLanaiTargetInfo(); - LLVMInitializeLoongArchTargetInfo(); - LLVMInitializeMipsTargetInfo(); - LLVMInitializeMSP430TargetInfo(); - LLVMInitializeNVPTXTargetInfo(); - LLVMInitializePowerPCTargetInfo(); - LLVMInitializeRISCVTargetInfo(); - LLVMInitializeSparcTargetInfo(); - LLVMInitializeSystemZTargetInfo(); - LLVMInitializeVETargetInfo(); - LLVMInitializeWebAssemblyTargetInfo(); - LLVMInitializeX86TargetInfo(); - LLVMInitializeXCoreTargetInfo(); - return; -}; - -extern LLVMInitializeAArch64Target = () => void; -extern LLVMInitializeAMDGPUTarget = () => void; -extern LLVMInitializeARMTarget = () => void; -extern LLVMInitializeAVRTarget = () => void; -extern LLVMInitializeBPFTarget = () => void; -extern LLVMInitializeHexagonTarget = () => void; -extern LLVMInitializeLanaiTarget = () => void; -extern LLVMInitializeLoongArchTarget = () => void; -extern LLVMInitializeMipsTarget = () => void; -extern LLVMInitializeMSP430Target = () => void; -extern LLVMInitializeNVPTXTarget = () => void; -extern LLVMInitializePowerPCTarget = () => void; -extern LLVMInitializeRISCVTarget = () => void; -extern LLVMInitializeSparcTarget = () => void; -extern LLVMInitializeSystemZTarget = () => void; -extern LLVMInitializeVETarget = () => void; -extern LLVMInitializeWebAssemblyTarget = () => void; -extern LLVMInitializeX86Target = () => void; -extern LLVMInitializeXCoreTarget = () => void; - -let LLVMInitializeAllTargets = () => void { - LLVMInitializeAArch64Target(); - LLVMInitializeAMDGPUTarget(); - LLVMInitializeARMTarget(); - LLVMInitializeAVRTarget(); - LLVMInitializeBPFTarget(); - LLVMInitializeHexagonTarget(); - LLVMInitializeLanaiTarget(); - LLVMInitializeLoongArchTarget(); - LLVMInitializeMipsTarget(); - LLVMInitializeMSP430Target(); - LLVMInitializeNVPTXTarget(); - LLVMInitializePowerPCTarget(); - LLVMInitializeRISCVTarget(); - LLVMInitializeSparcTarget(); - LLVMInitializeSystemZTarget(); - LLVMInitializeVETarget(); - LLVMInitializeWebAssemblyTarget(); - LLVMInitializeX86Target(); - LLVMInitializeXCoreTarget(); - return; -}; - -extern LLVMInitializeAArch64TargetMC = () => void; -extern LLVMInitializeAMDGPUTargetMC = () => void; -extern LLVMInitializeARMTargetMC = () => void; -extern LLVMInitializeAVRTargetMC = () => void; -extern LLVMInitializeBPFTargetMC = () => void; -extern LLVMInitializeHexagonTargetMC = () => void; -extern LLVMInitializeLanaiTargetMC = () => void; -extern LLVMInitializeLoongArchTargetMC = () => void; -extern LLVMInitializeMipsTargetMC = () => void; -extern LLVMInitializeMSP430TargetMC = () => void; -extern LLVMInitializeNVPTXTargetMC = () => void; -extern LLVMInitializePowerPCTargetMC = () => void; -extern LLVMInitializeRISCVTargetMC = () => void; -extern LLVMInitializeSparcTargetMC = () => void; -extern LLVMInitializeSystemZTargetMC = () => void; -extern LLVMInitializeVETargetMC = () => void; -extern LLVMInitializeWebAssemblyTargetMC = () => void; -extern LLVMInitializeX86TargetMC = () => void; -extern LLVMInitializeXCoreTargetMC = () => void; - -let LLVMInitializeAllTargetMCs = () => void { - LLVMInitializeAArch64TargetMC(); - LLVMInitializeAMDGPUTargetMC(); - LLVMInitializeARMTargetMC(); - LLVMInitializeAVRTargetMC(); - LLVMInitializeBPFTargetMC(); - LLVMInitializeHexagonTargetMC(); - LLVMInitializeLanaiTargetMC(); - LLVMInitializeLoongArchTargetMC(); - LLVMInitializeMipsTargetMC(); - LLVMInitializeMSP430TargetMC(); - LLVMInitializeNVPTXTargetMC(); - LLVMInitializePowerPCTargetMC(); - LLVMInitializeRISCVTargetMC(); - LLVMInitializeSparcTargetMC(); - LLVMInitializeSystemZTargetMC(); - LLVMInitializeVETargetMC(); - LLVMInitializeWebAssemblyTargetMC(); - LLVMInitializeX86TargetMC(); - LLVMInitializeXCoreTargetMC(); - return; -}; - -extern LLVMInitializeAArch64AsmPrinter = () => void; -extern LLVMInitializeAMDGPUAsmPrinter = () => void; -extern LLVMInitializeARMAsmPrinter = () => void; -extern LLVMInitializeAVRAsmPrinter = () => void; -extern LLVMInitializeBPFAsmPrinter = () => void; -extern LLVMInitializeHexagonAsmPrinter = () => void; -extern LLVMInitializeLanaiAsmPrinter = () => void; -extern LLVMInitializeLoongArchAsmPrinter = () => void; -extern LLVMInitializeMipsAsmPrinter = () => void; -extern LLVMInitializeMSP430AsmPrinter = () => void; -extern LLVMInitializeNVPTXAsmPrinter = () => void; -extern LLVMInitializePowerPCAsmPrinter = () => void; -extern LLVMInitializeRISCVAsmPrinter = () => void; -extern LLVMInitializeSparcAsmPrinter = () => void; -extern LLVMInitializeSystemZAsmPrinter = () => void; -extern LLVMInitializeVEAsmPrinter = () => void; -extern LLVMInitializeWebAssemblyAsmPrinter = () => void; -extern LLVMInitializeX86AsmPrinter = () => void; -extern LLVMInitializeXCoreAsmPrinter = () => void; - -let LLVMInitializeAllAsmPrinters = () => void { - LLVMInitializeAArch64AsmPrinter(); - LLVMInitializeAMDGPUAsmPrinter(); - LLVMInitializeARMAsmPrinter(); - LLVMInitializeAVRAsmPrinter(); - LLVMInitializeBPFAsmPrinter(); - LLVMInitializeHexagonAsmPrinter(); - LLVMInitializeLanaiAsmPrinter(); - LLVMInitializeLoongArchAsmPrinter(); - LLVMInitializeMipsAsmPrinter(); - LLVMInitializeMSP430AsmPrinter(); - LLVMInitializeNVPTXAsmPrinter(); - LLVMInitializePowerPCAsmPrinter(); - LLVMInitializeRISCVAsmPrinter(); - LLVMInitializeSparcAsmPrinter(); - LLVMInitializeSystemZAsmPrinter(); - LLVMInitializeVEAsmPrinter(); - LLVMInitializeWebAssemblyAsmPrinter(); - LLVMInitializeX86AsmPrinter(); - LLVMInitializeXCoreAsmPrinter(); - return; -}; - -extern LLVMInitializeAArch64AsmParser = () => void; -extern LLVMInitializeAMDGPUAsmParser = () => void; -extern LLVMInitializeARMAsmParser = () => void; -extern LLVMInitializeAVRAsmParser = () => void; -extern LLVMInitializeBPFAsmParser = () => void; -extern LLVMInitializeHexagonAsmParser = () => void; -extern LLVMInitializeLanaiAsmParser = () => void; -extern LLVMInitializeLoongArchAsmParser = () => void; -extern LLVMInitializeMipsAsmParser = () => void; -extern LLVMInitializeMSP430AsmParser = () => void; -extern LLVMInitializePowerPCAsmParser = () => void; -extern LLVMInitializeRISCVAsmParser = () => void; -extern LLVMInitializeSparcAsmParser = () => void; -extern LLVMInitializeSystemZAsmParser = () => void; -extern LLVMInitializeVEAsmParser = () => void; -extern LLVMInitializeWebAssemblyAsmParser = () => void; -extern LLVMInitializeX86AsmParser = () => void; - -let LLVMInitializeAllAsmParsers = () => void { - LLVMInitializeAArch64AsmParser(); - LLVMInitializeAMDGPUAsmParser(); - LLVMInitializeARMAsmParser(); - LLVMInitializeAVRAsmParser(); - LLVMInitializeBPFAsmParser(); - LLVMInitializeHexagonAsmParser(); - LLVMInitializeLanaiAsmParser(); - LLVMInitializeLoongArchAsmParser(); - LLVMInitializeMipsAsmParser(); - LLVMInitializeMSP430AsmParser(); - LLVMInitializePowerPCAsmParser(); - LLVMInitializeRISCVAsmParser(); - LLVMInitializeSparcAsmParser(); - LLVMInitializeSystemZAsmParser(); - LLVMInitializeVEAsmParser(); - LLVMInitializeWebAssemblyAsmParser(); - LLVMInitializeX86AsmParser(); - return; -}; - -extern LLVMInitializeAArch64Disassembler = () => void; -extern LLVMInitializeAMDGPUDisassembler = () => void; -extern LLVMInitializeARMDisassembler = () => void; -extern LLVMInitializeAVRDisassembler = () => void; -extern LLVMInitializeBPFDisassembler = () => void; -extern LLVMInitializeHexagonDisassembler = () => void; -extern LLVMInitializeLanaiDisassembler = () => void; -extern LLVMInitializeLoongArchDisassembler = () => void; -extern LLVMInitializeMipsDisassembler = () => void; -extern LLVMInitializeMSP430Disassembler = () => void; -extern LLVMInitializePowerPCDisassembler = () => void; -extern LLVMInitializeRISCVDisassembler = () => void; -extern LLVMInitializeSparcDisassembler = () => void; -extern LLVMInitializeSystemZDisassembler = () => void; -extern LLVMInitializeVEDisassembler = () => void; -extern LLVMInitializeWebAssemblyDisassembler = () => void; -extern LLVMInitializeX86Disassembler = () => void; -extern LLVMInitializeXCoreDisassembler = () => void; - -let LLVMInitializeAllDisassemblers = () => void { - LLVMInitializeAArch64Disassembler(); - LLVMInitializeAMDGPUDisassembler(); - LLVMInitializeARMDisassembler(); - LLVMInitializeAVRDisassembler(); - LLVMInitializeBPFDisassembler(); - LLVMInitializeHexagonDisassembler(); - LLVMInitializeLanaiDisassembler(); - LLVMInitializeLoongArchDisassembler(); - LLVMInitializeMipsDisassembler(); - LLVMInitializeMSP430Disassembler(); - LLVMInitializePowerPCDisassembler(); - LLVMInitializeRISCVDisassembler(); - LLVMInitializeSparcDisassembler(); - LLVMInitializeSystemZDisassembler(); - LLVMInitializeVEDisassembler(); - LLVMInitializeWebAssemblyDisassembler(); - LLVMInitializeX86Disassembler(); - LLVMInitializeXCoreDisassembler(); - return; -}; - -let LLVMBuilderRef = newtype *void; -let LLVMModuleRef = newtype *void; -let LLVMTargetMachineRef = newtype *void; -let LLVMContextRef = newtype *void; -let LLVMTargetRef = newtype *void; - -let LLVMValueRef = newtype *void; -let LLVMTypeRef = newtype *void; - -extern LLVMConstInt = (LLVMTypeRef, i64, i64) => LLVMValueRef; -extern LLVMInt64Type = () => LLVMTypeRef; - -extern LLVMModuleCreateWithName = (*i8) => LLVMModuleRef; -extern LLVMGetGlobalContext = () => LLVMContextRef; -extern LLVMCreateBuilder = () => LLVMBuilderRef; -extern LLVMDisposeModule = (LLVMModuleRef) => void; -extern LLVMShutdown = () => void; -extern LLVMDisposeBuilder = (LLVMBuilderRef) => void; - -extern LLVMDumpModule = (LLVMModuleRef) => void; -extern LLVMGetDefaultTargetTriple = () => *i8; -extern LLVMGetTargetFromTriple = (*i8, *LLVMTargetRef, **i8) => i64; -extern LLVMDisposeMessage = (*i8) => void; -extern LLVMCreateTargetMachine = (LLVMTargetRef, *i8, *i8, *i8, i64, i64, i64) => LLVMTargetMachineRef; -extern LLVMDisposeTargetMachine = (LLVMTargetMachineRef) => void; - -let LLVMCodeGenLevelDefault = 2; -let LLVMRelocDefault = 0; -let LLVMCodeModelDefault = 0; - -extern LLVMVerifyModule = (LLVMModuleRef, i64, **i8) => i64; - -let LLVMAbortProcessAction = 0; - -extern LLVMTargetMachineEmitToFile = (LLVMTargetMachineRef, LLVMModuleRef, *i8, i64, **i8) => i64; - -let LLVMObjectFile = 1; diff --git a/src/bootstrap/main.pry b/src/bootstrap/main.pry new file mode 100644 index 0000000..29e41ff --- /dev/null +++ b/src/bootstrap/main.pry @@ -0,0 +1,69 @@ +extern fopen = (*i8, *i8) => *i8; +extern fgets = (*i8, i64, *i8) => void; +extern feof = (*i8) => bool; +extern fseek = (*i8, i64, i64) => i64; +extern ftell = (*i8) => i64; +extern fread = (*i8, i64, i64, *i8) => i64; +extern fclose = (*i8) => *i8; + +import "!stdlib.pry"; +import "!mem.pry"; + +let slice = struct { + data: *void, + data_len: i64, +}; + +import "tokenizer.pry"; +import "parser.pry"; +import "codegen.pry"; + +let read_file = (filename: *i8, alloc: *arena) => slice { + let file = fopen(filename, "r"); + + fseek(file, 0, 2); + let file_size = ftell(file); + fseek(file, 0, 0); + + let buf = cast(*i8, arena_alloc(alloc, file_size + 1)); + + let bytes_read = fread(buf, 1, file_size, file); + (*(buf + cast(*i8, bytes_read))) = '\0'; + + fclose(file); + + let sl = slice{}; + sl.data = cast(*void, buf); + sl.data_len = file_size; + return sl; +}; + +let main = (argc: i64, argv: **i8) => i64 { + if argc < 2 { + printf("Need filename!\n"); + return 1; + }; + + let filename = *(argv + cast(**i8, 1)); + + printf("%s\n", filename); + + let alloc = arena_init(999999999); + + let file = read_file(filename, alloc); + + let t = tokenizer_init(alloc, file); + let ts = tokenizer_tokenize(t); + + let p = parser_init(cast(*token, ts.data), ts.data_len, alloc); + let ast = parse(p); + + let c = codegen_init(alloc); + let res = codegen_generate(c, ast); + let res = codegen_compile(c); + codegen_deinit(c); + + arena_free(alloc); + + return 0; +}; diff --git a/src/bootstrap/main.src b/src/bootstrap/main.src deleted file mode 100644 index 571cc03..0000000 --- a/src/bootstrap/main.src +++ /dev/null @@ -1,69 +0,0 @@ -extern fopen = (*i8, *i8) => *i8; -extern fgets = (*i8, i64, *i8) => void; -extern feof = (*i8) => bool; -extern fseek = (*i8, i64, i64) => i64; -extern ftell = (*i8) => i64; -extern fread = (*i8, i64, i64, *i8) => i64; -extern fclose = (*i8) => *i8; - -import "!stdlib.src"; -import "!mem.src"; - -let slice = struct { - data: *void, - data_len: i64, -}; - -import "tokenizer.src"; -import "parser.src"; -import "codegen.src"; - -let read_file = (filename: *i8, alloc: *arena) => slice { - let file = fopen(filename, "r"); - - fseek(file, 0, 2); - let file_size = ftell(file); - fseek(file, 0, 0); - - let buf = cast(*i8, arena_alloc(alloc, file_size + 1)); - - let bytes_read = fread(buf, 1, file_size, file); - (*(buf + cast(*i8, bytes_read))) = '\0'; - - fclose(file); - - let sl = slice{}; - sl.data = cast(*void, buf); - sl.data_len = file_size; - return sl; -}; - -let main = (argc: i64, argv: **i8) => i64 { - if argc < 2 { - printf("Need filename!\n"); - return 1; - }; - - let filename = *(argv + cast(**i8, 1)); - - printf("%s\n", filename); - - let alloc = arena_init(999999999); - - let file = read_file(filename, alloc); - - let t = tokenizer_init(alloc, file); - let ts = tokenizer_tokenize(t); - - let p = parser_init(cast(*token, ts.data), ts.data_len, alloc); - let ast = parse(p); - - let c = codegen_init(alloc); - let res = codegen_generate(c, ast); - let res = codegen_compile(c); - codegen_deinit(c); - - arena_free(alloc); - - return 0; -}; diff --git a/src/bootstrap/parser.pry b/src/bootstrap/parser.pry new file mode 100644 index 0000000..daac296 --- /dev/null +++ b/src/bootstrap/parser.pry @@ -0,0 +1,530 @@ +let Node = struct { + type: i64, + data: *void, +}; + +let NODE_PROGRAM = 1; +let NODE_STATEMENT = 2; +let NODE_ASSIGNMENT_STATEMENT = 3; +let NODE_IMPORT_DECLARATION = 4; +let NODE_FUNCTION_CALL_STATEMENT = 5; +let NODE_IF_STATEMENT = 6; +let NODE_WHILE_STATEMENT = 7; +let NODE_EQUALITY_EXPRESSION = 8; +let NODE_ADDITIVE_EXPRESSION = 9; +let NODE_MULTIPLICATIVE_EXPRESSION = 10; +let NODE_UNARY_EXPRESSION = 11; +let NODE_POSTFIX_EXPRESSION = 12; +let NODE_PRIMARY_EXPRESSION_NUMBER = 13; +let NODE_PRIMARY_EXPRESSION_BOOLEAN = 14; +let NODE_PRIMARY_EXPRESSION_NULL = 15; +let NODE_PRIMARY_EXPRESSION_CHAR = 16; +let NODE_PRIMARY_EXPRESSION_STRING = 17; +let NODE_PRIMARY_EXPRESSION_IDENTIFIER = 18; +let NODE_FUNCTION_DEFINITION = 19; +let NODE_STRUCT_INSTANCIATION = 20; +let NODE_FIELD_ACCESS = 21; +let NODE_TYPE_SIMPLE_TYPE = 22; +let NODE_TYPE_FUNCTION_TYPE = 23; +let NODE_TYPE_POINTER_TYPE = 24; +let NODE_TYPE_STRUCT_TYPE = 25; +let NODE_RETURN_STATEMENT = 26; +let NODE_CAST_STATEMENT = 27; +let NODE_SIZEOF_STATEMENT = 28; +let NODE_BREAK_STATEMENT = 29; +let NODE_CONTINUE_STATEMENT = 30; + +let EQUALITY_EXPRESSION_TYPE_EQ = 0; +let EQUALITY_EXPRESSION_TYPE_NE = 1; +let EQUALITY_EXPRESSION_TYPE_GE = 2; +let EQUALITY_EXPRESSION_TYPE_LE = 3; +let EQUALITY_EXPRESSION_TYPE_LT = 4; +let EQUALITY_EXPRESSION_TYPE_GT = 5; + +let MULTIPLICATIVE_EXPRESSION_TYPE_MUL = 0; +let MULTIPLICATIVE_EXPRESSION_TYPE_DIV = 1; +let MULTIPLICATIVE_EXPRESSION_TYPE_MOD = 2; + +let UNARY_EXPRESSION_TYPE_NOT = 0; +let UNARY_EXPRESSION_TYPE_MINUS = 1; +let UNARY_EXPRESSION_TYPE_STAR = 2; + +let NODE_PROGRAM_DATA = struct { + statements: **Node, + statements_len: i64, +}; + +let NODE_STATEMENT_DATA = struct { + statement: *Node, +}; + +let NODE_ASSIGNMENT_STATEMENT_DATA = struct { + is_declaration: bool, + is_dereference: bool, + lhs: *Node, + rhs: *Node, +}; + +let NODE_IMPORT_DECLARATION_DATA = struct { + filename: *i8, + program: *Node, +}; + +let NODE_FUNCTION_CALL_STATEMENT_DATA = struct { + expression: *Node, + arguments: *Node, + arguments_len: i64, +}; + +let NODE_IF_STATEMENT_DATA = struct { + condition: *Node, + statements: **Node, + statements_len: i64, +}; + +let NODE_WHILE_STATEMENT_DATA = struct { + condition: *Node, + statements: **Node, + statements_len: i64, +}; + +let NODE_EQUALITY_EXPRESSION_DATA = struct { + lhs: *Node, + rhs: *Node, + typ: i64, +}; + +let NODE_ADDITIVE_EXPRESSION_DATA = struct { + addition: bool, + lhs: *Node, + rhs: *Node, +}; + +let NODE_MULTIPLICATIVE_EXPRESSION_DATA = struct { + lhs: *Node, + rhs: *Node, + typ: i64, +}; + +let NODE_UNARY_EXPRESSION_DATA = struct { + typ: i64, + expression: *Node, +}; + +let NODE_POSTFIX_EXPRESSION_DATA = struct { + lhs: *Node, + rhs: *Node, +}; + +let NODE_PRIMARY_EXPRESSION_NUMBER_DATA = struct { + value: i64, +}; + +let NODE_PRIMARY_EXPRESSION_BOOLEAN_DATA = struct { + value: bool, +}; + +let NODE_PRIMARY_EXPRESSION_CHAR_DATA = struct { + value: i8, +}; + +let NODE_PRIMARY_EXPRESSION_STRING_DATA = struct { + value: *i8, +}; + +let NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA = struct { + name: *i8, + type: *Node, +}; + +let NODE_FUNCTION_DEFINITION_DATA = struct { + statements: **Node, + statements_len: i64, + parameters: **Node, + parameters_len: i64, + retur_type: *Node, +}; + +let NODE_STRUCT_INSTANCIATION_DATA = struct { + typ: *i8, +}; + +let NODE_FIELD_ACCESS_DATA = struct { + expression: *Node, + name: *i8, +}; + +let NODE_TYPE_SIMPLE_TYPE_DATA = struct { + name: *i8, + underlying_type: *Node, +}; + +let NODE_TYPE_FUNCTION_TYPE_DATA = struct { + parameters: *Node, + parameters_len: i64, + retur_type: *Node, +}; + +let NODE_TYPE_POINTER_TYPE_DATA = struct { + type: *Node, +}; + +let NODE_TYPE_STRUCT_TYPE_DATA = struct { + fields: *Node, + fields_len: i64, +}; + +let NODE_RETURN_STATEMENT_DATA = struct { + expression: *Node, +}; + +let NODE_CAST_STATEMENT_DATA = struct { + typ: *Node, + expression: *Node, +}; + +let NODE_SIZEOF_STATEMENT_DATA = struct { + typ: *Node, +}; + + +let parser = struct { + tokens: *token, + tokens_len: i64, + + offset: i64, + + arena: *arena, +}; + +extern parser_parse_statement = (*parser) => *Node; +extern parser_parse_expression = (*parser) => *Node; + +let parser_init = (ts: *token, ts_len: i64, ar: *arena) => *parser { + let p = cast(*parser, arena_alloc(ar, sizeof(parser))); + + (*p).tokens = ts; + (*p).tokens_len = ts_len; + (*p).offset = 0; + (*p).arena = ar; + + return p; +}; + +let create_node = (p: *parser, n: Node) => *Node { + let res = cast(*Node, arena_alloc((*p).arena, sizeof(Node))); + *res = n; + return res; +}; + +let parser_peek_token = (p: *parser) => *token { + if (*p).offset >= (*p).tokens_len { + return cast(*token, null); + }; + + return ((*p).tokens + cast(*token, (*p).offset)); +}; + + let parser_consume_token = (p: *parser) => *token { + if (*p).offset >= (*p).tokens_len { + return cast(*token, null); + }; + + let t = ((*p).tokens + cast(*token, (*p).offset)); + (*p).offset = (*p).offset + 1; + return t; +}; + +let parser_accept_token = (p: *parser, t: i64) => *token { + let curr_token = parser_peek_token(p); + if curr_token == cast(*token, null) { + return cast(*token, null); + }; + + if (*curr_token).type == t { + return parser_consume_token(p); + }; + return cast(*token, null); +}; + +let parser_accept_parse = (p: *parser, parsing_func: (*parser) => *Node) => *Node { + let prev_offset = (*p).offset; + let node = parsing_func(p); + if node == cast(*Node, null) { + (*p).offset = prev_offset; + }; + return node; +}; + +/* ReturnStatement ::= RETURN (Expression)? */ +let parser_parse_return_statement = (p: *parser) => *Node { + if parser_accept_token(p, TOKEN_RETURN) == cast(*token, null) { + return cast(*Node, null); + }; + + let maybe_expr = parser_accept_parse(p, parser_parse_expression); + + let d = cast(*NODE_RETURN_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_RETURN_STATEMENT_DATA ))); + (*d).expression = maybe_expr; + + let r = Node{}; + r.type = NODE_RETURN_STATEMENT; + r.data = cast(*void, d); + + return create_node(p, r); +}; + +/* Type ::= IDENTIFIER | FunctionType */ +let parser_parse_type = (p: *parser) => *Node { + /* TODO: Function type */ + let to = parser_consume_token(p); + assert(to != cast(*token, null)); + assert((*to).type == TOKEN_IDENTIFIER); + + let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*p).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA))); + (*d).name = cast(*i8, (*to).data); + (*d).underlying_type = cast(*Node, null); + + let r = Node{}; + r.type = NODE_TYPE_SIMPLE_TYPE; + r.data = cast(*void, d); + + return create_node(p, r); +}; + +/* FunctionParameters ::= IDENTIFIER ":" Type ("," IDENTIFIER ":" Type)* */ +let parser_parse_function_parameters = (p: *parser) => *slice { + /* TODO: Params */ + + let node_list = cast(**Node, arena_alloc((*p).arena, sizeof(**Node) * 20)); + let i = 0; + while true { + if i != 0 { + parser_accept_token(p, TOKEN_COMMA); + }; + let ident = parser_accept_token(p, TOKEN_IDENTIFIER); + if ident == cast(*token, null) { + break; + }; + /* TODO: Rest */ + }; + + let s = cast(*slice, arena_alloc((*p).arena, sizeof(slice))); + (*s).data = cast(*void, node_list); + (*s).data_len = 0; + return s; +}; + +/* FunctionDefinition ::= LPAREN FunctionParameters? RPAREN ARROW IDENTIFIER LBRACE Statement* ReturnStatement SEMICOLON RBRACE */ +let parser_parse_function_definition = (p: *parser) => *Node { + if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) { + return cast(*Node, null); + }; + let params = parser_parse_function_parameters(p); + if params == cast(*slice, null) { + return cast(*Node, null); + }; + if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) { + return cast(*Node, null); + }; + if parser_accept_token(p, TOKEN_ARROW) == cast(*token, null) { + return cast(*Node, null); + }; + let retur_type = parser_parse_type(p); + if retur_type == cast(*Node, null) { + return cast(*Node, null); + }; + if parser_accept_token(p, TOKEN_LBRACE) == cast(*token, null) { + return cast(*Node, null); + }; + + /* TODO: Body */ + let statements = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 100)); + let i = 0; + while true { + let n = parser_accept_parse(p, parser_parse_statement); + if n == cast(*Node, null) { + break; + }; + (*(statements + cast(**Node, i))) = n; + i = i + 1; + }; + + + if parser_accept_token(p, TOKEN_RBRACE) == cast(*token, null) { + return cast(*Node, null); + }; + + + let d = cast(*NODE_FUNCTION_DEFINITION_DATA, arena_alloc((*p).arena, sizeof(NODE_FUNCTION_DEFINITION_DATA))); + (*d).statements = statements; + (*d).statements_len = i; + (*d).parameters = cast(**Node, params.data); + (*d).parameters_len = params.data_len; + (*d).retur_type = cast(*Node, null); + + let n = Node{}; + n.type = NODE_FUNCTION_DEFINITION; + n.data = cast(*void, d); + + return create_node(p, n); +}; + +/* PrimaryExpression ::= NULL | NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | FunctionDefinition | StructDefinition | StructInstantiation | FieldAccess | LPAREN Expression RPAREN */ +let parser_parse_primary_expression = (p: *parser) => *Node { + let stmt = parser_accept_parse(p, parser_parse_function_definition); + if stmt != cast(*Node, null) { + return stmt; + }; + + let tok = parser_consume_token(p); + if tok == cast(*token, null) { + printf("NO TOK\n"); + return cast(*Node, null); + }; + + if (*tok).type == TOKEN_IDENTIFIER { + let d = cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA))); + (*d).name = cast(*i8, (*tok).data); + (*d).type = cast(*Node, null); /* TODO */ + let n = Node{}; + n.type = NODE_PRIMARY_EXPRESSION_IDENTIFIER; + n.data = cast(*void, d); + return create_node(p, n); + }; + + if (*tok).type == TOKEN_NUMBER { + let d = cast(*NODE_PRIMARY_EXPRESSION_NUMBER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_NUMBER_DATA))); + (*d).value = *(cast(*i64, (*tok).data)); + let n = Node{}; + n.type = NODE_PRIMARY_EXPRESSION_NUMBER; + n.data = cast(*void, d); + return create_node(p, n); + }; + + printf("DIFF TYPE: %d\n", (*tok).type); + + return cast(*Node, null); +}; + +/* EqualityExpression ::= AdditiveExpression ("==" | "!=" | "<=" | ">=" | "<" | ">") AdditiveExpression */ +let parser_parse_equality_expression = (p: *parser) => *Node { + /* TODO */ + return cast(*Node, null); +}; + +/* AdditiveExpression ::= MultiplicativeExpression (("+" | "-") MultiplicativeExpression)* */ +let parser_parse_additive_expression = (p: *parser) => *Node { + /* TODO */ + return parser_parse_primary_expression(p); +}; + +/* Expression ::= EqualityExpression | AdditiveExpression */ +let parser_parse_expression = (p: *parser) => *Node { + let ex = parser_accept_parse(p, parser_parse_equality_expression); + if ex != cast(*Node, null) { + return ex; + }; + let ax = parser_accept_parse(p, parser_parse_additive_expression); + if ax != cast(*Node, null) { + return ax; + }; + + return cast(*Node, null); +}; + +/* AssignmentStatement ::= ("let")? ("*")? Expression EQUALS Expression */ +let parse_assignment_statement = (p: *parser) => *Node { + let is_declaration = false; + if parser_accept_token(p, TOKEN_LET) != cast(*token, null) { + printf("IS DECLARATION\n"); + is_declaration = true; + }; + + /* TODO: is_dereference */ + + let lhs = parser_parse_expression(p); /* TODO */ + if lhs == cast(*Node, null) { + printf("ANOTHER BNLL\n"); + return cast(*Node, null); + }; + + if parser_accept_token(p, TOKEN_EQUALS) == cast(*token, null) { + return cast(*Node, null); + }; + + let rhs = parser_parse_expression(p); /* TODO */ + if rhs == cast(*Node, null) { + printf("NUL EXP\n"); + return cast(*Node, null); + }; + + let d = cast(*NODE_ASSIGNMENT_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_ASSIGNMENT_STATEMENT_DATA ))); + (*d).is_declaration = is_declaration; + (*d).is_dereference = false; + (*d).lhs = lhs; + (*d).rhs = rhs; + let n = Node{}; + n.type = NODE_ASSIGNMENT_STATEMENT; + n.data = cast(*void, d); + printf("CONTINUE\n"); + return create_node(p, n); +}; + +/* Statement ::= (AssignmentStatement | ImportDeclaration | ExternDeclaration | CastStatement | SizeOfStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement | "break" | "continue") SEMICOLON */ +let parser_parse_statement = (p: *parser) => *Node { + let assignment = parser_accept_parse(p, parse_assignment_statement); + if assignment != cast(*Node, null) { + if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) { + return cast(*Node, null); + }; + return assignment; + }; + + let retu = parser_accept_parse(p, parser_parse_return_statement); + if retu != cast(*Node, null) { + if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) { + return cast(*Node, null); + }; + return retu; + }; + + + printf("None\n"); + + return cast(*Node, null); +}; + +/* Program ::= Statement+ */ +let parse_program = (p: *parser) => *Node { + let nodes = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 1000)); + + let i = 0; + while (*p).offset < (*p).tokens_len { + let s = parser_parse_statement(p); + assert(s != cast(*Node, null)); + (*(nodes + cast(**Node, i))) = s; + i = i + 1; + }; + + let d = cast(*NODE_PROGRAM_DATA, arena_alloc((*p).arena, sizeof(NODE_PROGRAM_DATA))); + (*d).statements = nodes; + (*d).statements_len = i; + let n = Node{}; + n.type = NODE_PROGRAM; + n.data = cast(*void, d); + return create_node(p, n); +}; + +let parse = (p: *parser) => *Node { + return parse_program(p); +}; + +/* + +For example -2: + +* parsing assignment statement +* parsing ident and num literals + +*/ diff --git a/src/bootstrap/parser.src b/src/bootstrap/parser.src deleted file mode 100644 index daac296..0000000 --- a/src/bootstrap/parser.src +++ /dev/null @@ -1,530 +0,0 @@ -let Node = struct { - type: i64, - data: *void, -}; - -let NODE_PROGRAM = 1; -let NODE_STATEMENT = 2; -let NODE_ASSIGNMENT_STATEMENT = 3; -let NODE_IMPORT_DECLARATION = 4; -let NODE_FUNCTION_CALL_STATEMENT = 5; -let NODE_IF_STATEMENT = 6; -let NODE_WHILE_STATEMENT = 7; -let NODE_EQUALITY_EXPRESSION = 8; -let NODE_ADDITIVE_EXPRESSION = 9; -let NODE_MULTIPLICATIVE_EXPRESSION = 10; -let NODE_UNARY_EXPRESSION = 11; -let NODE_POSTFIX_EXPRESSION = 12; -let NODE_PRIMARY_EXPRESSION_NUMBER = 13; -let NODE_PRIMARY_EXPRESSION_BOOLEAN = 14; -let NODE_PRIMARY_EXPRESSION_NULL = 15; -let NODE_PRIMARY_EXPRESSION_CHAR = 16; -let NODE_PRIMARY_EXPRESSION_STRING = 17; -let NODE_PRIMARY_EXPRESSION_IDENTIFIER = 18; -let NODE_FUNCTION_DEFINITION = 19; -let NODE_STRUCT_INSTANCIATION = 20; -let NODE_FIELD_ACCESS = 21; -let NODE_TYPE_SIMPLE_TYPE = 22; -let NODE_TYPE_FUNCTION_TYPE = 23; -let NODE_TYPE_POINTER_TYPE = 24; -let NODE_TYPE_STRUCT_TYPE = 25; -let NODE_RETURN_STATEMENT = 26; -let NODE_CAST_STATEMENT = 27; -let NODE_SIZEOF_STATEMENT = 28; -let NODE_BREAK_STATEMENT = 29; -let NODE_CONTINUE_STATEMENT = 30; - -let EQUALITY_EXPRESSION_TYPE_EQ = 0; -let EQUALITY_EXPRESSION_TYPE_NE = 1; -let EQUALITY_EXPRESSION_TYPE_GE = 2; -let EQUALITY_EXPRESSION_TYPE_LE = 3; -let EQUALITY_EXPRESSION_TYPE_LT = 4; -let EQUALITY_EXPRESSION_TYPE_GT = 5; - -let MULTIPLICATIVE_EXPRESSION_TYPE_MUL = 0; -let MULTIPLICATIVE_EXPRESSION_TYPE_DIV = 1; -let MULTIPLICATIVE_EXPRESSION_TYPE_MOD = 2; - -let UNARY_EXPRESSION_TYPE_NOT = 0; -let UNARY_EXPRESSION_TYPE_MINUS = 1; -let UNARY_EXPRESSION_TYPE_STAR = 2; - -let NODE_PROGRAM_DATA = struct { - statements: **Node, - statements_len: i64, -}; - -let NODE_STATEMENT_DATA = struct { - statement: *Node, -}; - -let NODE_ASSIGNMENT_STATEMENT_DATA = struct { - is_declaration: bool, - is_dereference: bool, - lhs: *Node, - rhs: *Node, -}; - -let NODE_IMPORT_DECLARATION_DATA = struct { - filename: *i8, - program: *Node, -}; - -let NODE_FUNCTION_CALL_STATEMENT_DATA = struct { - expression: *Node, - arguments: *Node, - arguments_len: i64, -}; - -let NODE_IF_STATEMENT_DATA = struct { - condition: *Node, - statements: **Node, - statements_len: i64, -}; - -let NODE_WHILE_STATEMENT_DATA = struct { - condition: *Node, - statements: **Node, - statements_len: i64, -}; - -let NODE_EQUALITY_EXPRESSION_DATA = struct { - lhs: *Node, - rhs: *Node, - typ: i64, -}; - -let NODE_ADDITIVE_EXPRESSION_DATA = struct { - addition: bool, - lhs: *Node, - rhs: *Node, -}; - -let NODE_MULTIPLICATIVE_EXPRESSION_DATA = struct { - lhs: *Node, - rhs: *Node, - typ: i64, -}; - -let NODE_UNARY_EXPRESSION_DATA = struct { - typ: i64, - expression: *Node, -}; - -let NODE_POSTFIX_EXPRESSION_DATA = struct { - lhs: *Node, - rhs: *Node, -}; - -let NODE_PRIMARY_EXPRESSION_NUMBER_DATA = struct { - value: i64, -}; - -let NODE_PRIMARY_EXPRESSION_BOOLEAN_DATA = struct { - value: bool, -}; - -let NODE_PRIMARY_EXPRESSION_CHAR_DATA = struct { - value: i8, -}; - -let NODE_PRIMARY_EXPRESSION_STRING_DATA = struct { - value: *i8, -}; - -let NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA = struct { - name: *i8, - type: *Node, -}; - -let NODE_FUNCTION_DEFINITION_DATA = struct { - statements: **Node, - statements_len: i64, - parameters: **Node, - parameters_len: i64, - retur_type: *Node, -}; - -let NODE_STRUCT_INSTANCIATION_DATA = struct { - typ: *i8, -}; - -let NODE_FIELD_ACCESS_DATA = struct { - expression: *Node, - name: *i8, -}; - -let NODE_TYPE_SIMPLE_TYPE_DATA = struct { - name: *i8, - underlying_type: *Node, -}; - -let NODE_TYPE_FUNCTION_TYPE_DATA = struct { - parameters: *Node, - parameters_len: i64, - retur_type: *Node, -}; - -let NODE_TYPE_POINTER_TYPE_DATA = struct { - type: *Node, -}; - -let NODE_TYPE_STRUCT_TYPE_DATA = struct { - fields: *Node, - fields_len: i64, -}; - -let NODE_RETURN_STATEMENT_DATA = struct { - expression: *Node, -}; - -let NODE_CAST_STATEMENT_DATA = struct { - typ: *Node, - expression: *Node, -}; - -let NODE_SIZEOF_STATEMENT_DATA = struct { - typ: *Node, -}; - - -let parser = struct { - tokens: *token, - tokens_len: i64, - - offset: i64, - - arena: *arena, -}; - -extern parser_parse_statement = (*parser) => *Node; -extern parser_parse_expression = (*parser) => *Node; - -let parser_init = (ts: *token, ts_len: i64, ar: *arena) => *parser { - let p = cast(*parser, arena_alloc(ar, sizeof(parser))); - - (*p).tokens = ts; - (*p).tokens_len = ts_len; - (*p).offset = 0; - (*p).arena = ar; - - return p; -}; - -let create_node = (p: *parser, n: Node) => *Node { - let res = cast(*Node, arena_alloc((*p).arena, sizeof(Node))); - *res = n; - return res; -}; - -let parser_peek_token = (p: *parser) => *token { - if (*p).offset >= (*p).tokens_len { - return cast(*token, null); - }; - - return ((*p).tokens + cast(*token, (*p).offset)); -}; - - let parser_consume_token = (p: *parser) => *token { - if (*p).offset >= (*p).tokens_len { - return cast(*token, null); - }; - - let t = ((*p).tokens + cast(*token, (*p).offset)); - (*p).offset = (*p).offset + 1; - return t; -}; - -let parser_accept_token = (p: *parser, t: i64) => *token { - let curr_token = parser_peek_token(p); - if curr_token == cast(*token, null) { - return cast(*token, null); - }; - - if (*curr_token).type == t { - return parser_consume_token(p); - }; - return cast(*token, null); -}; - -let parser_accept_parse = (p: *parser, parsing_func: (*parser) => *Node) => *Node { - let prev_offset = (*p).offset; - let node = parsing_func(p); - if node == cast(*Node, null) { - (*p).offset = prev_offset; - }; - return node; -}; - -/* ReturnStatement ::= RETURN (Expression)? */ -let parser_parse_return_statement = (p: *parser) => *Node { - if parser_accept_token(p, TOKEN_RETURN) == cast(*token, null) { - return cast(*Node, null); - }; - - let maybe_expr = parser_accept_parse(p, parser_parse_expression); - - let d = cast(*NODE_RETURN_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_RETURN_STATEMENT_DATA ))); - (*d).expression = maybe_expr; - - let r = Node{}; - r.type = NODE_RETURN_STATEMENT; - r.data = cast(*void, d); - - return create_node(p, r); -}; - -/* Type ::= IDENTIFIER | FunctionType */ -let parser_parse_type = (p: *parser) => *Node { - /* TODO: Function type */ - let to = parser_consume_token(p); - assert(to != cast(*token, null)); - assert((*to).type == TOKEN_IDENTIFIER); - - let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*p).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA))); - (*d).name = cast(*i8, (*to).data); - (*d).underlying_type = cast(*Node, null); - - let r = Node{}; - r.type = NODE_TYPE_SIMPLE_TYPE; - r.data = cast(*void, d); - - return create_node(p, r); -}; - -/* FunctionParameters ::= IDENTIFIER ":" Type ("," IDENTIFIER ":" Type)* */ -let parser_parse_function_parameters = (p: *parser) => *slice { - /* TODO: Params */ - - let node_list = cast(**Node, arena_alloc((*p).arena, sizeof(**Node) * 20)); - let i = 0; - while true { - if i != 0 { - parser_accept_token(p, TOKEN_COMMA); - }; - let ident = parser_accept_token(p, TOKEN_IDENTIFIER); - if ident == cast(*token, null) { - break; - }; - /* TODO: Rest */ - }; - - let s = cast(*slice, arena_alloc((*p).arena, sizeof(slice))); - (*s).data = cast(*void, node_list); - (*s).data_len = 0; - return s; -}; - -/* FunctionDefinition ::= LPAREN FunctionParameters? RPAREN ARROW IDENTIFIER LBRACE Statement* ReturnStatement SEMICOLON RBRACE */ -let parser_parse_function_definition = (p: *parser) => *Node { - if parser_accept_token(p, TOKEN_LPAREN) == cast(*token, null) { - return cast(*Node, null); - }; - let params = parser_parse_function_parameters(p); - if params == cast(*slice, null) { - return cast(*Node, null); - }; - if parser_accept_token(p, TOKEN_RPAREN) == cast(*token, null) { - return cast(*Node, null); - }; - if parser_accept_token(p, TOKEN_ARROW) == cast(*token, null) { - return cast(*Node, null); - }; - let retur_type = parser_parse_type(p); - if retur_type == cast(*Node, null) { - return cast(*Node, null); - }; - if parser_accept_token(p, TOKEN_LBRACE) == cast(*token, null) { - return cast(*Node, null); - }; - - /* TODO: Body */ - let statements = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 100)); - let i = 0; - while true { - let n = parser_accept_parse(p, parser_parse_statement); - if n == cast(*Node, null) { - break; - }; - (*(statements + cast(**Node, i))) = n; - i = i + 1; - }; - - - if parser_accept_token(p, TOKEN_RBRACE) == cast(*token, null) { - return cast(*Node, null); - }; - - - let d = cast(*NODE_FUNCTION_DEFINITION_DATA, arena_alloc((*p).arena, sizeof(NODE_FUNCTION_DEFINITION_DATA))); - (*d).statements = statements; - (*d).statements_len = i; - (*d).parameters = cast(**Node, params.data); - (*d).parameters_len = params.data_len; - (*d).retur_type = cast(*Node, null); - - let n = Node{}; - n.type = NODE_FUNCTION_DEFINITION; - n.data = cast(*void, d); - - return create_node(p, n); -}; - -/* PrimaryExpression ::= NULL | NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | FunctionDefinition | StructDefinition | StructInstantiation | FieldAccess | LPAREN Expression RPAREN */ -let parser_parse_primary_expression = (p: *parser) => *Node { - let stmt = parser_accept_parse(p, parser_parse_function_definition); - if stmt != cast(*Node, null) { - return stmt; - }; - - let tok = parser_consume_token(p); - if tok == cast(*token, null) { - printf("NO TOK\n"); - return cast(*Node, null); - }; - - if (*tok).type == TOKEN_IDENTIFIER { - let d = cast(*NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_IDENTIFIER_DATA))); - (*d).name = cast(*i8, (*tok).data); - (*d).type = cast(*Node, null); /* TODO */ - let n = Node{}; - n.type = NODE_PRIMARY_EXPRESSION_IDENTIFIER; - n.data = cast(*void, d); - return create_node(p, n); - }; - - if (*tok).type == TOKEN_NUMBER { - let d = cast(*NODE_PRIMARY_EXPRESSION_NUMBER_DATA, arena_alloc((*p).arena, sizeof(NODE_PRIMARY_EXPRESSION_NUMBER_DATA))); - (*d).value = *(cast(*i64, (*tok).data)); - let n = Node{}; - n.type = NODE_PRIMARY_EXPRESSION_NUMBER; - n.data = cast(*void, d); - return create_node(p, n); - }; - - printf("DIFF TYPE: %d\n", (*tok).type); - - return cast(*Node, null); -}; - -/* EqualityExpression ::= AdditiveExpression ("==" | "!=" | "<=" | ">=" | "<" | ">") AdditiveExpression */ -let parser_parse_equality_expression = (p: *parser) => *Node { - /* TODO */ - return cast(*Node, null); -}; - -/* AdditiveExpression ::= MultiplicativeExpression (("+" | "-") MultiplicativeExpression)* */ -let parser_parse_additive_expression = (p: *parser) => *Node { - /* TODO */ - return parser_parse_primary_expression(p); -}; - -/* Expression ::= EqualityExpression | AdditiveExpression */ -let parser_parse_expression = (p: *parser) => *Node { - let ex = parser_accept_parse(p, parser_parse_equality_expression); - if ex != cast(*Node, null) { - return ex; - }; - let ax = parser_accept_parse(p, parser_parse_additive_expression); - if ax != cast(*Node, null) { - return ax; - }; - - return cast(*Node, null); -}; - -/* AssignmentStatement ::= ("let")? ("*")? Expression EQUALS Expression */ -let parse_assignment_statement = (p: *parser) => *Node { - let is_declaration = false; - if parser_accept_token(p, TOKEN_LET) != cast(*token, null) { - printf("IS DECLARATION\n"); - is_declaration = true; - }; - - /* TODO: is_dereference */ - - let lhs = parser_parse_expression(p); /* TODO */ - if lhs == cast(*Node, null) { - printf("ANOTHER BNLL\n"); - return cast(*Node, null); - }; - - if parser_accept_token(p, TOKEN_EQUALS) == cast(*token, null) { - return cast(*Node, null); - }; - - let rhs = parser_parse_expression(p); /* TODO */ - if rhs == cast(*Node, null) { - printf("NUL EXP\n"); - return cast(*Node, null); - }; - - let d = cast(*NODE_ASSIGNMENT_STATEMENT_DATA , arena_alloc((*p).arena, sizeof(NODE_ASSIGNMENT_STATEMENT_DATA ))); - (*d).is_declaration = is_declaration; - (*d).is_dereference = false; - (*d).lhs = lhs; - (*d).rhs = rhs; - let n = Node{}; - n.type = NODE_ASSIGNMENT_STATEMENT; - n.data = cast(*void, d); - printf("CONTINUE\n"); - return create_node(p, n); -}; - -/* Statement ::= (AssignmentStatement | ImportDeclaration | ExternDeclaration | CastStatement | SizeOfStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement | "break" | "continue") SEMICOLON */ -let parser_parse_statement = (p: *parser) => *Node { - let assignment = parser_accept_parse(p, parse_assignment_statement); - if assignment != cast(*Node, null) { - if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) { - return cast(*Node, null); - }; - return assignment; - }; - - let retu = parser_accept_parse(p, parser_parse_return_statement); - if retu != cast(*Node, null) { - if parser_accept_token(p, TOKEN_SEMICOLON) == cast(*token, null) { - return cast(*Node, null); - }; - return retu; - }; - - - printf("None\n"); - - return cast(*Node, null); -}; - -/* Program ::= Statement+ */ -let parse_program = (p: *parser) => *Node { - let nodes = cast(**Node, arena_alloc((*p).arena, sizeof(*Node) * 1000)); - - let i = 0; - while (*p).offset < (*p).tokens_len { - let s = parser_parse_statement(p); - assert(s != cast(*Node, null)); - (*(nodes + cast(**Node, i))) = s; - i = i + 1; - }; - - let d = cast(*NODE_PROGRAM_DATA, arena_alloc((*p).arena, sizeof(NODE_PROGRAM_DATA))); - (*d).statements = nodes; - (*d).statements_len = i; - let n = Node{}; - n.type = NODE_PROGRAM; - n.data = cast(*void, d); - return create_node(p, n); -}; - -let parse = (p: *parser) => *Node { - return parse_program(p); -}; - -/* - -For example -2: - -* parsing assignment statement -* parsing ident and num literals - -*/ diff --git a/src/bootstrap/tokenizer.pry b/src/bootstrap/tokenizer.pry new file mode 100644 index 0000000..a2cafb4 --- /dev/null +++ b/src/bootstrap/tokenizer.pry @@ -0,0 +1,553 @@ +extern strlen = (*i8) => i64; +extern memcpy = (*void, *void, i64) => void; +extern sprintf = (*i8, *i8, varargs) => void; +extern atoi = (*i8) => i64; + +import "!stdlib.pry"; +import "!mem.pry"; + +/* Keywords */ +let TOKEN_IMPORT = 1; +let TOKEN_LET = 2; +let TOKEN_EXTERN = 3; +let TOKEN_IF = 4; +let TOKEN_WHILE = 5; +let TOKEN_RETURN = 6; +let TOKEN_BREAK = 7; +let TOKEN_CONTINUE = 8; +let TOKEN_ARROW = 9; +let TOKEN_STRUCT = 10; +let TOKEN_TYPE = 34; + +/* Identifiers */ +let TOKEN_IDENTIFIER = 11; + +/* Literals */ +let TOKEN_NUMBER = 12; +let TOKEN_BOOLEAN = 13; +let TOKEN_NULL = 14; +let TOKEN_CHAR = 15; +let TOKEN_STRING = 16; + +/* Operators */ +let TOKEN_EQUALS = 17; +let TOKEN_PLUS = 18; +let TOKEN_MINUS = 19; +let TOKEN_MUL = 20; +let TOKEN_DIV = 21; +let TOKEN_MOD = 22; +let TOKEN_BANG = 23; +let TOKEN_LESS = 24; +let TOKEN_GREATER = 25; +let TOKEN_DOT = 26; + +/* Punctuation */ +let TOKEN_SEMICOLON = 27; +let TOKEN_COMMA = 28; +let TOKEN_COLON = 29; +let TOKEN_LPAREN = 30; +let TOKEN_RPAREN = 31; +let TOKEN_LBRACE = 32; +let TOKEN_RBRACE = 33; + +let token = struct { + type: i64, + data: *void, +}; + +let tokenizer = struct { + buf: *i8, + buf_len: i64, + offset: i64, + + arena: *arena, +}; + +let print_tokens = (ts: *token, ts_len: i64) => i64 { + let i = 0; + while i < ts_len { + let to = (*(ts + cast(*token, i))); + + if (to.type == TOKEN_IMPORT) { + printf("Import\n"); + }; + if (to.type == TOKEN_LET) { + printf("Let\n"); + }; + if (to.type == TOKEN_EXTERN) { + printf("Extern\n"); + }; + if (to.type == TOKEN_IF) { + printf("If\n"); + }; + if (to.type == TOKEN_WHILE) { + printf("While\n"); + }; + if (to.type == TOKEN_RETURN) { + printf("Return\n"); + }; + if (to.type == TOKEN_BREAK) { + printf("Break\n"); + }; + if (to.type == TOKEN_CONTINUE) { + printf("Continue\n"); + }; + if (to.type == TOKEN_ARROW) { + printf("Arrow\n"); + }; + if (to.type == TOKEN_STRUCT) { + printf("Struct\n"); + }; + if (to.type == TOKEN_TYPE) { + printf("Type\n"); + }; + if (to.type == TOKEN_IDENTIFIER) { + printf("Identifier: %s\n", cast(*i8, to.data)); + }; + if (to.type == TOKEN_NUMBER) { + printf("Number: %d\n", *cast(*i64, to.data)); + }; + if (to.type == TOKEN_BOOLEAN) { + printf("Boolean: %d\n", *cast(*bool, to.data)); + }; + if (to.type == TOKEN_NULL) { + printf("Null\n"); + }; + if (to.type == TOKEN_CHAR) { + printf("Char: %c\n", *cast(*i8, to.data)); + }; + if (to.type == TOKEN_STRING) { + printf("String: %s\n", cast(*i8, to.data)); + }; + if (to.type == TOKEN_EQUALS) { + printf("Equals\n"); + }; + if (to.type == TOKEN_PLUS) { + printf("Plus\n"); + }; + if (to.type == TOKEN_MINUS) { + printf("Minus\n"); + }; + if (to.type == TOKEN_MUL) { + printf("Mul\n"); + }; + if (to.type == TOKEN_DIV) { + printf("Div\n"); + }; + if (to.type == TOKEN_MOD) { + printf("Mod\n"); + }; + if (to.type == TOKEN_BANG) { + printf("Bang\n"); + }; + if (to.type == TOKEN_LESS) { + printf("Less\n"); + }; + if (to.type == TOKEN_GREATER) { + printf("Greater\n"); + }; + if (to.type == TOKEN_DOT) { + printf("Dot\n"); + }; + if (to.type == TOKEN_SEMICOLON) { + printf("Semicolon\n"); + }; + if (to.type == TOKEN_COMMA) { + printf("Comma\n"); + }; + if (to.type == TOKEN_COLON) { + printf("Colon\n"); + }; + if (to.type == TOKEN_LPAREN) { + printf("LParen\n"); + }; + if (to.type == TOKEN_RPAREN) { + printf("RParen\n"); + }; + if (to.type == TOKEN_LBRACE) { + printf("LBrace\n"); + }; + if (to.type == TOKEN_RBRACE) { + printf("RBrace\n"); + }; + + i = i + 1; + }; + + return 0; +}; + +let tokenizer_skip_whitespace = (t: *tokenizer) => void { + while true { + if (*t).offset >= (*t).buf_len { return; }; + let c = (*((*t).buf + cast(*i8, (*t).offset))); + if !iswhitespace(c) { + return; + }; + (*t).offset = (*t).offset + 1; + }; + + return; +}; + +let tokenizer_accept_string = (t: *tokenizer, str: *i8) => bool { + let str_len = strlen(str); + if (*t).offset + str_len > (*t).buf_len { return false; }; + + let s = cast(*i8, arena_alloc((*t).arena, 1000)); + memcpy(cast(*void, s), cast(*void, (*t).buf + cast(*i8, (*t).offset)), str_len); + + if strcmp(s, str) { + (*t).offset = (*t).offset + str_len; + return true; + }; + + return false; +}; + +let tokenizer_consume_until_condition = (t: *tokenizer, condition: (i8) => bool) => *i8 { + let start = (*t).offset; + let res = cast(*i8, arena_alloc((*t).arena, 1000)); + + while true { + if (*t).offset >= (*t).buf_len { + return res; + }; + + let c = (*((*t).buf + cast(*i8, (*t).offset))); + + let offset = (*t).offset; + if c == '\\' { + let next_c = (*((*t).buf + cast(*i8, offset + 1))); + + let any = false; + if next_c == 'n' { + (*(res + cast(*i8, offset - start))) = '\n'; + any = true; + }; + if next_c == 't' { + (*(res + cast(*i8, offset - start))) = '\t'; + any = true; + }; + if next_c == 'r' { + (*(res + cast(*i8, offset - start))) = '\r'; + any = true; + }; + if next_c == '0' { + (*(res + cast(*i8, offset - start))) = '\0'; + any = true; + }; + if next_c == '\\' { + (*(res + cast(*i8, offset - start))) = '\\'; + any = true; + }; + if !any { + (*(res + cast(*i8, offset - start))) = next_c; + }; + + offset = offset + 1; + offset = offset + 1; + (*t).offset = offset; + + continue; + }; + + if condition(c) { + return res; + }; + + (*(res + cast(*i8, offset - start))) = c; + (*(res + cast(*i8, offset - start + 1))) = '\0'; + + offset = offset + 1; + (*t).offset = offset; + }; + + return cast(*i8, null); +}; + +let tokenizer_accept_int_type = (t: *tokenizer) => *i64 { + let string = tokenizer_consume_until_condition(t, (c: i8) => bool { + return !isdigit(c); + }); + if string == cast(*i8, null) { + return cast(*i64, null); + }; + if strlen(string) == 0 { + return cast(*i64, null); + }; + let x = cast(*i64, arena_alloc((*t).arena, sizeof(i64))); + *x = atoi(string); + return x; +}; + +let tokenizer_accept_char_type = (t: *tokenizer) => *i8 { + let prev_offset = (*t).offset; + if !tokenizer_accept_string(t, "'") { + (*t).offset = prev_offset; + return cast(*i8, null); + }; + + let string = tokenizer_consume_until_condition(t, (c: i8) => bool { + return c == '\''; + }); + + if !tokenizer_accept_string(t, "'") { + (*t).offset = prev_offset; + return cast(*i8, null); + }; + + return string; +}; + +let tokenizer_accept_string_type = (t: *tokenizer) => *i8 { + let prev_offset = (*t).offset; + if !tokenizer_accept_string(t, "\"") { + (*t).offset = prev_offset; + return cast(*i8, null); + }; + + let string = tokenizer_consume_until_condition(t, (c: i8) => bool { + return c == '"'; + }); + + if !tokenizer_accept_string(t, "\"") { + (*t).offset = prev_offset; + return cast(*i8, null); + }; + + return string; +}; + +let tokenizer_skip_comments = (t: *tokenizer) => void { + if !tokenizer_accept_string(t, "/*") { return; }; + + while !tokenizer_accept_string(t, "*/") { + (*t).offset = (*t).offset + 1; + }; + + return; +}; + +let tokenizer_next = (t: *tokenizer) => *token { + tokenizer_skip_whitespace(t); + tokenizer_skip_comments(t); + tokenizer_skip_whitespace(t); + + if (*t).offset >= (*t).buf_len { + return cast(*token, null); + }; + + let to = cast(*token, arena_alloc((*t).arena, sizeof(token))); + + if tokenizer_accept_string(t, "import") { + (*to).type = TOKEN_IMPORT; + return to; + }; + if tokenizer_accept_string(t, "let") { + (*to).type = TOKEN_LET; + return to; + }; + if tokenizer_accept_string(t, "extern") { + (*to).type = TOKEN_EXTERN; + return to; + }; + if tokenizer_accept_string(t, "if") { + (*to).type = TOKEN_IF; + return to; + }; + if tokenizer_accept_string(t, "while") { + (*to).type = TOKEN_WHILE; + return to; + }; + if tokenizer_accept_string(t, "return") { + (*to).type = TOKEN_RETURN; + return to; + }; + if tokenizer_accept_string(t, "break") { + (*to).type = TOKEN_BREAK; + return to; + }; + if tokenizer_accept_string(t, "continue") { + (*to).type = TOKEN_CONTINUE; + return to; + }; + if tokenizer_accept_string(t, "true") { + (*to).type = TOKEN_BOOLEAN; + let data = cast(*bool, arena_alloc((*t).arena, sizeof(bool))); + *data = true; + (*to).data = cast(*void, data); + return to; + }; + if tokenizer_accept_string(t, "false") { + (*to).type = TOKEN_BOOLEAN; + let data = cast(*bool, arena_alloc((*t).arena, sizeof(bool))); + *data = false; + (*to).data = cast(*void, data); + return to; + }; + if tokenizer_accept_string(t, "null") { + (*to).type = TOKEN_NULL; + return to; + }; + if tokenizer_accept_string(t, "struct") { + (*to).type = TOKEN_STRUCT; + return to; + }; + if tokenizer_accept_string(t, "newtype") { + (*to).type = TOKEN_TYPE; + return to; + }; + + if tokenizer_accept_string(t, "=>") { + (*to).type = TOKEN_ARROW; + return to; + }; + if tokenizer_accept_string(t, ";") { + (*to).type = TOKEN_SEMICOLON; + return to; + }; + if tokenizer_accept_string(t, ",") { + (*to).type = TOKEN_COMMA; + return to; + }; + if tokenizer_accept_string(t, ":") { + (*to).type = TOKEN_COLON; + return to; + }; + if tokenizer_accept_string(t, "(") { + (*to).type = TOKEN_LPAREN; + return to; + }; + if tokenizer_accept_string(t, ")") { + (*to).type = TOKEN_RPAREN; + return to; + }; + if tokenizer_accept_string(t, "{") { + (*to).type = TOKEN_LBRACE; + return to; + }; + if tokenizer_accept_string(t, "}") { + (*to).type = TOKEN_RBRACE; + return to; + }; + if tokenizer_accept_string(t, "=") { + (*to).type = TOKEN_EQUALS; + return to; + }; + if tokenizer_accept_string(t, "+") { + (*to).type = TOKEN_PLUS; + return to; + }; + if tokenizer_accept_string(t, "-") { + (*to).type = TOKEN_MINUS; + return to; + }; + if tokenizer_accept_string(t, "*") { + (*to).type = TOKEN_MUL; + return to; + }; + if tokenizer_accept_string(t, "/") { + (*to).type = TOKEN_DIV; + return to; + }; + if tokenizer_accept_string(t, "%") { + (*to).type = TOKEN_MOD; + return to; + }; + if tokenizer_accept_string(t, "!") { + (*to).type = TOKEN_BANG; + return to; + }; + if tokenizer_accept_string(t, "<") { + (*to).type = TOKEN_LESS; + return to; + }; + if tokenizer_accept_string(t, ">") { + (*to).type = TOKEN_GREATER; + return to; + }; + if tokenizer_accept_string(t, ".") { + (*to).type = TOKEN_DOT; + return to; + }; + + let maybe_int = tokenizer_accept_int_type(t); + if maybe_int != cast(*i64, null) { + (*to).type = TOKEN_NUMBER; + (*to).data = cast(*void, maybe_int); + return to; + }; + + let maybe_char = tokenizer_accept_char_type(t); + if maybe_char != cast(*i8, null) { + (*to).type = TOKEN_CHAR; + (*to).data = cast(*void, maybe_char); + return to; + }; + + let maybe_string = tokenizer_accept_string_type(t); + if maybe_string != cast(*i8, null) { + (*to).type = TOKEN_STRING; + (*to).data = cast(*void, maybe_string); + return to; + }; + + let string = tokenizer_consume_until_condition(t, (c: i8) => bool { + if isalphanum(c) { + return false; + }; + if c == '_' { + return false; + }; + return true; + }); + if strlen(string) == 0 { + printf("NO IDENT!\n"); + return cast(*token, null); + }; + + (*to).type = TOKEN_IDENTIFIER; + (*to).data = cast(*void, string); + + return to; +}; + +let tokenizer_init = (alloc: *arena, file: slice) => *tokenizer { + let t = cast(*tokenizer, arena_alloc(alloc, sizeof(tokenizer))); + (*t).arena = alloc; + (*t).offset = 0; + (*t).buf = cast(*i8, file.data); + (*t).buf_len = file.data_len; + + printf("File size: %d\n", (*t).buf_len); + + printf("%s\n", (*t).buf); + + return t; +}; + +let tokenizer_tokenize = (t: *tokenizer) => slice { + let tokens = cast(*token, arena_alloc((*t).arena, sizeof(token) * 1000)); /* why does it not care about type here */ + let tokens_len = 0; + + while true { + let tk = tokenizer_next(t); + if tk == cast(*token, null) { + break; + }; + printf("Add token: %d\n", (*tk).type); + + (*(tokens + cast(*token, tokens_len))) = *tk; + tokens_len = tokens_len + 1; + }; + + printf("PRINT TOKENS: %d\n", tokens_len); + + print_tokens(tokens, tokens_len); + + let res = slice{}; + res.data = cast(*void, tokens); + res.data_len = tokens_len; + return res; +}; diff --git a/src/bootstrap/tokenizer.src b/src/bootstrap/tokenizer.src deleted file mode 100644 index 8d7f997..0000000 --- a/src/bootstrap/tokenizer.src +++ /dev/null @@ -1,553 +0,0 @@ -extern strlen = (*i8) => i64; -extern memcpy = (*void, *void, i64) => void; -extern sprintf = (*i8, *i8, varargs) => void; -extern atoi = (*i8) => i64; - -import "!stdlib.src"; -import "!mem.src"; - -/* Keywords */ -let TOKEN_IMPORT = 1; -let TOKEN_LET = 2; -let TOKEN_EXTERN = 3; -let TOKEN_IF = 4; -let TOKEN_WHILE = 5; -let TOKEN_RETURN = 6; -let TOKEN_BREAK = 7; -let TOKEN_CONTINUE = 8; -let TOKEN_ARROW = 9; -let TOKEN_STRUCT = 10; -let TOKEN_TYPE = 34; - -/* Identifiers */ -let TOKEN_IDENTIFIER = 11; - -/* Literals */ -let TOKEN_NUMBER = 12; -let TOKEN_BOOLEAN = 13; -let TOKEN_NULL = 14; -let TOKEN_CHAR = 15; -let TOKEN_STRING = 16; - -/* Operators */ -let TOKEN_EQUALS = 17; -let TOKEN_PLUS = 18; -let TOKEN_MINUS = 19; -let TOKEN_MUL = 20; -let TOKEN_DIV = 21; -let TOKEN_MOD = 22; -let TOKEN_BANG = 23; -let TOKEN_LESS = 24; -let TOKEN_GREATER = 25; -let TOKEN_DOT = 26; - -/* Punctuation */ -let TOKEN_SEMICOLON = 27; -let TOKEN_COMMA = 28; -let TOKEN_COLON = 29; -let TOKEN_LPAREN = 30; -let TOKEN_RPAREN = 31; -let TOKEN_LBRACE = 32; -let TOKEN_RBRACE = 33; - -let token = struct { - type: i64, - data: *void, -}; - -let tokenizer = struct { - buf: *i8, - buf_len: i64, - offset: i64, - - arena: *arena, -}; - -let print_tokens = (ts: *token, ts_len: i64) => i64 { - let i = 0; - while i < ts_len { - let to = (*(ts + cast(*token, i))); - - if (to.type == TOKEN_IMPORT) { - printf("Import\n"); - }; - if (to.type == TOKEN_LET) { - printf("Let\n"); - }; - if (to.type == TOKEN_EXTERN) { - printf("Extern\n"); - }; - if (to.type == TOKEN_IF) { - printf("If\n"); - }; - if (to.type == TOKEN_WHILE) { - printf("While\n"); - }; - if (to.type == TOKEN_RETURN) { - printf("Return\n"); - }; - if (to.type == TOKEN_BREAK) { - printf("Break\n"); - }; - if (to.type == TOKEN_CONTINUE) { - printf("Continue\n"); - }; - if (to.type == TOKEN_ARROW) { - printf("Arrow\n"); - }; - if (to.type == TOKEN_STRUCT) { - printf("Struct\n"); - }; - if (to.type == TOKEN_TYPE) { - printf("Type\n"); - }; - if (to.type == TOKEN_IDENTIFIER) { - printf("Identifier: %s\n", cast(*i8, to.data)); - }; - if (to.type == TOKEN_NUMBER) { - printf("Number: %d\n", *cast(*i64, to.data)); - }; - if (to.type == TOKEN_BOOLEAN) { - printf("Boolean: %d\n", *cast(*bool, to.data)); - }; - if (to.type == TOKEN_NULL) { - printf("Null\n"); - }; - if (to.type == TOKEN_CHAR) { - printf("Char: %c\n", *cast(*i8, to.data)); - }; - if (to.type == TOKEN_STRING) { - printf("String: %s\n", cast(*i8, to.data)); - }; - if (to.type == TOKEN_EQUALS) { - printf("Equals\n"); - }; - if (to.type == TOKEN_PLUS) { - printf("Plus\n"); - }; - if (to.type == TOKEN_MINUS) { - printf("Minus\n"); - }; - if (to.type == TOKEN_MUL) { - printf("Mul\n"); - }; - if (to.type == TOKEN_DIV) { - printf("Div\n"); - }; - if (to.type == TOKEN_MOD) { - printf("Mod\n"); - }; - if (to.type == TOKEN_BANG) { - printf("Bang\n"); - }; - if (to.type == TOKEN_LESS) { - printf("Less\n"); - }; - if (to.type == TOKEN_GREATER) { - printf("Greater\n"); - }; - if (to.type == TOKEN_DOT) { - printf("Dot\n"); - }; - if (to.type == TOKEN_SEMICOLON) { - printf("Semicolon\n"); - }; - if (to.type == TOKEN_COMMA) { - printf("Comma\n"); - }; - if (to.type == TOKEN_COLON) { - printf("Colon\n"); - }; - if (to.type == TOKEN_LPAREN) { - printf("LParen\n"); - }; - if (to.type == TOKEN_RPAREN) { - printf("RParen\n"); - }; - if (to.type == TOKEN_LBRACE) { - printf("LBrace\n"); - }; - if (to.type == TOKEN_RBRACE) { - printf("RBrace\n"); - }; - - i = i + 1; - }; - - return 0; -}; - -let tokenizer_skip_whitespace = (t: *tokenizer) => void { - while true { - if (*t).offset >= (*t).buf_len { return; }; - let c = (*((*t).buf + cast(*i8, (*t).offset))); - if !iswhitespace(c) { - return; - }; - (*t).offset = (*t).offset + 1; - }; - - return; -}; - -let tokenizer_accept_string = (t: *tokenizer, str: *i8) => bool { - let str_len = strlen(str); - if (*t).offset + str_len > (*t).buf_len { return false; }; - - let s = cast(*i8, arena_alloc((*t).arena, 1000)); - memcpy(cast(*void, s), cast(*void, (*t).buf + cast(*i8, (*t).offset)), str_len); - - if strcmp(s, str) { - (*t).offset = (*t).offset + str_len; - return true; - }; - - return false; -}; - -let tokenizer_consume_until_condition = (t: *tokenizer, condition: (i8) => bool) => *i8 { - let start = (*t).offset; - let res = cast(*i8, arena_alloc((*t).arena, 1000)); - - while true { - if (*t).offset >= (*t).buf_len { - return res; - }; - - let c = (*((*t).buf + cast(*i8, (*t).offset))); - - let offset = (*t).offset; - if c == '\\' { - let next_c = (*((*t).buf + cast(*i8, offset + 1))); - - let any = false; - if next_c == 'n' { - (*(res + cast(*i8, offset - start))) = '\n'; - any = true; - }; - if next_c == 't' { - (*(res + cast(*i8, offset - start))) = '\t'; - any = true; - }; - if next_c == 'r' { - (*(res + cast(*i8, offset - start))) = '\r'; - any = true; - }; - if next_c == '0' { - (*(res + cast(*i8, offset - start))) = '\0'; - any = true; - }; - if next_c == '\\' { - (*(res + cast(*i8, offset - start))) = '\\'; - any = true; - }; - if !any { - (*(res + cast(*i8, offset - start))) = next_c; - }; - - offset = offset + 1; - offset = offset + 1; - (*t).offset = offset; - - continue; - }; - - if condition(c) { - return res; - }; - - (*(res + cast(*i8, offset - start))) = c; - (*(res + cast(*i8, offset - start + 1))) = '\0'; - - offset = offset + 1; - (*t).offset = offset; - }; - - return cast(*i8, null); -}; - -let tokenizer_accept_int_type = (t: *tokenizer) => *i64 { - let string = tokenizer_consume_until_condition(t, (c: i8) => bool { - return !isdigit(c); - }); - if string == cast(*i8, null) { - return cast(*i64, null); - }; - if strlen(string) == 0 { - return cast(*i64, null); - }; - let x = cast(*i64, arena_alloc((*t).arena, sizeof(i64))); - *x = atoi(string); - return x; -}; - -let tokenizer_accept_char_type = (t: *tokenizer) => *i8 { - let prev_offset = (*t).offset; - if !tokenizer_accept_string(t, "'") { - (*t).offset = prev_offset; - return cast(*i8, null); - }; - - let string = tokenizer_consume_until_condition(t, (c: i8) => bool { - return c == '\''; - }); - - if !tokenizer_accept_string(t, "'") { - (*t).offset = prev_offset; - return cast(*i8, null); - }; - - return string; -}; - -let tokenizer_accept_string_type = (t: *tokenizer) => *i8 { - let prev_offset = (*t).offset; - if !tokenizer_accept_string(t, "\"") { - (*t).offset = prev_offset; - return cast(*i8, null); - }; - - let string = tokenizer_consume_until_condition(t, (c: i8) => bool { - return c == '"'; - }); - - if !tokenizer_accept_string(t, "\"") { - (*t).offset = prev_offset; - return cast(*i8, null); - }; - - return string; -}; - -let tokenizer_skip_comments = (t: *tokenizer) => void { - if !tokenizer_accept_string(t, "/*") { return; }; - - while !tokenizer_accept_string(t, "*/") { - (*t).offset = (*t).offset + 1; - }; - - return; -}; - -let tokenizer_next = (t: *tokenizer) => *token { - tokenizer_skip_whitespace(t); - tokenizer_skip_comments(t); - tokenizer_skip_whitespace(t); - - if (*t).offset >= (*t).buf_len { - return cast(*token, null); - }; - - let to = cast(*token, arena_alloc((*t).arena, sizeof(token))); - - if tokenizer_accept_string(t, "import") { - (*to).type = TOKEN_IMPORT; - return to; - }; - if tokenizer_accept_string(t, "let") { - (*to).type = TOKEN_LET; - return to; - }; - if tokenizer_accept_string(t, "extern") { - (*to).type = TOKEN_EXTERN; - return to; - }; - if tokenizer_accept_string(t, "if") { - (*to).type = TOKEN_IF; - return to; - }; - if tokenizer_accept_string(t, "while") { - (*to).type = TOKEN_WHILE; - return to; - }; - if tokenizer_accept_string(t, "return") { - (*to).type = TOKEN_RETURN; - return to; - }; - if tokenizer_accept_string(t, "break") { - (*to).type = TOKEN_BREAK; - return to; - }; - if tokenizer_accept_string(t, "continue") { - (*to).type = TOKEN_CONTINUE; - return to; - }; - if tokenizer_accept_string(t, "true") { - (*to).type = TOKEN_BOOLEAN; - let data = cast(*bool, arena_alloc((*t).arena, sizeof(bool))); - *data = true; - (*to).data = cast(*void, data); - return to; - }; - if tokenizer_accept_string(t, "false") { - (*to).type = TOKEN_BOOLEAN; - let data = cast(*bool, arena_alloc((*t).arena, sizeof(bool))); - *data = false; - (*to).data = cast(*void, data); - return to; - }; - if tokenizer_accept_string(t, "null") { - (*to).type = TOKEN_NULL; - return to; - }; - if tokenizer_accept_string(t, "struct") { - (*to).type = TOKEN_STRUCT; - return to; - }; - if tokenizer_accept_string(t, "newtype") { - (*to).type = TOKEN_TYPE; - return to; - }; - - if tokenizer_accept_string(t, "=>") { - (*to).type = TOKEN_ARROW; - return to; - }; - if tokenizer_accept_string(t, ";") { - (*to).type = TOKEN_SEMICOLON; - return to; - }; - if tokenizer_accept_string(t, ",") { - (*to).type = TOKEN_COMMA; - return to; - }; - if tokenizer_accept_string(t, ":") { - (*to).type = TOKEN_COLON; - return to; - }; - if tokenizer_accept_string(t, "(") { - (*to).type = TOKEN_LPAREN; - return to; - }; - if tokenizer_accept_string(t, ")") { - (*to).type = TOKEN_RPAREN; - return to; - }; - if tokenizer_accept_string(t, "{") { - (*to).type = TOKEN_LBRACE; - return to; - }; - if tokenizer_accept_string(t, "}") { - (*to).type = TOKEN_RBRACE; - return to; - }; - if tokenizer_accept_string(t, "=") { - (*to).type = TOKEN_EQUALS; - return to; - }; - if tokenizer_accept_string(t, "+") { - (*to).type = TOKEN_PLUS; - return to; - }; - if tokenizer_accept_string(t, "-") { - (*to).type = TOKEN_MINUS; - return to; - }; - if tokenizer_accept_string(t, "*") { - (*to).type = TOKEN_MUL; - return to; - }; - if tokenizer_accept_string(t, "/") { - (*to).type = TOKEN_DIV; - return to; - }; - if tokenizer_accept_string(t, "%") { - (*to).type = TOKEN_MOD; - return to; - }; - if tokenizer_accept_string(t, "!") { - (*to).type = TOKEN_BANG; - return to; - }; - if tokenizer_accept_string(t, "<") { - (*to).type = TOKEN_LESS; - return to; - }; - if tokenizer_accept_string(t, ">") { - (*to).type = TOKEN_GREATER; - return to; - }; - if tokenizer_accept_string(t, ".") { - (*to).type = TOKEN_DOT; - return to; - }; - - let maybe_int = tokenizer_accept_int_type(t); - if maybe_int != cast(*i64, null) { - (*to).type = TOKEN_NUMBER; - (*to).data = cast(*void, maybe_int); - return to; - }; - - let maybe_char = tokenizer_accept_char_type(t); - if maybe_char != cast(*i8, null) { - (*to).type = TOKEN_CHAR; - (*to).data = cast(*void, maybe_char); - return to; - }; - - let maybe_string = tokenizer_accept_string_type(t); - if maybe_string != cast(*i8, null) { - (*to).type = TOKEN_STRING; - (*to).data = cast(*void, maybe_string); - return to; - }; - - let string = tokenizer_consume_until_condition(t, (c: i8) => bool { - if isalphanum(c) { - return false; - }; - if c == '_' { - return false; - }; - return true; - }); - if strlen(string) == 0 { - printf("NO IDENT!\n"); - return cast(*token, null); - }; - - (*to).type = TOKEN_IDENTIFIER; - (*to).data = cast(*void, string); - - return to; -}; - -let tokenizer_init = (alloc: *arena, file: slice) => *tokenizer { - let t = cast(*tokenizer, arena_alloc(alloc, sizeof(tokenizer))); - (*t).arena = alloc; - (*t).offset = 0; - (*t).buf = cast(*i8, file.data); - (*t).buf_len = file.data_len; - - printf("File size: %d\n", (*t).buf_len); - - printf("%s\n", (*t).buf); - - return t; -}; - -let tokenizer_tokenize = (t: *tokenizer) => slice { - let tokens = cast(*token, arena_alloc((*t).arena, sizeof(token) * 1000)); /* why does it not care about type here */ - let tokens_len = 0; - - while true { - let tk = tokenizer_next(t); - if tk == cast(*token, null) { - break; - }; - printf("Add token: %d\n", (*tk).type); - - (*(tokens + cast(*token, tokens_len))) = *tk; - tokens_len = tokens_len + 1; - }; - - printf("PRINT TOKENS: %d\n", tokens_len); - - print_tokens(tokens, tokens_len); - - let res = slice{}; - res.data = cast(*void, tokens); - res.data_len = tokens_len; - return res; -}; diff --git a/std/mem.pry b/std/mem.pry new file mode 100644 index 0000000..75f3d1d --- /dev/null +++ b/std/mem.pry @@ -0,0 +1,29 @@ +extern calloc = (i64, i64) => *void; +extern realloc = (*void, i64) => *void; +extern free = (*void) => void; + +import "!stdlib.pry"; + +let arena = struct { + buf: *void, + offset: i64, +}; + +let arena_init = (size: i64) => *arena { + let a = cast(*arena, calloc(1, sizeof(arena))); + (*a).buf = calloc(1, size); + (*a).offset = 0; + return a; +}; + +let arena_free = (a: *arena) => void { + free((*a).buf); + free(cast(*void, a)); + return; +}; + +let arena_alloc = (a: *arena, size: i64) => *void { + let old_offset = (*a).offset; + (*a).offset = (*a).offset + size; + return cast(*void, cast(*i8, (*a).buf) + cast(*i8, old_offset)); +}; diff --git a/std/mem.src b/std/mem.src deleted file mode 100644 index 3bb1a0a..0000000 --- a/std/mem.src +++ /dev/null @@ -1,29 +0,0 @@ -extern calloc = (i64, i64) => *void; -extern realloc = (*void, i64) => *void; -extern free = (*void) => void; - -import "!stdlib.src"; - -let arena = struct { - buf: *void, - offset: i64, -}; - -let arena_init = (size: i64) => *arena { - let a = cast(*arena, calloc(1, sizeof(arena))); - (*a).buf = calloc(1, size); - (*a).offset = 0; - return a; -}; - -let arena_free = (a: *arena) => void { - free((*a).buf); - free(cast(*void, a)); - return; -}; - -let arena_alloc = (a: *arena, size: i64) => *void { - let old_offset = (*a).offset; - (*a).offset = (*a).offset + size; - return cast(*void, cast(*i8, (*a).buf) + cast(*i8, old_offset)); -}; diff --git a/std/stdlib.pry b/std/stdlib.pry new file mode 100644 index 0000000..aecd4df --- /dev/null +++ b/std/stdlib.pry @@ -0,0 +1,83 @@ +extern printf = (*i8, varargs) => void; +extern exit = (i64) => void; + +let strcmp = (stra: *i8, strb: *i8) => bool { + let i = 0; + while true { + let ca = (*(stra + cast(*i8, i))); + let cb = (*(strb + cast(*i8, i))); + + if ca == '\0' { + return cb == '\0'; + }; + + if cb == '\0' { + return ca == '\0'; + }; + + if !(ca == cb) { + return false; + }; + + i = i + 1; + }; + + return true; +}; + +let isdigit = (c: i8) => bool { + if c >= '0' { + if c <= '9' { + return true; + }; + }; + return false; +}; + +let isalpha = (c: i8) => bool { + if c >= 'a' { + if c <= 'z' { + return true; + }; + }; + if c >= 'A' { + if c <= 'Z' { + return true; + }; + }; + return false; +}; + +let isalphanum = (c: i8) => bool { + if isalpha(c) { + return true; + }; + if isdigit(c) { + return true; + }; + + return false; +}; + +let iswhitespace = (c: i8) => bool { + if c == ' ' { + return true; + }; + + if c >= '\t' { + if c <= '\r' { + return true; + }; + }; + + return false; +}; + +let assert = (cond: bool) => void { + if !cond { + printf("ASSERTION FAILED\n"); + exit(1); + }; + + return; +}; diff --git a/std/stdlib.src b/std/stdlib.src deleted file mode 100644 index aecd4df..0000000 --- a/std/stdlib.src +++ /dev/null @@ -1,83 +0,0 @@ -extern printf = (*i8, varargs) => void; -extern exit = (i64) => void; - -let strcmp = (stra: *i8, strb: *i8) => bool { - let i = 0; - while true { - let ca = (*(stra + cast(*i8, i))); - let cb = (*(strb + cast(*i8, i))); - - if ca == '\0' { - return cb == '\0'; - }; - - if cb == '\0' { - return ca == '\0'; - }; - - if !(ca == cb) { - return false; - }; - - i = i + 1; - }; - - return true; -}; - -let isdigit = (c: i8) => bool { - if c >= '0' { - if c <= '9' { - return true; - }; - }; - return false; -}; - -let isalpha = (c: i8) => bool { - if c >= 'a' { - if c <= 'z' { - return true; - }; - }; - if c >= 'A' { - if c <= 'Z' { - return true; - }; - }; - return false; -}; - -let isalphanum = (c: i8) => bool { - if isalpha(c) { - return true; - }; - if isdigit(c) { - return true; - }; - - return false; -}; - -let iswhitespace = (c: i8) => bool { - if c == ' ' { - return true; - }; - - if c >= '\t' { - if c <= '\r' { - return true; - }; - }; - - return false; -}; - -let assert = (cond: bool) => void { - if !cond { - printf("ASSERTION FAILED\n"); - exit(1); - }; - - return; -}; -- cgit 1.4.1