Compare commits
No commits in common. "f013e90936308deb015808a4404858e63103b1a0" and "3f30735eaa9a182b83ad4990ab9f50d6539fb98f" have entirely different histories.
f013e90936
...
3f30735eaa
|
@ -89,6 +89,7 @@ pub enum DisasmError<'a> {
|
|||
InstructionOutOfBounds(&'a str),
|
||||
FmtFailed(core::fmt::Error),
|
||||
HasOutOfBoundsJumps,
|
||||
HasDirectInstructionCycles,
|
||||
}
|
||||
|
||||
#[cfg(feature = "disasm")]
|
||||
|
@ -112,6 +113,9 @@ impl core::fmt::Display for DisasmError<'_> {
|
|||
"the code contained jumps that dont got neither to a \
|
||||
valid symbol or local insturction"
|
||||
),
|
||||
DisasmError::HasDirectInstructionCycles => {
|
||||
writeln!(f, "found instruction that jumps to itself")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +145,7 @@ pub fn disasm<'a>(
|
|||
|
||||
let mut labels = BTreeMap::<u32, u32>::default();
|
||||
let mut buf = Vec::<instrs::Oper>::new();
|
||||
let mut has_cycle = false;
|
||||
let mut has_oob = false;
|
||||
|
||||
'_offset_pass: for (&off, &(name, len, kind)) in functions.iter() {
|
||||
|
@ -169,6 +174,8 @@ pub fn disasm<'a>(
|
|||
_ => continue,
|
||||
};
|
||||
|
||||
has_cycle |= rel == 0;
|
||||
|
||||
let global_offset: u32 = (offset + rel).try_into().unwrap();
|
||||
if functions.get(&global_offset).is_some() {
|
||||
continue;
|
||||
|
@ -280,5 +287,9 @@ pub fn disasm<'a>(
|
|||
return Err(DisasmError::HasOutOfBoundsJumps);
|
||||
}
|
||||
|
||||
if has_cycle {
|
||||
return Err(DisasmError::HasDirectInstructionCycles);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
104
lang/README.md
104
lang/README.md
|
@ -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 {
|
||||
|
@ -926,14 +1019,6 @@ main := fn(arg: int): int {
|
|||
#### exhaustive_loop_testing
|
||||
```hb
|
||||
main := fn(): int {
|
||||
loop break
|
||||
|
||||
x := 0
|
||||
loop {
|
||||
x += 1
|
||||
break
|
||||
}
|
||||
|
||||
if multiple_breaks(0) != 3 {
|
||||
return 1
|
||||
}
|
||||
|
@ -958,8 +1043,7 @@ main := fn(): int {
|
|||
return 6
|
||||
}
|
||||
|
||||
loop {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
multiple_breaks := fn(arg: int): int {
|
||||
|
|
618
lang/src/son.rs
618
lang/src/son.rs
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue