diff --git a/README.md b/README.md index 2f9101e..194e57c 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ A very cool language ## Syntax ```go -func fib[n: U32] : U32 +func fib[n: I64] : I64 if n <= 1 return n return fib(n-2) + fib(n-1) -func main[] +func main[] : I64 for i in 0..20 - fib(i) |> U32.to_string() |> IO.print() + fib(i) |> I64.to_string() |> print() ``` \ No newline at end of file diff --git a/examples/euler10.zr b/examples/euler10.zr index 57b3e80..db23dff 100644 --- a/examples/euler10.zr +++ b/examples/euler10.zr @@ -3,18 +3,18 @@ func print_i64[x: I64] : I64 func is_prime[n: I64]: I64 if n <= 1 - return 0 + return false if n == 2 || n == 3 - return 1 + return true if n % 2 == 0 || n % 3 == 0 - return 0 - + return false + let i: I64 = 5 while i * i <= n if n % i == 0 || n % (i + 2) == 0 - return 0 + return false i = i + 6 - return 1 + return true func main[] : I64 let sum: I64 = 0 diff --git a/examples/euler12.zr b/examples/euler12.zr index c358b2e..c18b91e 100644 --- a/examples/euler12.zr +++ b/examples/euler12.zr @@ -3,7 +3,7 @@ func print_i64[x: I64] : I64 func num_divisors[n: I64] : I64 let end: I64 = isqrt(n) - + let result: I64 = 0 let i: I64 = 1 while i < end + 1 diff --git a/examples/euler4.zr b/examples/euler4.zr index 454283a..66b9c2a 100644 --- a/examples/euler4.zr +++ b/examples/euler4.zr @@ -1,7 +1,7 @@ func print_i64[x: I64] : I64 printf("%ld\n", x) -func i64_to_string[n: I64] : String +func I64.to_string[n: I64] : String let x: I64 = malloc(21) sprintf(x, "%ld", n) return x @@ -14,7 +14,7 @@ func main[] : I64 let b: I64 = 500 while b < 1000 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) if strcmp(s, s_rev) == 0 out = a * b diff --git a/examples/euler7.zr b/examples/euler7.zr index 9b4c0a8..b4b08a0 100644 --- a/examples/euler7.zr +++ b/examples/euler7.zr @@ -3,18 +3,18 @@ func print_i64[x: I64] : I64 func is_prime[n: I64]: I64 if n <= 1 - return 0 + return false if n == 2 || n == 3 - return 1 + return true if n % 2 == 0 || n % 3 == 0 - return 0 - + return false + let i: I64 = 5 while i * i <= n if n % i == 0 || n % (i + 2) == 0 - return 0 + return false i = i + 6 - return 1 + return true func main[] : I64 let found: I64 = 0 diff --git a/examples/strings.zr b/examples/strings.zr index 5b0318b..f6ba059 100644 --- a/examples/strings.zr +++ b/examples/strings.zr @@ -1,12 +1,12 @@ func print_i64[x: I64] : I64 printf("%ld\n", x) -func i64_to_string[n: I64] : String - let x: I64 = malloc(21) - sprintf(x, "%d", n) +func I64.to_string[n: I64] : String + let x: String = malloc(21) + sprintf(x, "%ld", n) return x func main[] : I64 - let s: String = i64_to_string(58394) + let s: String = I64.to_string(58394) print_i64(strlen(s)) free(s) \ No newline at end of file diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index f7c55a2..e5cf401 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -58,7 +58,7 @@ macro_rules! emit { } 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 { output: String, @@ -259,7 +259,11 @@ nth: 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, " pop rbp"); emit!(&mut self.output, " ret"); @@ -366,6 +370,12 @@ nth: emit!(&mut self.output, " mov rax, S{}", self.data_counter); self.data_counter += 1; } + TokenType::True => { + emit!(&mut self.output, " mov rax, 1"); + } + TokenType::False => { + emit!(&mut self.output, " mov rax, 0"); + } _ => unreachable!(), }, Expr::Unary { op, right } => { diff --git a/src/parser.rs b/src/parser.rs index 7f0ba5f..9dfcdcd 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -396,7 +396,12 @@ impl Parser { } fn primary(&mut self) -> Result { - 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())) } else if self.match_token(&[TokenType::LeftParen]) { let expr = self.expression()?; diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 4ff4222..e911fca 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -30,6 +30,8 @@ pub enum TokenType { Identifier, String, Number, + True, + False, KeywordLet, KeywordIf, @@ -305,6 +307,8 @@ impl Tokenizer { "while" => TokenType::KeywordWhile, "func" => TokenType::KeywordFunc, "return" => TokenType::KeywordReturn, + "true" => TokenType::True, + "false" => TokenType::False, _ => TokenType::Identifier, }) }