finally allow bare returns
This commit is contained in:
@@ -415,15 +415,18 @@ _builtin_environ:
|
|||||||
.replace_range(prologue_offset..prologue_offset + patch.len(), &patch);
|
.replace_range(prologue_offset..prologue_offset + patch.len(), &patch);
|
||||||
}
|
}
|
||||||
Stmt::Return { keyword: _, exprs } => {
|
Stmt::Return { keyword: _, exprs } => {
|
||||||
if exprs.len() == 2 {
|
match exprs.len() {
|
||||||
self.compile_expr(env, &exprs[1])?;
|
2 => {
|
||||||
emit!(&mut self.output, " push rax");
|
self.compile_expr(env, &exprs[1])?;
|
||||||
self.compile_expr(env, &exprs[0])?;
|
emit!(&mut self.output, " push rax");
|
||||||
emit!(&mut self.output, " pop rdx");
|
self.compile_expr(env, &exprs[0])?;
|
||||||
} else if exprs.len() == 1 {
|
emit!(&mut self.output, " pop rdx");
|
||||||
self.compile_expr(env, &exprs[0])?;
|
}
|
||||||
} else {
|
1 => {
|
||||||
todo!();
|
self.compile_expr(env, &exprs[0])?;
|
||||||
|
}
|
||||||
|
0 => {}
|
||||||
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
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");
|
||||||
|
|||||||
@@ -327,10 +327,12 @@ impl Parser {
|
|||||||
} else if self.match_token(&[TokenType::KeywordReturn]) {
|
} else if self.match_token(&[TokenType::KeywordReturn]) {
|
||||||
let keyword = self.previous().clone();
|
let keyword = self.previous().clone();
|
||||||
let mut exprs = vec![];
|
let mut exprs = vec![];
|
||||||
loop {
|
if !self.check(&TokenType::Dedent) {
|
||||||
exprs.push(self.expression()?);
|
loop {
|
||||||
if !self.match_token(&[TokenType::Comma]) {
|
exprs.push(self.expression()?);
|
||||||
break;
|
if !self.match_token(&[TokenType::Comma]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Stmt::Return { keyword, exprs })
|
Ok(Stmt::Return { keyword, exprs })
|
||||||
|
|||||||
@@ -81,11 +81,11 @@ func mem.free[x: any] : void
|
|||||||
|
|
||||||
func ptr.free[x: ptr] : void
|
func ptr.free[x: ptr] : void
|
||||||
if x == 0
|
if x == 0
|
||||||
return 0
|
return
|
||||||
|
|
||||||
blk := (x - MEM_BLOCK_SIZE) as mem.Block
|
blk := (x - MEM_BLOCK_SIZE) as mem.Block
|
||||||
if blk->free
|
if blk->free
|
||||||
return 0
|
return
|
||||||
|
|
||||||
blk->free = true
|
blk->free = true
|
||||||
|
|
||||||
@@ -733,7 +733,7 @@ func i64.to_str_buf[n: i64, buf: ptr] : void
|
|||||||
if n == 0
|
if n == 0
|
||||||
buf[0] = '0'
|
buf[0] = '0'
|
||||||
buf[1] = 0
|
buf[1] = 0
|
||||||
return 0
|
return
|
||||||
|
|
||||||
neg : bool = n < 0
|
neg : bool = n < 0
|
||||||
if neg
|
if neg
|
||||||
@@ -768,7 +768,7 @@ func i64.to_hex_str_buf[n: i64, buf: ptr] : void
|
|||||||
if n == 0
|
if n == 0
|
||||||
buf[0] = '0'
|
buf[0] = '0'
|
||||||
buf[1] = 0
|
buf[1] = 0
|
||||||
return 0
|
return
|
||||||
|
|
||||||
mask := (1 << 60) - 1
|
mask := (1 << 60) - 1
|
||||||
tmp := _stackalloc(17)
|
tmp := _stackalloc(17)
|
||||||
@@ -849,7 +849,7 @@ func Array.new_preallocated_and_zeroed[size: i64] : Array
|
|||||||
|
|
||||||
func Array.nth[xs: Array, n: i64] : any
|
func Array.nth[xs: Array, n: i64] : any
|
||||||
if n < 0 || n >= xs->size
|
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)
|
return mem.read64(xs->data + n * 8)
|
||||||
|
|
||||||
func Array.set[xs: Array, n: i64, x: any] : void
|
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
|
func Array.pop[xs: Array] : any
|
||||||
if xs->size == 0
|
if xs->size == 0
|
||||||
panic("array.pop on empty array")
|
panic("Array.pop on empty array")
|
||||||
x : any = xs->nth(xs->size - 1)
|
x : any = Array.last(xs)
|
||||||
xs->size = xs->size - 1
|
xs->size = xs->size - 1
|
||||||
return x
|
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
|
func Array.slice[xs: Array, start: i64, length: i64] : Array
|
||||||
if start < 0 || length < 0 || start + length > xs->size
|
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)
|
new_array := Array.new_preallocated_and_zeroed(length)
|
||||||
mem.copy(xs->data + start * 8, new_array->data, length * 8)
|
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
|
while current as ptr
|
||||||
if current->key->equal(key)
|
if current->key->equal(key)
|
||||||
current->value = value
|
current->value = value
|
||||||
return 0
|
return
|
||||||
current = current->next
|
current = current->next
|
||||||
|
|
||||||
new_node := new* HashMap._Node
|
new_node := new* HashMap._Node
|
||||||
@@ -1005,7 +1010,7 @@ func HashMap.delete[map: HashMap, key: str] : void
|
|||||||
|
|
||||||
current->key->free()
|
current->key->free()
|
||||||
mem.free(current)
|
mem.free(current)
|
||||||
return 0
|
return
|
||||||
|
|
||||||
prev = current
|
prev = current
|
||||||
current = current->next
|
current = current->next
|
||||||
|
|||||||
@@ -329,17 +329,16 @@ impl<'a> TypeChecker<'a> {
|
|||||||
env.pop_scope();
|
env.pop_scope();
|
||||||
}
|
}
|
||||||
Stmt::Return { keyword, exprs } => {
|
Stmt::Return { keyword, exprs } => {
|
||||||
let expected = if self.current_function_return_type == "void" {
|
let joined_type = if exprs.is_empty() {
|
||||||
"i64".into()
|
"void".into()
|
||||||
} else {
|
} 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
|
expect_type!(joined_type, self.current_function_return_type, keyword.loc);
|
||||||
.iter()
|
|
||||||
.map(|e| self.typecheck_expr(env, e))
|
|
||||||
.collect::<Result<Vec<String>, _>>()?
|
|
||||||
.join(",");
|
|
||||||
expect_type!(joined_type, expected, keyword.loc);
|
|
||||||
}
|
}
|
||||||
Stmt::Break => {}
|
Stmt::Break => {}
|
||||||
Stmt::Continue => {}
|
Stmt::Continue => {}
|
||||||
|
|||||||
4
test.zr
4
test.zr
@@ -5,7 +5,7 @@ func run_test[x: str] : void
|
|||||||
for i in 0..build_blacklist->size
|
for i in 0..build_blacklist->size
|
||||||
if x->equal(build_blacklist->nth(i))
|
if x->equal(build_blacklist->nth(i))
|
||||||
io.printf("Skipping %s...\n", x)
|
io.printf("Skipping %s...\n", x)
|
||||||
return 0
|
return
|
||||||
|
|
||||||
io.printf("Building %s...\n", x)
|
io.printf("Building %s...\n", x)
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ func run_test[x: str] : void
|
|||||||
for i in 0..run_blacklist->size
|
for i in 0..run_blacklist->size
|
||||||
if x->contains(run_blacklist->nth(i))
|
if x->contains(run_blacklist->nth(i))
|
||||||
io.printf("Skipping %s...\n", x)
|
io.printf("Skipping %s...\n", x)
|
||||||
return 0
|
return
|
||||||
|
|
||||||
io.printf("Running %s...\n", x)
|
io.printf("Running %s...\n", x)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user