This commit is contained in:
2025-06-01 19:54:35 +02:00
parent e84419f0cf
commit 437697b287
9 changed files with 44 additions and 25 deletions

View File

@@ -4,12 +4,12 @@ A very cool language
## Syntax ## Syntax
```go ```go
func fib[n: U32] : U32 func fib[n: I64] : I64
if n <= 1 if n <= 1
return n return n
return fib(n-2) + fib(n-1) return fib(n-2) + fib(n-1)
func main[] func main[] : I64
for i in 0..20 for i in 0..20
fib(i) |> U32.to_string() |> IO.print() fib(i) |> I64.to_string() |> print()
``` ```

View File

@@ -3,18 +3,18 @@ func print_i64[x: I64] : I64
func is_prime[n: I64]: I64 func is_prime[n: I64]: I64
if n <= 1 if n <= 1
return 0 return false
if n == 2 || n == 3 if n == 2 || n == 3
return 1 return true
if n % 2 == 0 || n % 3 == 0 if n % 2 == 0 || n % 3 == 0
return 0 return false
let i: I64 = 5 let i: I64 = 5
while i * i <= n while i * i <= n
if n % i == 0 || n % (i + 2) == 0 if n % i == 0 || n % (i + 2) == 0
return 0 return false
i = i + 6 i = i + 6
return 1 return true
func main[] : I64 func main[] : I64
let sum: I64 = 0 let sum: I64 = 0

View File

@@ -3,7 +3,7 @@ func print_i64[x: I64] : I64
func num_divisors[n: I64] : I64 func num_divisors[n: I64] : I64
let end: I64 = isqrt(n) let end: I64 = isqrt(n)
let result: I64 = 0 let result: I64 = 0
let i: I64 = 1 let i: I64 = 1
while i < end + 1 while i < end + 1

View File

@@ -1,7 +1,7 @@
func print_i64[x: I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func i64_to_string[n: I64] : String func I64.to_string[n: I64] : String
let x: I64 = malloc(21) let x: I64 = malloc(21)
sprintf(x, "%ld", n) sprintf(x, "%ld", n)
return x return x
@@ -14,7 +14,7 @@ func main[] : I64
let b: I64 = 500 let b: I64 = 500
while b < 1000 while b < 1000
if a * b > out if a * b > out
let s: String = i64_to_string(a * b) let s: String = I64.to_string(a * b)
let s_rev: String = strrev(s) let s_rev: String = strrev(s)
if strcmp(s, s_rev) == 0 if strcmp(s, s_rev) == 0
out = a * b out = a * b

View File

@@ -3,18 +3,18 @@ func print_i64[x: I64] : I64
func is_prime[n: I64]: I64 func is_prime[n: I64]: I64
if n <= 1 if n <= 1
return 0 return false
if n == 2 || n == 3 if n == 2 || n == 3
return 1 return true
if n % 2 == 0 || n % 3 == 0 if n % 2 == 0 || n % 3 == 0
return 0 return false
let i: I64 = 5 let i: I64 = 5
while i * i <= n while i * i <= n
if n % i == 0 || n % (i + 2) == 0 if n % i == 0 || n % (i + 2) == 0
return 0 return false
i = i + 6 i = i + 6
return 1 return true
func main[] : I64 func main[] : I64
let found: I64 = 0 let found: I64 = 0

View File

@@ -1,12 +1,12 @@
func print_i64[x: I64] : I64 func print_i64[x: I64] : I64
printf("%ld\n", x) printf("%ld\n", x)
func i64_to_string[n: I64] : String func I64.to_string[n: I64] : String
let x: I64 = malloc(21) let x: String = malloc(21)
sprintf(x, "%d", n) sprintf(x, "%ld", n)
return x return x
func main[] : I64 func main[] : I64
let s: String = i64_to_string(58394) let s: String = I64.to_string(58394)
print_i64(strlen(s)) print_i64(strlen(s))
free(s) free(s)

View File

@@ -58,7 +58,7 @@ macro_rules! emit {
} }
static REGISTERS: [&str; 6] = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"]; static REGISTERS: [&str; 6] = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
static TYPES: [&str; 2] = ["I64", "String"]; static TYPES: [&str; 3] = ["I64", "String", "Bool"];
pub struct CodegenX86_64 { pub struct CodegenX86_64 {
output: String, output: String,
@@ -259,7 +259,11 @@ nth:
self.compile_stmt(env, *body)?; self.compile_stmt(env, *body)?;
emit!(&mut self.output, " mov rax, 0"); // TODO: remove default return value if name.lexeme == "main" {
// default exit code
emit!(&mut self.output, " mov rax, 0");
}
emit!(&mut self.output, " mov rsp, rbp"); emit!(&mut self.output, " mov rsp, rbp");
emit!(&mut self.output, " pop rbp"); emit!(&mut self.output, " pop rbp");
emit!(&mut self.output, " ret"); emit!(&mut self.output, " ret");
@@ -366,6 +370,12 @@ nth:
emit!(&mut self.output, " mov rax, S{}", self.data_counter); emit!(&mut self.output, " mov rax, S{}", self.data_counter);
self.data_counter += 1; self.data_counter += 1;
} }
TokenType::True => {
emit!(&mut self.output, " mov rax, 1");
}
TokenType::False => {
emit!(&mut self.output, " mov rax, 0");
}
_ => unreachable!(), _ => unreachable!(),
}, },
Expr::Unary { op, right } => { Expr::Unary { op, right } => {

View File

@@ -396,7 +396,12 @@ impl Parser {
} }
fn primary(&mut self) -> Result<Expr, ZernError> { fn primary(&mut self) -> Result<Expr, ZernError> {
if self.match_token(&[TokenType::Number, TokenType::String]) { if self.match_token(&[
TokenType::Number,
TokenType::String,
TokenType::True,
TokenType::False,
]) {
Ok(Expr::Literal(self.previous().clone())) Ok(Expr::Literal(self.previous().clone()))
} else if self.match_token(&[TokenType::LeftParen]) { } else if self.match_token(&[TokenType::LeftParen]) {
let expr = self.expression()?; let expr = self.expression()?;

View File

@@ -30,6 +30,8 @@ pub enum TokenType {
Identifier, Identifier,
String, String,
Number, Number,
True,
False,
KeywordLet, KeywordLet,
KeywordIf, KeywordIf,
@@ -305,6 +307,8 @@ impl Tokenizer {
"while" => TokenType::KeywordWhile, "while" => TokenType::KeywordWhile,
"func" => TokenType::KeywordFunc, "func" => TokenType::KeywordFunc,
"return" => TokenType::KeywordReturn, "return" => TokenType::KeywordReturn,
"true" => TokenType::True,
"false" => TokenType::False,
_ => TokenType::Identifier, _ => TokenType::Identifier,
}) })
} }