seems to be compiling

This commit is contained in:
Jakub Doka 2024-10-22 16:53:48 +02:00
parent 58f4837ae0
commit 3f30735eaa
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
4 changed files with 142 additions and 20 deletions

View file

@ -378,7 +378,7 @@ main := fn(): int {
gb := 0
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
}
```
@ -528,6 +528,99 @@ main := fn(): int {
### 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
```hb
OemIdent := struct {

View file

@ -49,7 +49,7 @@ impl StoreId 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);
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)]
struct Nodes {
values: Vec<Result<Node, Nid>>,
values: Vec<Result<Node, (Nid, Trace)>>,
visited: BitSet,
free: Nid,
lookup: Lookup,
@ -130,11 +144,12 @@ impl Nodes {
fn remove_low(&mut self, id: Nid) -> Node {
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;
value
} 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 {
self.free = self.values.len() as _;
self.values.push(Err(Nid::MAX));
self.values.push(Err((Nid::MAX, trace())));
}
let free = self.free;
@ -170,7 +185,7 @@ impl Nodes {
debug_assert_ne!(d, 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 {
entry.insert(crate::ctx_map::Key { value: free, hash }, ());
@ -219,7 +234,7 @@ impl Nodes {
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() {
let inp = self[target].inputs[i];
@ -935,13 +950,13 @@ impl ops::Index<Nid> for Nodes {
type Output = Node;
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 {
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[self.ci.ctrl].outputs.push(NEVER);
} else if let Some((pv, ctrl)) = &mut self.ci.inline_ret {
self.ci.nodes.unlock(*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.nodes.unlock(pv.id);
pv.id = self.ci.nodes.new_node(value.ty, Kind::Phi, [*ctrl, value.id, pv.id]);
self.ci.nodes.lock(pv.id);
} else {
self.ci.nodes.lock(value.id);
self.ci.nodes.lock(self.ci.ctrl);
self.ci.inline_ret = Some((value, self.ci.ctrl));
}
@ -2501,9 +2519,10 @@ impl<'a> Codegen<'a> {
return Value::NEVER;
};
let fuc = &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 Func { expr, file, .. } = self.tys.ins.funcs[fu as usize];
let ast = &self.files[file as usize];
let &Expr::Closure { args: cargs, body, .. } = expr.get(ast) else {
unreachable!()
};
@ -2550,6 +2569,7 @@ impl<'a> Codegen<'a> {
let prev_ret = self.ci.ret.replace(sig.ret);
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;
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.file = prev_file;
self.ci.inline_depth -= 1;
for var in self.ci.scope.vars.drain(arg_base..) {
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);
v
})
@ -3145,6 +3167,7 @@ impl<'a> Codegen<'a> {
from: &mut Scope,
drop_from: bool,
) {
nodes.lock(ctrl);
for (i, ((.., ty, to_value), (.., from_value))) in
to.iter_elems_mut().zip(from.iter_elems_mut()).enumerate()
{
@ -3170,6 +3193,7 @@ impl<'a> Codegen<'a> {
if drop_from {
nodes.unlock_remove_scope(from);
}
nodes.unlock(ctrl);
}
#[inline(always)]
@ -4170,6 +4194,7 @@ mod tests {
fb_driver;
// Purely Testing Examples;
smh_happened;
wide_ret;
comptime_min_reg_leak;
different_types;

View file

@ -2,13 +2,17 @@ main:
LI64 r5, 0d
LRA r4, r0, :gb
LD r6, r4, 0a, 8h
LI64 r9, 6d
JEQ r6, r5, :0
LI64 r12, 1d
CMPS r9, r6, r5
CMPUI r9, r9, 0d
ORI r11, r9, 0d
LI64 r1, 6d
ANDI r11, r11, 255d
JNE r11, r0, :0
CP r5, r1
JMP :1
0: CP r12, r9
1: SUB64 r1, r12, r9
0: LI64 r5, 1d
1: SUB64 r1, r5, r1
JALA r0, r31, 0a
code size: 94
code size: 131
ret: 0
status: Ok(())

View file