seems to be compiling
This commit is contained in:
parent
58f4837ae0
commit
3f30735eaa
|
@ -378,7 +378,7 @@ main := fn(): int {
|
||||||
gb := 0
|
gb := 0
|
||||||
|
|
||||||
foo := fn(a: int, b: int, c: int): int {
|
foo := fn(a: int, b: int, c: int): int {
|
||||||
if true | gb == 0 return 1
|
if false | gb != 0 return 1
|
||||||
return a + b + c
|
return a + b + c
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -528,6 +528,99 @@ main := fn(): int {
|
||||||
|
|
||||||
### Purely Testing Examples
|
### Purely Testing Examples
|
||||||
|
|
||||||
|
#### smh_happened
|
||||||
|
```hb
|
||||||
|
render := @use("render.hb")
|
||||||
|
|
||||||
|
main := fn(): void {
|
||||||
|
render.init(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// in module: stn.hb
|
||||||
|
|
||||||
|
string := @use("string.hb")
|
||||||
|
dt := @use("dt.hb")
|
||||||
|
memory := @use("memory.hb")
|
||||||
|
|
||||||
|
// in module: memory.hb
|
||||||
|
|
||||||
|
PAGE_SIZE := 4096
|
||||||
|
MAX_ALLOC := 0xFF
|
||||||
|
|
||||||
|
alloc := fn($Expr: type, num: int): ^Expr {
|
||||||
|
pages := 1 + @bitcast(@sizeof(Expr)) * num / PAGE_SIZE
|
||||||
|
if pages <= MAX_ALLOC {
|
||||||
|
return @bitcast(@inline(request_page, pages))
|
||||||
|
}
|
||||||
|
ptr := @inline(request_page, 0xFF)
|
||||||
|
remaining := pages - MAX_ALLOC
|
||||||
|
loop if remaining <= 0 break else {
|
||||||
|
if remaining < MAX_ALLOC {
|
||||||
|
request_page(remaining)
|
||||||
|
} else {
|
||||||
|
request_page(MAX_ALLOC)
|
||||||
|
}
|
||||||
|
remaining -= MAX_ALLOC
|
||||||
|
}
|
||||||
|
return @bitcast(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
request_page := fn(page_count: u8): ^u8 {
|
||||||
|
msg := "\{00}\{01}xxxxxxxx\0"
|
||||||
|
msg_page_count := msg + 1;
|
||||||
|
*msg_page_count = page_count
|
||||||
|
return @eca(3, 2, msg, 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
// in module: string.hb
|
||||||
|
|
||||||
|
length := fn(ptr: ^u8): uint {
|
||||||
|
len := @as(uint, 0)
|
||||||
|
loop if *(ptr + len) == 0 break else len += 1
|
||||||
|
return len
|
||||||
|
}
|
||||||
|
|
||||||
|
// in module: dt.hb
|
||||||
|
|
||||||
|
.{string} := @use("stn.hb")
|
||||||
|
|
||||||
|
get := fn($Expr: type, query: ^u8): Expr {
|
||||||
|
return @eca(3, 5, query, @inline(string.length, query))
|
||||||
|
}
|
||||||
|
|
||||||
|
// in module: render.hb
|
||||||
|
|
||||||
|
.{dt, memory} := @use("stn.hb")
|
||||||
|
Color := packed struct {b: u8, g: u8, r: u8, a: u8}
|
||||||
|
|
||||||
|
Surface := struct {
|
||||||
|
buf: ^Color,
|
||||||
|
width: int,
|
||||||
|
height: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
new_surface := fn(width: int, height: int): Surface {
|
||||||
|
return .(
|
||||||
|
@inline(memory.alloc, Color, width * height),
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
init := fn(doublebuffer: bool): Surface {
|
||||||
|
framebuffer := dt.get(^Color, "framebuffer/fb0/ptr\0")
|
||||||
|
width := dt.get(int, "framebuffer/fb0/width\0")
|
||||||
|
height := dt.get(int, "framebuffer/fb0/height\0")
|
||||||
|
if doublebuffer {
|
||||||
|
return new_surface(width, height)
|
||||||
|
} else {
|
||||||
|
return .(framebuffer, width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
#### wide_ret
|
#### wide_ret
|
||||||
```hb
|
```hb
|
||||||
OemIdent := struct {
|
OemIdent := struct {
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl StoreId for Nid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::ctx_map::CtxEntry for Nid {
|
impl crate::ctx_map::CtxEntry for Nid {
|
||||||
type Ctx = [Result<Node, Nid>];
|
type Ctx = [Result<Node, (Nid, Trace)>];
|
||||||
type Key<'a> = (Kind, &'a [Nid], ty::Id);
|
type Key<'a> = (Kind, &'a [Nid], ty::Id);
|
||||||
|
|
||||||
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a> {
|
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a> {
|
||||||
|
@ -57,9 +57,23 @@ impl crate::ctx_map::CtxEntry for Nid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
type Trace = std::rc::Rc<std::backtrace::Backtrace>;
|
||||||
|
#[cfg(not(test))]
|
||||||
|
type Trace = ();
|
||||||
|
|
||||||
|
fn trace() -> Trace {
|
||||||
|
#[cfg(test)]
|
||||||
|
{
|
||||||
|
std::rc::Rc::new(std::backtrace::Backtrace::capture())
|
||||||
|
}
|
||||||
|
#[cfg(not(test))]
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Nodes {
|
struct Nodes {
|
||||||
values: Vec<Result<Node, Nid>>,
|
values: Vec<Result<Node, (Nid, Trace)>>,
|
||||||
visited: BitSet,
|
visited: BitSet,
|
||||||
free: Nid,
|
free: Nid,
|
||||||
lookup: Lookup,
|
lookup: Lookup,
|
||||||
|
@ -130,11 +144,12 @@ impl Nodes {
|
||||||
|
|
||||||
fn remove_low(&mut self, id: Nid) -> Node {
|
fn remove_low(&mut self, id: Nid) -> Node {
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
let value = mem::replace(&mut self.values[id as usize], Err(self.free)).unwrap();
|
let value =
|
||||||
|
mem::replace(&mut self.values[id as usize], Err((self.free, trace()))).unwrap();
|
||||||
self.free = id;
|
self.free = id;
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
mem::replace(&mut self.values[id as usize], Err(Nid::MAX)).unwrap()
|
mem::replace(&mut self.values[id as usize], Err((Nid::MAX, trace()))).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +177,7 @@ impl Nodes {
|
||||||
|
|
||||||
if self.free == Nid::MAX {
|
if self.free == Nid::MAX {
|
||||||
self.free = self.values.len() as _;
|
self.free = self.values.len() as _;
|
||||||
self.values.push(Err(Nid::MAX));
|
self.values.push(Err((Nid::MAX, trace())));
|
||||||
}
|
}
|
||||||
|
|
||||||
let free = self.free;
|
let free = self.free;
|
||||||
|
@ -170,7 +185,7 @@ impl Nodes {
|
||||||
debug_assert_ne!(d, free);
|
debug_assert_ne!(d, free);
|
||||||
self.values[d as usize].as_mut().unwrap_or_else(|_| panic!("{d}")).outputs.push(free);
|
self.values[d as usize].as_mut().unwrap_or_else(|_| panic!("{d}")).outputs.push(free);
|
||||||
}
|
}
|
||||||
self.free = mem::replace(&mut self.values[free as usize], Ok(node)).unwrap_err();
|
self.free = mem::replace(&mut self.values[free as usize], Ok(node)).unwrap_err().0;
|
||||||
|
|
||||||
if let Some((entry, hash)) = lookup_meta {
|
if let Some((entry, hash)) = lookup_meta {
|
||||||
entry.insert(crate::ctx_map::Key { value: free, hash }, ());
|
entry.insert(crate::ctx_map::Key { value: free, hash }, ());
|
||||||
|
@ -219,7 +234,7 @@ impl Nodes {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(!matches!(self[target].kind, Kind::Call { .. }));
|
debug_assert!(!matches!(self[target].kind, Kind::Call { .. }), "{:?}", self[target]);
|
||||||
|
|
||||||
for i in 0..self[target].inputs.len() {
|
for i in 0..self[target].inputs.len() {
|
||||||
let inp = self[target].inputs[i];
|
let inp = self[target].inputs[i];
|
||||||
|
@ -935,13 +950,13 @@ impl ops::Index<Nid> for Nodes {
|
||||||
type Output = Node;
|
type Output = Node;
|
||||||
|
|
||||||
fn index(&self, index: Nid) -> &Self::Output {
|
fn index(&self, index: Nid) -> &Self::Output {
|
||||||
self.values[index as usize].as_ref().unwrap()
|
self.values[index as usize].as_ref().unwrap_or_else(|(_, bt)| panic!("{index} {bt:#?}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::IndexMut<Nid> for Nodes {
|
impl ops::IndexMut<Nid> for Nodes {
|
||||||
fn index_mut(&mut self, index: Nid) -> &mut Self::Output {
|
fn index_mut(&mut self, index: Nid) -> &mut Self::Output {
|
||||||
self.values[index as usize].as_mut().unwrap()
|
self.values[index as usize].as_mut().unwrap_or_else(|(_, bt)| panic!("{index} {bt:#?}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2048,14 +2063,17 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes[NEVER].inputs.push(self.ci.ctrl);
|
self.ci.nodes[NEVER].inputs.push(self.ci.ctrl);
|
||||||
self.ci.nodes[self.ci.ctrl].outputs.push(NEVER);
|
self.ci.nodes[self.ci.ctrl].outputs.push(NEVER);
|
||||||
} else if let Some((pv, ctrl)) = &mut self.ci.inline_ret {
|
} else if let Some((pv, ctrl)) = &mut self.ci.inline_ret {
|
||||||
|
self.ci.nodes.unlock(*ctrl);
|
||||||
*ctrl =
|
*ctrl =
|
||||||
self.ci.nodes.new_node(ty::Id::VOID, Kind::Region, [self.ci.ctrl, *ctrl]);
|
self.ci.nodes.new_node(ty::Id::VOID, Kind::Region, [self.ci.ctrl, *ctrl]);
|
||||||
|
self.ci.nodes.lock(*ctrl);
|
||||||
self.ci.ctrl = *ctrl;
|
self.ci.ctrl = *ctrl;
|
||||||
self.ci.nodes.unlock(pv.id);
|
self.ci.nodes.unlock(pv.id);
|
||||||
pv.id = self.ci.nodes.new_node(value.ty, Kind::Phi, [*ctrl, value.id, pv.id]);
|
pv.id = self.ci.nodes.new_node(value.ty, Kind::Phi, [*ctrl, value.id, pv.id]);
|
||||||
self.ci.nodes.lock(pv.id);
|
self.ci.nodes.lock(pv.id);
|
||||||
} else {
|
} else {
|
||||||
self.ci.nodes.lock(value.id);
|
self.ci.nodes.lock(value.id);
|
||||||
|
self.ci.nodes.lock(self.ci.ctrl);
|
||||||
self.ci.inline_ret = Some((value, self.ci.ctrl));
|
self.ci.inline_ret = Some((value, self.ci.ctrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2501,9 +2519,10 @@ impl<'a> Codegen<'a> {
|
||||||
return Value::NEVER;
|
return Value::NEVER;
|
||||||
};
|
};
|
||||||
|
|
||||||
let fuc = &self.tys.ins.funcs[fu as usize];
|
let Func { expr, file, .. } = self.tys.ins.funcs[fu as usize];
|
||||||
let ast = &self.files[fuc.file as usize];
|
|
||||||
let &Expr::Closure { args: cargs, body, .. } = fuc.expr.get(ast) else {
|
let ast = &self.files[file as usize];
|
||||||
|
let &Expr::Closure { args: cargs, body, .. } = expr.get(ast) else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2550,6 +2569,7 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let prev_ret = self.ci.ret.replace(sig.ret);
|
let prev_ret = self.ci.ret.replace(sig.ret);
|
||||||
let prev_inline_ret = self.ci.inline_ret.take();
|
let prev_inline_ret = self.ci.inline_ret.take();
|
||||||
|
let prev_file = core::mem::replace(&mut self.ci.file, file);
|
||||||
self.ci.inline_depth += 1;
|
self.ci.inline_depth += 1;
|
||||||
|
|
||||||
if self.expr(body).is_some() && sig.ret == ty::Id::VOID {
|
if self.expr(body).is_some() && sig.ret == ty::Id::VOID {
|
||||||
|
@ -2561,12 +2581,14 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.ret = prev_ret;
|
self.ci.ret = prev_ret;
|
||||||
|
self.ci.file = prev_file;
|
||||||
self.ci.inline_depth -= 1;
|
self.ci.inline_depth -= 1;
|
||||||
for var in self.ci.scope.vars.drain(arg_base..) {
|
for var in self.ci.scope.vars.drain(arg_base..) {
|
||||||
self.ci.nodes.unlock_remove(var.value);
|
self.ci.nodes.unlock_remove(var.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
core::mem::replace(&mut self.ci.inline_ret, prev_inline_ret).map(|(v, _)| {
|
core::mem::replace(&mut self.ci.inline_ret, prev_inline_ret).map(|(v, ctrl)| {
|
||||||
|
self.ci.nodes.unlock(ctrl);
|
||||||
self.ci.nodes.unlock(v.id);
|
self.ci.nodes.unlock(v.id);
|
||||||
v
|
v
|
||||||
})
|
})
|
||||||
|
@ -3145,6 +3167,7 @@ impl<'a> Codegen<'a> {
|
||||||
from: &mut Scope,
|
from: &mut Scope,
|
||||||
drop_from: bool,
|
drop_from: bool,
|
||||||
) {
|
) {
|
||||||
|
nodes.lock(ctrl);
|
||||||
for (i, ((.., ty, to_value), (.., from_value))) in
|
for (i, ((.., ty, to_value), (.., from_value))) in
|
||||||
to.iter_elems_mut().zip(from.iter_elems_mut()).enumerate()
|
to.iter_elems_mut().zip(from.iter_elems_mut()).enumerate()
|
||||||
{
|
{
|
||||||
|
@ -3170,6 +3193,7 @@ impl<'a> Codegen<'a> {
|
||||||
if drop_from {
|
if drop_from {
|
||||||
nodes.unlock_remove_scope(from);
|
nodes.unlock_remove_scope(from);
|
||||||
}
|
}
|
||||||
|
nodes.unlock(ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -4170,6 +4194,7 @@ mod tests {
|
||||||
fb_driver;
|
fb_driver;
|
||||||
|
|
||||||
// Purely Testing Examples;
|
// Purely Testing Examples;
|
||||||
|
smh_happened;
|
||||||
wide_ret;
|
wide_ret;
|
||||||
comptime_min_reg_leak;
|
comptime_min_reg_leak;
|
||||||
different_types;
|
different_types;
|
||||||
|
|
|
@ -2,13 +2,17 @@ main:
|
||||||
LI64 r5, 0d
|
LI64 r5, 0d
|
||||||
LRA r4, r0, :gb
|
LRA r4, r0, :gb
|
||||||
LD r6, r4, 0a, 8h
|
LD r6, r4, 0a, 8h
|
||||||
LI64 r9, 6d
|
CMPS r9, r6, r5
|
||||||
JEQ r6, r5, :0
|
CMPUI r9, r9, 0d
|
||||||
LI64 r12, 1d
|
ORI r11, r9, 0d
|
||||||
|
LI64 r1, 6d
|
||||||
|
ANDI r11, r11, 255d
|
||||||
|
JNE r11, r0, :0
|
||||||
|
CP r5, r1
|
||||||
JMP :1
|
JMP :1
|
||||||
0: CP r12, r9
|
0: LI64 r5, 1d
|
||||||
1: SUB64 r1, r12, r9
|
1: SUB64 r1, r5, r1
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 94
|
code size: 131
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
0
lang/tests/son_tests_smh_happened.txt
Normal file
0
lang/tests/son_tests_smh_happened.txt
Normal file
Loading…
Reference in a new issue