This commit is contained in:
mlokr 2024-09-19 17:15:03 +02:00
commit 6b454b2862
23 changed files with 1075 additions and 1481 deletions

283
Cargo.lock generated
View file

@ -1,283 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "arbitrary"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift-bforest"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-bitset"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
[[package]]
name = "cranelift-codegen"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"bumpalo",
"cranelift-bforest",
"cranelift-bitset",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-control",
"cranelift-entity",
"cranelift-isle",
"hashbrown",
"log",
"regalloc2",
"rustc-hash",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
[[package]]
name = "cranelift-control"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
dependencies = [
"cranelift-bitset",
]
[[package]]
name = "cranelift-isle"
version = "0.113.0"
source = "git+https://github.com/jakubDoka/wasmtime.git#969c85a481985be2fa2d555cdb338454f77213c6"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
]
[[package]]
name = "hbbytecode"
version = "0.1.0"
[[package]]
name = "hbcb"
version = "0.1.0"
dependencies = [
"cranelift-codegen",
"cranelift-codegen-meta",
"cranelift-control",
"cranelift-isle",
"log",
"regalloc2",
"smallvec",
"target-lexicon",
]
[[package]]
name = "hbjit"
version = "0.1.0"
[[package]]
name = "hblang"
version = "0.1.0"
dependencies = [
"hbvm",
]
[[package]]
name = "hbvm"
version = "0.1.0"
dependencies = [
"hbbytecode",
]
[[package]]
name = "hbxrt"
version = "0.1.0"
dependencies = [
"hbvm",
"memmap2",
]
[[package]]
name = "libc"
version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "memmap2"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
dependencies = [
"libc",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "proc-macro2"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regalloc2"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
dependencies = [
"hashbrown",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]
[[package]]
name = "rustc-hash"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
[[package]]
name = "slice-group-by"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "syn"
version = "2.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "target-lexicon"
version = "0.12.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "xtask"
version = "0.1.0"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View file

@ -9,3 +9,4 @@ path = "src/main.rs"
[dependencies]
hbvm = { path = "../hbvm", features = ["nightly"] }
regalloc2 = { git = "https://github.com/jakubDoka/regalloc2" }

View file

@ -237,7 +237,7 @@ main := fn(): int {
size_of_Type_in_bytes := @sizeof(foo.Type)
align_of_Type_in_bytes := @alignof(foo.Type)
hardcoded_pointer := @as(^u8, @bitcast(10))
ecall_that_returns_int := @eca(int, 1, foo.Type.(10, 20), 5, 6)
ecall_that_returns_int := @as(int, @eca(1, foo.Type.(10, 20), 5, 6))
return @inline(foo.foo)
}
@ -356,6 +356,29 @@ main := fn(): int {
}
```
#### wide_ret
```hb
OemIdent := struct {
dos_version: [u8; 8],
dos_version_name: [u8; 8],
}
Stru := struct {
a: u16,
b: u16,
}
small_struct := fn(): Stru {
return .{a: 0, b: 0}
}
main := fn(major: int, minor: int): OemIdent {
small_struct()
ver := [u8].(0, 0, 0, 0, 0, 0, 0, 0)
return OemIdent.(ver, ver)
}
```
### Incomplete Examples
#### comptime_pointers
@ -376,8 +399,8 @@ modify := fn($num: ^int): void {
MALLOC_SYS_CALL := 69
FREE_SYS_CALL := 96
malloc := fn(size: uint, align: uint): ^void return @eca(^void, MALLOC_SYS_CALL, size, align)
free := fn(ptr: ^void, size: uint, align: uint): void return @eca(void, FREE_SYS_CALL, ptr, size, align)
malloc := fn(size: uint, align: uint): ^void return @eca(MALLOC_SYS_CALL, size, align)
free := fn(ptr: ^void, size: uint, align: uint): void return @eca(FREE_SYS_CALL, ptr, size, align)
Vec := fn($Elem: type): type {
return struct {
@ -750,7 +773,7 @@ screenidx := fn(orange: int): int {
// in module: random.hb
integer := fn(min: int, max: int): int {
rng := @eca(int, 3, 4)
rng := @as(int, @eca(3, 4))
if min != 0 | max != 0 {
return rng % (max - min + 1) + min
@ -781,7 +804,7 @@ main := fn(): void {
// in module: random.hb
integer_range := fn(min: uint, max: int): uint {
return @eca(uint, 3, 4) % (@bitcast(max) - min + 1) + min
return @eca(3, 4) % (@bitcast(max) - min + 1) + min
}
```
@ -876,7 +899,7 @@ request_page := fn(page_count: u8): ^u8 {
msg := "\{00}\{01}xxxxxxxx\0"
msg_page_count := msg + 1;
*msg_page_count = page_count
return @eca(^u8, 3, 2, msg, 12)
return @eca(3, 2, msg, 12)
}
create_back_buffer := fn(total_pages: int): ^u32 {

View file

@ -898,13 +898,21 @@ impl Codegen {
E::Directive { name: "TypeOf", args: [expr], .. } => {
Some(Value::ty(self.infer_type(expr)))
}
E::Directive { name: "eca", args: [ret_ty, args @ ..], .. } => {
let ty = self.ty(ret_ty);
E::Directive { name: "eca", args, pos } => {
let Some(ty) = ctx.ty else {
self.report(
pos,
"type to return form eca is unknown, use `@as(<type>, @eca(...<expr>))`",
);
};
let mut parama = self.tys.parama(ty);
let base = self.pool.arg_locs.len();
for arg in args {
let arg = self.expr(arg)?;
if arg.ty == ty::Id::from(ty::TYPE) {
self.report(pos, "na na na nana, no passing types to ecas");
}
self.pass_arg(&arg, &mut parama);
self.pool.arg_locs.push(arg.loc);
}
@ -932,7 +940,7 @@ impl Codegen {
let Some(ty) = ctx.ty else {
self.report(
expr.pos(),
"type to cast to is unknown, use `@as(<type>, <expr>)`",
"type to cast to is unknown, use `@as(<type>, @intcast(<expr>))`",
);
};
let mut val = self.expr(val)?;
@ -1086,7 +1094,7 @@ impl Codegen {
Some(Value::new(self.tys.make_ptr(ty::U8.into()), reg))
}
E::Ctor { pos, ty, fields, .. } => {
let (ty, loc) = self.prepare_struct_ctor(pos, ctx, ty, fields.len());
let (ty, loc) = self.prepare_struct_ctor(pos, &mut ctx, ty, fields.len());
let ty::Kind::Struct(stru) = ty.expand() else {
self.report(
@ -1103,10 +1111,16 @@ impl Codegen {
let value = self.expr_ctx(value, Ctx::default().with_loc(loc).with_ty(ty))?;
self.ci.free_loc(value.loc);
}
return Some(Value { ty, loc });
if let Some(dst_loc) = ctx.loc {
self.store_typed(loc, &dst_loc, ty);
return Some(Value { ty, loc: dst_loc });
} else {
return Some(Value { ty, loc });
}
}
E::Tupl { pos, ty, fields, .. } => {
let (ty, loc) = self.prepare_struct_ctor(pos, ctx, ty, fields.len());
let (ty, loc) = self.prepare_struct_ctor(pos, &mut ctx, ty, fields.len());
match ty.expand() {
ty::Kind::Struct(stru) => {
@ -1141,7 +1155,12 @@ impl Codegen {
),
}
return Some(Value { ty, loc });
if let Some(dst_loc) = ctx.loc {
self.store_typed(loc, &dst_loc, ty);
return Some(Value { ty, loc: dst_loc });
} else {
return Some(Value { ty, loc });
}
}
E::Field { target, name: field } => {
let checkpoint = self.ci.snap();
@ -1369,24 +1388,24 @@ impl Codegen {
tk => Some(Value::ty(tk.compress())),
},
E::Return { pos, val, .. } => {
let ty = if let Some(val) = val {
let size = self.ci.ret.map_or(17, |ty| self.tys.size_of(ty));
let loc = match size {
_ if self.ci.inline_ret_loc != Loc::default() => {
Some(self.ci.inline_ret_loc.as_ref())
}
0 => None,
1..=16 => Some(Loc::reg(1)),
_ => Some(Loc::reg(self.ci.ret_reg.as_ref()).into_derefed()),
};
self.expr_ctx(val, Ctx { ty: self.ci.ret, loc })?.ty
let size = self.ci.ret.map_or(17, |ty| self.tys.size_of(ty));
let loc = match size {
_ if self.ci.inline_ret_loc != Loc::default() => {
Some(self.ci.inline_ret_loc.as_ref())
}
0 => None,
1..=16 => Some(Loc::reg(1)),
_ => Some(Loc::reg(self.ci.ret_reg.as_ref()).into_derefed()),
};
let value = if let Some(val) = val {
self.expr_ctx(val, Ctx { ty: self.ci.ret, loc })?
} else {
ty::VOID.into()
Value::void()
};
match self.ci.ret {
None => self.ci.ret = Some(ty),
Some(ret) => _ = self.assert_ty(pos, ty, ret, "return type"),
None => self.ci.ret = Some(value.ty),
Some(ret) => _ = self.assert_ty(pos, value.ty, ret, "return type"),
}
self.ci.ret_relocs.push(Reloc::new(self.ci.code.len(), 1, 4));
@ -1891,7 +1910,7 @@ impl Codegen {
fn prepare_struct_ctor(
&mut self,
pos: Pos,
ctx: Ctx,
ctx: &mut Ctx,
ty: Option<&Expr>,
field_len: usize,
) -> (ty::Id, Loc) {
@ -1927,8 +1946,11 @@ impl Codegen {
}
let size = self.tys.size_of(ty);
let loc = ctx.loc.unwrap_or_else(|| Loc::stack(self.ci.stack.allocate(size)));
(ty, loc)
if ctx.loc.as_ref().map_or(true, |l| l.is_reg()) {
(ty, Loc::stack(self.ci.stack.allocate(size)))
} else {
(ty, ctx.loc.take().unwrap_or_else(|| Loc::stack(self.ci.stack.allocate(size))))
}
}
fn struct_op(
@ -2278,6 +2300,25 @@ impl Codegen {
self.ci.emit(cp(dst.get(), src.get()));
}
}
//(lpat!(false, src, 0, None), lpat!(false, dst, off, None)) => {
// assert!(size <= 8);
// let off_rem = 8 * (off % 8);
// let freg = dst.get() + (off / 8) as u8;
// if size < 8 {
// let mask = !(((1u64 << (8 * size)) - 1) << off_rem);
// self.ci.emit(andi(freg, freg, mask));
// if off_rem == 0 {
// self.ci.emit(or(freg, freg, src.get()));
// } else {
// let tmp = self.ci.regs.allocate();
// self.ci.emit(slui64(tmp.get(), src.get(), off_rem as _));
// self.ci.emit(or(freg, freg, src.get()));
// self.ci.regs.free(tmp);
// }
// } else {
// self.ci.emit(cp(freg, src.get()));
// }
//}
(lpat!(true, src, soff, ref ssta), lpat!(false, dst, 0, None)) => {
if size < 8 {
self.ci.emit(cp(dst.get(), 0));
@ -2740,5 +2781,6 @@ mod tests {
writing_into_string => README;
request_page => README;
tests_ptr_to_ptr_copy => README;
wide_ret => README;
}
}

View file

@ -371,6 +371,10 @@ impl<'a> Lexer<'a> {
Self { pos, bytes: input.as_bytes() }
}
pub fn source(&self) -> &'a str {
unsafe { std::str::from_utf8_unchecked(self.bytes) }
}
pub fn slice(&self, tok: std::ops::Range<usize>) -> &'a str {
unsafe { std::str::from_utf8_unchecked(&self.bytes[tok]) }
}
@ -511,10 +515,6 @@ impl<'a> Lexer<'a> {
false
}
}
pub fn line_col(&self, pos: u32) -> (usize, usize) {
line_col(self.bytes, pos)
}
}
pub fn line_col(bytes: &[u8], pos: u32) -> (usize, usize) {

View file

@ -30,7 +30,7 @@ use {
parser::Ast,
std::{
collections::{hash_map, BTreeMap, VecDeque},
io::{self, Read},
io,
ops::Range,
path::{Path, PathBuf},
rc::Rc,
@ -601,6 +601,19 @@ impl ParamAlloc {
}
}
#[repr(packed)]
#[allow(dead_code)]
struct AbleOsExecutableHeader {
magic_number: [u8; 3],
executable_version: u32,
code_length: u64,
data_length: u64,
debug_length: u64,
config_length: u64,
metadata_length: u64,
}
#[derive(Default)]
struct Types {
syms: HashMap<SymKey, ty::Id>,
@ -613,15 +626,24 @@ struct Types {
arrays: Vec<Array>,
}
const HEADER_SIZE: usize = std::mem::size_of::<AbleOsExecutableHeader>();
impl Types {
fn assemble(&mut self, to: &mut Vec<u8>) {
to.extend([0u8; HEADER_SIZE]);
emit(to, instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
emit(to, instrs::tx());
self.dump_reachable(0, to);
Reloc::new(0, 3, 4).apply_jump(to, self.funcs[0].offset, 0);
let exe = self.dump_reachable(0, to);
Reloc::new(HEADER_SIZE, 3, 4).apply_jump(to, self.funcs[0].offset, 0);
unsafe { *to.as_mut_ptr().cast::<AbleOsExecutableHeader>() = exe }
}
fn dump_reachable(&mut self, from: ty::Func, to: &mut Vec<u8>) {
fn dump_reachable(&mut self, from: ty::Func, to: &mut Vec<u8>) -> AbleOsExecutableHeader {
let mut used_funcs = vec![];
let mut used_globals = vec![];
let mut frontier = vec![ty::Kind::Func(from).compress()];
while let Some(itm) = frontier.pop() {
@ -631,8 +653,8 @@ impl Types {
if task::is_done(fuc.offset) {
continue;
}
fuc.offset = to.len() as _;
to.extend(&fuc.code);
fuc.offset = 0;
used_funcs.push(func);
frontier.extend(fuc.relocs.iter().map(|r| r.target));
}
ty::Kind::Global(glob) => {
@ -640,18 +662,31 @@ impl Types {
if task::is_done(glb.offset) {
continue;
}
glb.offset = to.len() as _;
to.extend(&glb.data);
glb.offset = 0;
used_globals.push(glob);
}
_ => unreachable!(),
}
}
for fuc in &self.funcs {
if !task::is_done(fuc.offset) {
continue;
}
for &func in &used_funcs {
let fuc = &mut self.funcs[func as usize];
fuc.offset = to.len() as _;
to.extend(&fuc.code);
}
let code_length = to.len();
for &global in &used_globals {
let global = &mut self.globals[global as usize];
global.offset = to.len() as _;
to.extend(&global.data);
}
let data_length = to.len() - code_length;
for func in used_funcs {
let fuc = &self.funcs[func as usize];
for rel in &fuc.relocs {
let offset = match rel.target.expand() {
ty::Kind::Func(fun) => self.funcs[fun as usize].offset,
@ -661,6 +696,16 @@ impl Types {
rel.reloc.apply_jump(to, offset, fuc.offset);
}
}
AbleOsExecutableHeader {
magic_number: [0x15, 0x91, 0xD2],
executable_version: 0,
code_length: (code_length - HEADER_SIZE) as _,
data_length: data_length as _,
debug_length: 0,
config_length: 0,
metadata_length: 0,
}
}
pub fn disasm(
@ -892,7 +937,10 @@ fn disasm(
*binary = prev;
}
'_dump: for (&off, &(name, len, kind)) in functions.iter() {
let mut ordered = functions.iter().collect::<Vec<_>>();
ordered.sort_unstable_by_key(|(_, (name, _, _))| name);
'_dump: for (&off, &(name, len, kind)) in ordered {
if matches!(kind, DisasmItem::Global) {
continue;
}
@ -1070,107 +1118,24 @@ impl<T> TaskQueueInner<T> {
}
pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Vec<Ast>> {
const GIT_DEPS_DIR: &str = "git-deps";
fn resolve(path: &str, from: &str) -> Result<PathBuf, CantLoadFile> {
let path = match Path::new(from).parent() {
Some(parent) => PathBuf::from_iter([parent, Path::new(path)]),
None => PathBuf::from(path),
};
enum Chk<'a> {
Branch(&'a str),
Rev(&'a str),
Tag(&'a str),
}
enum ImportPath<'a> {
Rel { path: &'a str },
Git { link: &'a str, path: &'a str, chk: Option<Chk<'a>> },
}
impl<'a> TryFrom<&'a str> for ImportPath<'a> {
type Error = ParseImportError;
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
let (prefix, path) = value.split_once(':').unwrap_or(("", value));
match prefix {
"rel" | "" => Ok(Self::Rel { path }),
"git" => {
let (link, path) =
path.split_once(':').ok_or(ParseImportError::ExpectedPath)?;
let (link, params) = link.split_once('?').unwrap_or((link, ""));
let chk = params.split('&').filter_map(|s| s.split_once('=')).find_map(
|(key, value)| match key {
"branch" => Some(Chk::Branch(value)),
"rev" => Some(Chk::Rev(value)),
"tag" => Some(Chk::Tag(value)),
_ => None,
},
);
Ok(Self::Git { link, path, chk })
}
_ => Err(ParseImportError::InvalidPrefix),
}
}
}
fn preprocess_git(link: &str) -> &str {
let link = link.strip_prefix("https://").unwrap_or(link);
link.strip_suffix(".git").unwrap_or(link)
}
impl<'a> ImportPath<'a> {
fn resolve(&self, from: &str) -> Result<PathBuf, CantLoadFile> {
let path = match self {
Self::Rel { path } => match Path::new(from).parent() {
Some(parent) => PathBuf::from_iter([parent, Path::new(path)]),
None => PathBuf::from(path),
},
Self::Git { path, link, .. } => {
let link = preprocess_git(link);
PathBuf::from_iter([GIT_DEPS_DIR, link, path])
}
};
path.canonicalize().map_err(|source| CantLoadFile {
path,
from: PathBuf::from(from),
source,
})
}
}
#[derive(Debug)]
enum ParseImportError {
ExpectedPath,
InvalidPrefix,
}
impl std::fmt::Display for ParseImportError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::ExpectedPath => "expected path".fmt(f),
Self::InvalidPrefix => "invalid prefix, expected one of rel, \
git or none followed by colon"
.fmt(f),
}
}
}
impl std::error::Error for ParseImportError {}
impl From<ParseImportError> for io::Error {
fn from(e: ParseImportError) -> Self {
io::Error::new(io::ErrorKind::InvalidInput, e)
}
path.canonicalize().map_err(|source| CantLoadFile { path, source })
}
#[derive(Debug)]
struct CantLoadFile {
path: PathBuf,
from: PathBuf,
source: io::Error,
}
impl std::fmt::Display for CantLoadFile {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "can't load file: {} (from: {})", self.path.display(), self.from.display(),)
write!(f, "can't load file: {}", parser::display_rel_path(&self.path),)
}
}
@ -1186,37 +1151,22 @@ pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Vec<Ast>> {
}
}
#[derive(Debug)]
struct InvalidFileData(std::str::Utf8Error);
impl std::fmt::Display for InvalidFileData {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "invalid file data")
}
}
impl std::error::Error for InvalidFileData {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.0)
}
}
impl From<InvalidFileData> for io::Error {
fn from(e: InvalidFileData) -> Self {
io::Error::new(io::ErrorKind::InvalidData, e)
}
}
type Task = (u32, PathBuf, Option<std::process::Command>);
type Task = (u32, PathBuf);
let seen = Mutex::new(HashMap::<PathBuf, u32>::default());
let tasks = TaskQueue::<Task>::new(extra_threads + 1);
let ast = Mutex::new(Vec::<io::Result<Ast>>::new());
let loader = |path: &str, from: &str| {
let path = ImportPath::try_from(path)?;
if path.starts_with("rel:") {
return Err(io::Error::new(
io::ErrorKind::Other,
"`rel:` prefix was removed and is now equivalent to no prefix (remove it)"
.to_string(),
));
}
let physiscal_path = path.resolve(from)?;
let physiscal_path = resolve(path, from)?;
let id = {
let mut seen = seen.lock().unwrap();
@ -1232,63 +1182,30 @@ pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Vec<Ast>> {
}
};
let command = if !physiscal_path.exists() {
let ImportPath::Git { link, chk, .. } = path else {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!("can't find file: {}", physiscal_path.display()),
));
};
if !physiscal_path.exists() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!("can't find file: {}", parser::display_rel_path(&physiscal_path)),
));
}
let root = PathBuf::from_iter([GIT_DEPS_DIR, preprocess_git(link)]);
let mut command = std::process::Command::new("git");
command.args(["clone", "--depth", "1"]);
if let Some(chk) = chk {
command.args(match chk {
Chk::Branch(b) => ["--branch", b],
Chk::Tag(t) => ["--tag", t],
Chk::Rev(r) => ["--rev", r],
});
}
command.arg(link).arg(root);
Some(command)
} else {
None
};
tasks.push((id, physiscal_path, command));
tasks.push((id, physiscal_path));
Ok(id)
};
let execute_task = |(_, path, command): Task, buffer: &mut Vec<u8>| {
if let Some(mut command) = command {
let output = command.output()?;
if !output.status.success() {
let msg =
format!("git command failed: {}", String::from_utf8_lossy(&output.stderr));
return Err(io::Error::new(io::ErrorKind::Other, msg));
}
}
let execute_task = |(_, path): Task| {
let path = path.to_str().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("path contains invalid characters: {}", path.display()),
format!("path contains invalid characters: {}", parser::display_rel_path(&path)),
)
})?;
let mut file = std::fs::File::open(path)?;
file.read_to_end(buffer)?;
let src = std::str::from_utf8(buffer).map_err(InvalidFileData)?;
Ok(Ast::new(path, src.to_owned(), &loader))
Ok(Ast::new(path, std::fs::read_to_string(path)?, &loader))
};
let thread = || {
let mut buffer = Vec::new();
while let Some(task @ (indx, ..)) = tasks.pop() {
let res = execute_task(task, &mut buffer);
buffer.clear();
let res = execute_task(task);
let mut ast = ast.lock().unwrap();
let len = ast.len().max(indx as usize + 1);
ast.resize_with(len, || Err(io::ErrorKind::InvalidData.into()));
@ -1298,7 +1215,7 @@ pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Vec<Ast>> {
let path = Path::new(root).canonicalize()?;
seen.lock().unwrap().insert(path.clone(), 0);
tasks.push((0, path, None));
tasks.push((0, path));
if extra_threads == 0 {
thread();
@ -1467,7 +1384,7 @@ fn test_run_vm(out: &[u8], output: &mut String) {
let mut vm = unsafe {
hbvm::Vm::<_, { 1024 * 100 }>::new(
LoggedMem::default(),
hbvm::mem::Address::new(out.as_ptr() as u64),
hbvm::mem::Address::new(out.as_ptr() as u64).wrapping_add(HEADER_SIZE),
)
};
@ -1506,7 +1423,7 @@ fn test_run_vm(out: &[u8], output: &mut String) {
}
};
writeln!(output, "code size: {}", out.len()).unwrap();
writeln!(output, "code size: {}", out.len() - HEADER_SIZE).unwrap();
writeln!(output, "ret: {:?}", vm.read_reg(1).0).unwrap();
writeln!(output, "status: {:?}", stat).unwrap();
}

View file

@ -5,8 +5,10 @@ use {
},
std::{
cell::{Cell, UnsafeCell},
ffi::OsStr,
fmt, io,
ops::{Deref, Not},
path::PathBuf,
ptr::NonNull,
sync::atomic::AtomicUsize,
},
@ -95,20 +97,20 @@ impl<'a, 'b> Parser<'a, 'b> {
let f = self.collect_list(TokenKind::Semi, TokenKind::Eof, |s| s.expr_low(true));
self.pop_scope(0);
let has_undeclared = !self.idents.is_empty();
let mut errors = String::new();
for id in self.idents.drain(..) {
let (line, col) = self.lexer.line_col(ident::pos(id.ident));
eprintln!(
"{}:{}:{} => undeclared identifier: {}",
report_to(
self.lexer.source(),
self.path,
line,
col,
self.lexer.slice(ident::range(id.ident))
id.ident,
format_args!("undeclared identifier: {}", self.lexer.slice(ident::range(id.ident))),
&mut errors,
);
}
if has_undeclared {
if !errors.is_empty() {
// TODO: we need error recovery
eprintln!("{errors}");
unreachable!();
}
@ -193,7 +195,7 @@ impl<'a, 'b> Parser<'a, 'b> {
self.declare_rec(value, top_level)
}
}
_ => self.report_pos(expr.pos(), "cant declare this shit (yet)"),
_ => self.report(expr.pos(), "cant declare this shit (yet)"),
}
}
@ -201,7 +203,7 @@ impl<'a, 'b> Parser<'a, 'b> {
if let Some(index) = index_to_check
&& index != 0
{
self.report_pos(
self.report(
pos,
format_args!(
"out of order declaration not allowed: {}",
@ -212,7 +214,7 @@ impl<'a, 'b> Parser<'a, 'b> {
let index = self.idents.binary_search_by_key(&id, |s| s.ident).expect("fck up");
if std::mem::replace(&mut self.idents[index].declared, true) {
self.report_pos(
self.report(
pos,
format_args!("redeclaration of identifier: {}", self.lexer.slice(ident::range(id))),
)
@ -276,7 +278,9 @@ impl<'a, 'b> Parser<'a, 'b> {
path: self.arena.alloc_str(path),
id: match (self.loader)(path, self.path) {
Ok(id) => id,
Err(e) => self.report(format_args!("error loading dependency: {e:#}")),
Err(e) => {
self.report(str.start, format_args!("error loading dependency: {e:#}"))
}
},
}
}
@ -408,7 +412,7 @@ impl<'a, 'b> Parser<'a, 'b> {
pos,
value: match u64::from_str_radix(slice, radix as u32) {
Ok(value) => value,
Err(e) => self.report(format_args!("invalid number: {e}")),
Err(e) => self.report(token.start, format_args!("invalid number: {e}")),
} as i64,
radix,
}
@ -419,7 +423,7 @@ impl<'a, 'b> Parser<'a, 'b> {
expr
}
T::Comment => Expr::Comment { pos, literal: self.move_str(token) },
tok => self.report(format_args!("unexpected token: {tok:?}")),
tok => self.report(token.start, format_args!("unexpected token: {tok:?}")),
};
loop {
@ -497,7 +501,10 @@ impl<'a, 'b> Parser<'a, 'b> {
if matches!(self.token.kind, TokenKind::Ident | TokenKind::CtIdent) {
self.next()
} else {
self.report(format_args!("expected identifier, found {:?}", self.token.kind))
self.report(
self.token.start,
format_args!("expected identifier, found {:?}", self.token.kind),
)
}
}
@ -552,20 +559,19 @@ impl<'a, 'b> Parser<'a, 'b> {
fn expect_advance(&mut self, kind: TokenKind) -> Token {
if self.token.kind != kind {
self.report(format_args!("expected {:?}, found {:?}", kind, self.token.kind));
self.report(
self.token.start,
format_args!("expected {:?}, found {:?}", kind, self.token.kind),
);
}
self.next()
}
#[track_caller]
fn report(&self, msg: impl fmt::Display) -> ! {
self.report_pos(self.token.start, msg)
}
#[track_caller]
fn report_pos(&self, pos: Pos, msg: impl fmt::Display) -> ! {
let (line, col) = self.lexer.line_col(pos);
eprintln!("{}:{}:{} => {}", self.path, line, col, msg);
fn report(&self, pos: Pos, msg: impl fmt::Display) -> ! {
let mut str = String::new();
report_to(self.lexer.source(), self.path, pos, msg, &mut str);
eprintln!("{str}");
unreachable!();
}
@ -1231,19 +1237,34 @@ impl AstInner<[Symbol]> {
}
pub fn report_to(&self, pos: Pos, msg: impl fmt::Display, out: &mut impl fmt::Write) {
let str = &self.file;
let (line, mut col) = lexer::line_col(str.as_bytes(), pos);
_ = writeln!(out, "{}:{}:{}: {}", self.path, line, col, msg);
let line = &str[str[..pos as usize].rfind('\n').map_or(0, |i| i + 1)
..str[pos as usize..].find('\n').unwrap_or(str.len()) + pos as usize];
col += line.matches('\t').count() * 3;
_ = writeln!(out, "{}", line.replace("\t", " "));
_ = writeln!(out, "{}^", " ".repeat(col - 1));
report_to(&self.file, &self.path, pos, msg, out);
}
}
pub fn display_rel_path(path: &(impl AsRef<OsStr> + ?Sized)) -> std::path::Display {
static CWD: std::sync::LazyLock<PathBuf> =
std::sync::LazyLock::new(|| std::env::current_dir().unwrap_or_default());
std::path::Path::new(path).strip_prefix(&*CWD).unwrap_or(std::path::Path::new(path)).display()
}
pub fn report_to(
file: &str,
path: &str,
pos: Pos,
msg: impl fmt::Display,
out: &mut impl fmt::Write,
) {
let (line, mut col) = lexer::line_col(file.as_bytes(), pos);
_ = writeln!(out, "{}:{}:{}: {}", display_rel_path(path), line, col, msg);
let line = &file[file[..pos as usize].rfind('\n').map_or(0, |i| i + 1)
..file[pos as usize..].find('\n').unwrap_or(file.len()) + pos as usize];
col += line.matches('\t').count() * 3;
_ = writeln!(out, "{}", line.replace("\t", " "));
_ = writeln!(out, "{}^", " ".repeat(col - 1));
}
#[derive(PartialEq, Eq, Hash)]
pub struct Ast(NonNull<AstInner<[Symbol]>>);

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,9 @@
foo:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
@ -6,12 +12,6 @@ main:
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
foo:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 143
ret: 0
status: Ok(())

View file

@ -1,3 +1,19 @@
add_one:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
CP r32, r2
ADDI64 r1, r32, 1d
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
add_two:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
CP r32, r2
ADDI64 r1, r32, 2d
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
@ -11,22 +27,6 @@ main:
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
add_two:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
CP r32, r2
ADDI64 r1, r32, 2d
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
add_one:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
CP r32, r2
ADDI64 r1, r32, 1d
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
code size: 257
ret: 33
status: Ok(())

View file

@ -1,20 +1,3 @@
main:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
LI64 r2, 2d
LI64 r3, 2d
JAL r31, r0, :add
CP r32, r1
LI64 r2, 1d
LI64 r3, 3d
JAL r31, r0, :add
CP r33, r1
CP r34, r32
SXT32 r34, r34
SUB64 r1, r34, r33
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
add:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
@ -33,6 +16,23 @@ add:
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
LI64 r2, 2d
LI64 r3, 2d
JAL r31, r0, :add
CP r32, r1
LI64 r2, 1d
LI64 r3, 3d
JAL r31, r0, :add
CP r33, r1
CP r34, r32
SXT32 r34, r34
SUB64 r1, r34, r33
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
code size: 275
ret: 0
status: Ok(())

View file

@ -1,3 +1,33 @@
deinit:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
CP r32, r2
LD r2, r32, 0a, 8h
LD r33, r32, 16a, 8h
MULI64 r33, r33, 8d
CP r3, r33
LI64 r4, 8d
JAL r31, r0, :free
CP r1, r32
JAL r31, r0, :new
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
free:
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
CP r32, r2
CP r33, r3
CP r34, r4
LRA r35, r0, :FREE_SYS_CALL
LD r2, r35, 0a, 8h
CP r3, r32
CP r4, r33
CP r5, r34
ECA
LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -48d
ST r31, r254, 24a, 24h
@ -17,20 +47,18 @@ main:
LD r31, r254, 24a, 24h
ADDI64 r254, r254, 48d
JALA r0, r31, 0a
deinit:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
malloc:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
CP r32, r2
LD r2, r32, 0a, 8h
LD r33, r32, 16a, 8h
MULI64 r33, r33, 8d
CP r3, r33
LI64 r4, 8d
JAL r31, r0, :free
CP r1, r32
JAL r31, r0, :new
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
CP r33, r3
LRA r34, r0, :MALLOC_SYS_CALL
LD r2, r34, 0a, 8h
CP r3, r32
CP r4, r33
ECA
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
new:
ADDI64 r254, r254, -24d
@ -45,21 +73,6 @@ new:
LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
free:
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
CP r32, r2
CP r33, r3
CP r34, r4
LRA r35, r0, :FREE_SYS_CALL
LD r2, r35, 0a, 8h
CP r3, r32
CP r4, r33
CP r5, r34
ECA
LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
push:
ADDI64 r254, r254, -72d
ST r31, r254, 0a, 72h
@ -124,19 +137,6 @@ push:
4: LD r31, r254, 0a, 72h
ADDI64 r254, r254, 72d
JALA r0, r31, 0a
malloc:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
CP r32, r2
CP r33, r3
LRA r34, r0, :MALLOC_SYS_CALL
LD r2, r34, 0a, 8h
CP r3, r32
CP r4, r33
ECA
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
code size: 1201
ret: 69
status: Ok(())

View file

@ -1,11 +1,3 @@
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r2, 10d
JAL r31, r0, :fib
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
fib:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h
@ -27,6 +19,14 @@ fib:
1: LD r31, r254, 0a, 24h
ADDI64 r254, r254, 24d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r2, 10d
JAL r31, r0, :fib
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 231
ret: 55
status: Ok(())

View file

@ -1,45 +1,3 @@
main:
ADDI64 r254, r254, -64d
ST r31, r254, 48a, 16h
LI64 r32, 0d
ST r32, r254, 0a, 8h
LI64 r32, 0d
ST r32, r254, 8a, 8h
LD r2, r254, 0a, 16h
LI64 r32, 0d
ST r32, r254, 16a, 8h
LI64 r32, 0d
ST r32, r254, 24a, 8h
LD r4, r254, 16a, 16h
LI64 r32, 0d
ST r32, r254, 32a, 8h
LI64 r32, 0d
ST r32, r254, 40a, 8h
LD r6, r254, 32a, 16h
LI64 r8, 10d
JAL r31, r0, :line
LI64 r32, 0d
ST r32, r254, 0a, 8h
LI64 r32, 0d
ST r32, r254, 8a, 8h
LD r2, r254, 0a, 16h
LI64 r32, 0d
ST r32, r254, 16a, 8h
LI64 r32, 0d
ST r32, r254, 24a, 8h
LD r4, r254, 16a, 16h
LI64 r32, 0d
ST r32, r254, 32a, 8h
LI64 r32, 0d
ST r32, r254, 40a, 8h
LD r6, r254, 32a, 16h
LI64 r8, 10d
JAL r31, r0, :rect_line
JAL r31, r0, :example
LI64 r1, 0d
LD r31, r254, 48a, 16h
ADDI64 r254, r254, 64d
JALA r0, r31, 0a
example:
ADDI64 r254, r254, -48d
ST r31, r254, 0a, 48h
@ -103,6 +61,69 @@ integer:
1: LD r31, r254, 0a, 56h
ADDI64 r254, r254, 56d
JALA r0, r31, 0a
line:
ADDI64 r254, r254, -80d
ST r31, r254, 48a, 32h
ST r2, r254, 16a, 16h
ST r4, r254, 0a, 16h
ST r6, r254, 32a, 16h
CP r32, r8
LI64 r33, 1d
JEQ r33, r0, :0
LD r33, r254, 16a, 8h
LD r34, r254, 0a, 8h
JGTS r33, r34, :1
JMP :1
1: JMP :2
0: LD r34, r254, 24a, 8h
LD r33, r254, 8a, 8h
JGTS r34, r33, :2
JMP :2
2: LD r31, r254, 48a, 32h
ADDI64 r254, r254, 80d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -64d
ST r31, r254, 48a, 16h
LI64 r32, 0d
ST r32, r254, 0a, 8h
LI64 r32, 0d
ST r32, r254, 8a, 8h
LD r2, r254, 0a, 16h
LI64 r32, 0d
ST r32, r254, 16a, 8h
LI64 r32, 0d
ST r32, r254, 24a, 8h
LD r4, r254, 16a, 16h
LI64 r32, 0d
ST r32, r254, 32a, 8h
LI64 r32, 0d
ST r32, r254, 40a, 8h
LD r6, r254, 32a, 16h
LI64 r8, 10d
JAL r31, r0, :line
LI64 r32, 0d
ST r32, r254, 0a, 8h
LI64 r32, 0d
ST r32, r254, 8a, 8h
LD r2, r254, 0a, 16h
LI64 r32, 0d
ST r32, r254, 16a, 8h
LI64 r32, 0d
ST r32, r254, 24a, 8h
LD r4, r254, 16a, 16h
LI64 r32, 0d
ST r32, r254, 32a, 8h
LI64 r32, 0d
ST r32, r254, 40a, 8h
LD r6, r254, 32a, 16h
LI64 r8, 10d
JAL r31, r0, :rect_line
JAL r31, r0, :example
LI64 r1, 0d
LD r31, r254, 48a, 16h
ADDI64 r254, r254, 64d
JALA r0, r31, 0a
rect_line:
ADDI64 r254, r254, -112d
ST r31, r254, 48a, 64h
@ -135,27 +156,6 @@ rect_line:
1: LD r31, r254, 48a, 64h
ADDI64 r254, r254, 112d
JALA r0, r31, 0a
line:
ADDI64 r254, r254, -80d
ST r31, r254, 48a, 32h
ST r2, r254, 16a, 16h
ST r4, r254, 0a, 16h
ST r6, r254, 32a, 16h
CP r32, r8
LI64 r33, 1d
JEQ r33, r0, :0
LD r33, r254, 16a, 8h
LD r34, r254, 0a, 8h
JGTS r33, r34, :1
JMP :1
1: JMP :2
0: LD r34, r254, 24a, 8h
LD r33, r254, 8a, 8h
JGTS r34, r33, :2
JMP :2
2: LD r31, r254, 48a, 32h
ADDI64 r254, r254, 80d
JALA r0, r31, 0a
code size: 1400
ret: 0
status: Ok(())

View file

@ -1,13 +1,3 @@
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
LI64 r2, 0d
LI64 r3, 1000d
JAL r31, r0, :integer_range
CP r32, r1
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
integer_range:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
@ -24,6 +14,16 @@ integer_range:
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
LI64 r2, 0d
LI64 r3, 1000d
JAL r31, r0, :integer_range
CP r32, r1
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
code size: 210
ret: 42
status: Ok(())

View file

@ -1,11 +1,3 @@
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r2, 10d
JAL r31, r0, :fib
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
fib:
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
@ -25,6 +17,14 @@ fib:
LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r2, 10d
JAL r31, r0, :fib
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 218
ret: 55
status: Ok(())

View file

@ -1,3 +1,10 @@
drop:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
CP r32, r2
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -40d
ST r31, r254, 8a, 32h
@ -14,13 +21,6 @@ main:
LD r31, r254, 8a, 32h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
drop:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
CP r32, r2
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
modify:
ADDI64 r254, r254, -24d
ST r31, r254, 0a, 24h

View file

@ -1,12 +1,3 @@
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
LI64 r2, 400d
JAL r31, r0, :create_back_buffer
CP r32, r1
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
create_back_buffer:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
@ -38,6 +29,15 @@ create_back_buffer:
1: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
LI64 r2, 400d
JAL r31, r0, :create_back_buffer
CP r32, r1
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
request_page:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h

View file

@ -1,43 +1,3 @@
main:
ADDI64 r254, r254, -26d
ST r31, r254, 2a, 24h
LI64 r32, 10d
ST r32, r254, 0a, 1h
LI64 r32, 10d
ST r32, r254, 1a, 1h
CP r32, r0
LD r32, r254, 0a, 1h
CP r33, r0
LD r33, r254, 1a, 1h
CP r2, r32
JAL r31, r0, :fib
CP r32, r1
CP r2, r33
JAL r31, r0, :fib_iter
CP r33, r1
SUB64 r1, r32, r33
LD r31, r254, 2a, 24h
ADDI64 r254, r254, 26d
JALA r0, r31, 0a
fib_iter:
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
CP r32, r2
LI64 r33, 0d
LI64 r34, 1d
2: LI64 r35, 0d
JNE r32, r35, :0
JMP :1
0: CP r35, r33
ADD64 r35, r35, r34
CP r33, r34
CP r34, r35
ADDI64 r32, r32, -1d
JMP :2
1: CP r1, r33
LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
fib:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
@ -60,6 +20,46 @@ fib:
1: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
fib_iter:
ADDI64 r254, r254, -40d
ST r31, r254, 0a, 40h
CP r32, r2
LI64 r33, 0d
LI64 r34, 1d
2: LI64 r35, 0d
JNE r32, r35, :0
JMP :1
0: CP r35, r33
ADD64 r35, r35, r34
CP r33, r34
CP r34, r35
ADDI64 r32, r32, -1d
JMP :2
1: CP r1, r33
LD r31, r254, 0a, 40h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -26d
ST r31, r254, 2a, 24h
LI64 r32, 10d
ST r32, r254, 0a, 1h
LI64 r32, 10d
ST r32, r254, 1a, 1h
CP r32, r0
LD r32, r254, 0a, 1h
CP r33, r0
LD r33, r254, 1a, 1h
CP r2, r32
JAL r31, r0, :fib
CP r32, r1
CP r2, r33
JAL r31, r0, :fib_iter
CP r33, r1
SUB64 r1, r32, r33
LD r31, r254, 2a, 24h
ADDI64 r254, r254, 26d
JALA r0, r31, 0a
code size: 452
ret: 0
status: Ok(())

View file

@ -1,3 +1,16 @@
foo:
ADDI64 r254, r254, -32d
ST r31, r254, 16a, 16h
LI64 r32, 3d
ST r32, r254, 0a, 8h
LI64 r32, 2d
ST r32, r254, 8a, 4h
LI64 r32, 2d
ST r32, r254, 12a, 4h
LD r1, r254, 0a, 16h
LD r31, r254, 16a, 16h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -40d
ST r31, r254, 16a, 24h
@ -21,17 +34,6 @@ main:
LD r31, r254, 16a, 24h
ADDI64 r254, r254, 40d
JALA r0, r31, 0a
foo:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r1, 3d
ANDI r2, r2, -4294967296d
ORI r2, r2, 2d
ANDI r2, r2, 4294967295d
ORI r2, r2, 8589934592d
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 313
code size: 341
ret: 0
status: Ok(())

View file

@ -21,16 +21,6 @@ main:
1: LD r31, r254, 24a, 24h
ADDI64 r254, r254, 48d
JALA r0, r31, 0a
pass:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
CP r32, r2
LD r33, r32, 0a, 8h
LD r34, r32, 8a, 8h
SUB64 r1, r33, r34
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
odher_pass:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
@ -41,6 +31,16 @@ odher_pass:
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
pass:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
CP r32, r2
LD r33, r32, 0a, 8h
LD r34, r32, 8a, 8h
SUB64 r1, r33, r34
LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
code size: 394
ret: 3
status: Ok(())

View file

@ -0,0 +1,45 @@
main:
ADDI64 r254, r254, -48d
ST r31, r254, 16a, 32h
CP r32, r3
CP r33, r4
JAL r31, r0, :small_struct
CP r34, r1
LI64 r34, 0d
ST r34, r254, 8a, 1h
LI64 r34, 0d
ST r34, r254, 9a, 1h
LI64 r34, 0d
ST r34, r254, 10a, 1h
LI64 r34, 0d
ST r34, r254, 11a, 1h
LI64 r34, 0d
ST r34, r254, 12a, 1h
LI64 r34, 0d
ST r34, r254, 13a, 1h
LI64 r34, 0d
ST r34, r254, 14a, 1h
LI64 r34, 0d
ST r34, r254, 15a, 1h
LD r34, r254, 8a, 8h
ST r34, r254, 0a, 8h
ST r34, r254, 8a, 8h
LD r1, r254, 0a, 16h
LD r31, r254, 16a, 32h
ADDI64 r254, r254, 48d
JALA r0, r31, 0a
small_struct:
ADDI64 r254, r254, -20d
ST r31, r254, 4a, 16h
LI64 r32, 0d
ST r32, r254, 0a, 2h
LI64 r32, 0d
ST r32, r254, 2a, 2h
CP r1, r0
LD r1, r254, 0a, 4h
LD r31, r254, 4a, 16h
ADDI64 r254, r254, 20d
JALA r0, r31, 0a
code size: 440
ret: 0
status: Ok(())

View file

@ -1,3 +1,10 @@
inl:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
LRA r32, r0, :"luhahah\0"
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
@ -6,13 +13,6 @@ main:
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
inl:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h
LRA r32, r0, :"luhahah\0"
LD r31, r254, 0a, 16h
ADDI64 r254, r254, 16d
JALA r0, r31, 0a
outl:
ADDI64 r254, r254, -16d
ST r31, r254, 0a, 16h