finally allow bare returns

This commit is contained in:
2026-06-07 13:10:36 +02:00
parent d4fe032a3a
commit 2864548daf
5 changed files with 43 additions and 34 deletions

View File

@@ -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");

View File

@@ -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 })

View File

@@ -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

View File

@@ -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::<Result<Vec<String>, _>>()?
.join(",")
};
let joined_type = exprs
.iter()
.map(|e| self.typecheck_expr(env, e))
.collect::<Result<Vec<String>, _>>()?
.join(",");
expect_type!(joined_type, expected, keyword.loc);
expect_type!(joined_type, self.current_function_return_type, keyword.loc);
}
Stmt::Break => {}
Stmt::Continue => {}