diff --git a/src/codegen_x86_64.rs b/src/codegen_x86_64.rs index 547587d..c62e94e 100644 --- a/src/codegen_x86_64.rs +++ b/src/codegen_x86_64.rs @@ -415,15 +415,18 @@ _builtin_environ: .replace_range(prologue_offset..prologue_offset + patch.len(), &patch); } Stmt::Return { keyword: _, exprs } => { - if exprs.len() == 2 { - self.compile_expr(env, &exprs[1])?; - emit!(&mut self.output, " push rax"); - self.compile_expr(env, &exprs[0])?; - emit!(&mut self.output, " pop rdx"); - } else if exprs.len() == 1 { - self.compile_expr(env, &exprs[0])?; - } else { - todo!(); + match exprs.len() { + 2 => { + self.compile_expr(env, &exprs[1])?; + emit!(&mut self.output, " push rax"); + self.compile_expr(env, &exprs[0])?; + emit!(&mut self.output, " pop rdx"); + } + 1 => { + self.compile_expr(env, &exprs[0])?; + } + 0 => {} + _ => todo!(), } emit!(&mut self.output, " mov rsp, rbp"); emit!(&mut self.output, " pop rbp"); diff --git a/src/parser.rs b/src/parser.rs index c4b8ed7..71f2850 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -327,10 +327,12 @@ impl Parser { } else if self.match_token(&[TokenType::KeywordReturn]) { let keyword = self.previous().clone(); let mut exprs = vec![]; - loop { - exprs.push(self.expression()?); - if !self.match_token(&[TokenType::Comma]) { - break; + if !self.check(&TokenType::Dedent) { + loop { + exprs.push(self.expression()?); + if !self.match_token(&[TokenType::Comma]) { + break; + } } } Ok(Stmt::Return { keyword, exprs }) diff --git a/src/std/std.zr b/src/std/std.zr index 286b8a7..a7ca675 100644 --- a/src/std/std.zr +++ b/src/std/std.zr @@ -81,11 +81,11 @@ func mem.free[x: any] : void func ptr.free[x: ptr] : void if x == 0 - return 0 + return blk := (x - MEM_BLOCK_SIZE) as mem.Block if blk->free - return 0 + return blk->free = true @@ -733,7 +733,7 @@ func i64.to_str_buf[n: i64, buf: ptr] : void if n == 0 buf[0] = '0' buf[1] = 0 - return 0 + return neg : bool = n < 0 if neg @@ -768,7 +768,7 @@ func i64.to_hex_str_buf[n: i64, buf: ptr] : void if n == 0 buf[0] = '0' buf[1] = 0 - return 0 + return mask := (1 << 60) - 1 tmp := _stackalloc(17) @@ -849,7 +849,7 @@ func Array.new_preallocated_and_zeroed[size: i64] : Array func Array.nth[xs: Array, n: i64] : any if n < 0 || n >= xs->size - panic("array.nth out of bounds") + panic("Array.nth out of bounds") return mem.read64(xs->data + n * 8) func Array.set[xs: Array, n: i64, x: any] : void @@ -882,14 +882,19 @@ func Array.free_with_items[xs: Array] : void func Array.pop[xs: Array] : any if xs->size == 0 - panic("array.pop on empty array") - x : any = xs->nth(xs->size - 1) + panic("Array.pop on empty array") + x : any = Array.last(xs) xs->size = xs->size - 1 return x +func Array.last[xs: Array] : any + if xs->size == 0 + panic("Array.last on empty array") + return xs->nth(xs->size - 1) + func Array.slice[xs: Array, start: i64, length: i64] : Array if start < 0 || length < 0 || start + length > xs->size - panic("array.slice out of bounds") + panic("Array.slice out of bounds") new_array := Array.new_preallocated_and_zeroed(length) mem.copy(xs->data + start * 8, new_array->data, length * 8) @@ -971,7 +976,7 @@ func HashMap.insert[map: HashMap, key: str, value: any] : void while current as ptr if current->key->equal(key) current->value = value - return 0 + return current = current->next new_node := new* HashMap._Node @@ -1005,7 +1010,7 @@ func HashMap.delete[map: HashMap, key: str] : void current->key->free() mem.free(current) - return 0 + return prev = current current = current->next diff --git a/src/typechecker.rs b/src/typechecker.rs index 44fe3ed..9a33150 100644 --- a/src/typechecker.rs +++ b/src/typechecker.rs @@ -329,17 +329,16 @@ impl<'a> TypeChecker<'a> { env.pop_scope(); } Stmt::Return { keyword, exprs } => { - let expected = if self.current_function_return_type == "void" { - "i64".into() + let joined_type = if exprs.is_empty() { + "void".into() } else { - self.current_function_return_type.clone() + exprs + .iter() + .map(|e| self.typecheck_expr(env, e)) + .collect::, _>>()? + .join(",") }; - let joined_type = exprs - .iter() - .map(|e| self.typecheck_expr(env, e)) - .collect::, _>>()? - .join(","); - expect_type!(joined_type, expected, keyword.loc); + expect_type!(joined_type, self.current_function_return_type, keyword.loc); } Stmt::Break => {} Stmt::Continue => {} diff --git a/test.zr b/test.zr index d9a3038..d4864d1 100644 --- a/test.zr +++ b/test.zr @@ -5,7 +5,7 @@ func run_test[x: str] : void for i in 0..build_blacklist->size if x->equal(build_blacklist->nth(i)) io.printf("Skipping %s...\n", x) - return 0 + return io.printf("Building %s...\n", x) @@ -20,7 +20,7 @@ func run_test[x: str] : void for i in 0..run_blacklist->size if x->contains(run_blacklist->nth(i)) io.printf("Skipping %s...\n", x) - return 0 + return io.printf("Running %s...\n", x)