forked from AbleOS/holey-bytes
Compare commits
106 commits
8528bef8cf
...
87cb77a553
Author | SHA1 | Date | |
---|---|---|---|
87cb77a553 | |||
276d1bb0cf | |||
5cce904135 | |||
3338d50672 | |||
2e36f32ae0 | |||
e8f1d2af8c | |||
999b25df8b | |||
61250c906a | |||
44fc9c3e2e | |||
798000c756 | |||
9de631234d | |||
843fbddf3b | |||
38a00cbaa0 | |||
4664240e08 | |||
728d563cea | |||
56984f08ff | |||
3f9f99ff65 | |||
9ed3c7ab9e | |||
acacd10ee9 | |||
f6f661cee3 | |||
4bfb5f192e | |||
ea628c1278 | |||
7448339605 | |||
da7cd5926c | |||
9cf7933251 | |||
24b9f9e78b | |||
80558ea7e6 | |||
348d9014e3 | |||
30bd6103a6 | |||
97eb985a02 | |||
7ef1adf7e2 | |||
be828b8c54 | |||
b4b3bae104 | |||
33d78fbc52 | |||
be2d38a6d2 | |||
bbd7e12af4 | |||
37db783699 | |||
948710dc27 | |||
f0a588fcff | |||
9c32f260a1 | |||
047e1ed15c | |||
2c2f0c048b | |||
3c12c0e288 | |||
ca8497550a | |||
849e842336 | |||
5c82623db9 | |||
e8a8fa3eb1 | |||
5926f69e6c | |||
83d3fb4919 | |||
b429534d23 | |||
b187af64a8 | |||
ce7bb001da | |||
9c90adbfe8 | |||
db62434736 | |||
3d721812f0 | |||
5b23a0661b | |||
7c919cd453 | |||
bb61526d3e | |||
45e1c6743a | |||
39588579a8 | |||
9095af6d84 | |||
b62413046d | |||
af4d965b8c | |||
855da58e06 | |||
2fc24f0f58 | |||
8016b1fad5 | |||
46f9903562 | |||
517850f283 | |||
faa8dd2e6f | |||
d23d010917 | |||
b1da36ecde | |||
e62aab9b4b | |||
423361a80e | |||
62a7c61cdc | |||
2bab16d3ce | |||
c88daa4800 | |||
6988d8893f | |||
64e228450f | |||
897e121eeb | |||
648bd24d0d | |||
aefa7e6405 | |||
026f6141e6 | |||
cb88edea1f | |||
127e8dcb38 | |||
9c43dafcf5 | |||
e65dbcfcbe | |||
e0d4955bd5 | |||
78ebc3292c | |||
0c2db878f0 | |||
cb9d7f7d1e | |||
41b70bec43 | |||
f013e90936 | |||
6977cb218c | |||
3f30735eaa | |||
58f4837ae0 | |||
b95bddac7b | |||
7d53706e71 | |||
4d699fcbf1 | |||
5aa6150c70 | |||
b0a85f44c9 | |||
2aa5ba9abc | |||
35d34dca54 | |||
bc817c4ea2 | |||
0298b32e38 | |||
73c9ccef6a | |||
ad4aed9c98 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,4 +9,5 @@ db.sqlite-journal
|
||||||
# assets
|
# assets
|
||||||
/depell/src/*.gz
|
/depell/src/*.gz
|
||||||
/depell/src/*.wasm
|
/depell/src/*.wasm
|
||||||
|
**/*-sv.rs
|
||||||
/bytecode/src/instrs.rs
|
/bytecode/src/instrs.rs
|
||||||
|
|
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -594,6 +594,9 @@ name = "hashbrown"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
|
||||||
|
dependencies = [
|
||||||
|
"allocator-api2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashlink"
|
name = "hashlink"
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -24,7 +24,7 @@ hbjit = { path = "jit" }
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
#debug = true
|
#debug = true
|
||||||
#strip = true
|
strip = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ panic = "abort"
|
||||||
rustflags = ["-Zfmt-debug=none", "-Zlocation-detail=none"]
|
rustflags = ["-Zfmt-debug=none", "-Zlocation-detail=none"]
|
||||||
inherits = "release"
|
inherits = "release"
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
strip = true
|
strip = "debuginfo"
|
||||||
lto = true
|
lto = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
@ -42,3 +42,9 @@ inherits = "dev"
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
strip = "debuginfo"
|
strip = "debuginfo"
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.fuzz]
|
||||||
|
inherits = "dev"
|
||||||
|
debug = true
|
||||||
|
opt-level = 3
|
||||||
|
panic = "abort"
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_instrs(generated: &mut String) -> Result<(), Box<dyn std::error::Error>> {
|
fn gen_instrs(generated: &mut String) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
writeln!(generated, "#![allow(dead_code)] #![allow(clippy::upper_case_acronyms)]")?;
|
writeln!(generated, "#![expect(dead_code)]")?;
|
||||||
writeln!(generated, "use crate::*;")?;
|
writeln!(generated, "use crate::*;")?;
|
||||||
|
|
||||||
'_opcode_structs: {
|
'_opcode_structs: {
|
||||||
|
|
|
@ -89,7 +89,6 @@ pub enum DisasmError<'a> {
|
||||||
InstructionOutOfBounds(&'a str),
|
InstructionOutOfBounds(&'a str),
|
||||||
FmtFailed(core::fmt::Error),
|
FmtFailed(core::fmt::Error),
|
||||||
HasOutOfBoundsJumps,
|
HasOutOfBoundsJumps,
|
||||||
HasDirectInstructionCycles,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "disasm")]
|
#[cfg(feature = "disasm")]
|
||||||
|
@ -113,9 +112,6 @@ impl core::fmt::Display for DisasmError<'_> {
|
||||||
"the code contained jumps that dont got neither to a \
|
"the code contained jumps that dont got neither to a \
|
||||||
valid symbol or local insturction"
|
valid symbol or local insturction"
|
||||||
),
|
),
|
||||||
DisasmError::HasDirectInstructionCycles => {
|
|
||||||
writeln!(f, "found instruction that jumps to itself")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +141,6 @@ pub fn disasm<'a>(
|
||||||
|
|
||||||
let mut labels = BTreeMap::<u32, u32>::default();
|
let mut labels = BTreeMap::<u32, u32>::default();
|
||||||
let mut buf = Vec::<instrs::Oper>::new();
|
let mut buf = Vec::<instrs::Oper>::new();
|
||||||
let mut has_cycle = false;
|
|
||||||
let mut has_oob = false;
|
let mut has_oob = false;
|
||||||
|
|
||||||
'_offset_pass: for (&off, &(name, len, kind)) in functions.iter() {
|
'_offset_pass: for (&off, &(name, len, kind)) in functions.iter() {
|
||||||
|
@ -174,8 +169,6 @@ pub fn disasm<'a>(
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
has_cycle |= rel == 0;
|
|
||||||
|
|
||||||
let global_offset: u32 = (offset + rel).try_into().unwrap();
|
let global_offset: u32 = (offset + rel).try_into().unwrap();
|
||||||
if functions.get(&global_offset).is_some() {
|
if functions.get(&global_offset).is_some() {
|
||||||
continue;
|
continue;
|
||||||
|
@ -287,9 +280,5 @@ pub fn disasm<'a>(
|
||||||
return Err(DisasmError::HasOutOfBoundsJumps);
|
return Err(DisasmError::HasOutOfBoundsJumps);
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_cycle {
|
|
||||||
return Err(DisasmError::HasDirectInstructionCycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -665,7 +665,6 @@ mod db {
|
||||||
($vis:vis struct $name:ident {
|
($vis:vis struct $name:ident {
|
||||||
$($qname:ident: $code:expr,)*
|
$($qname:ident: $code:expr,)*
|
||||||
}) => {
|
}) => {
|
||||||
#[allow(dead_code)]
|
|
||||||
$vis struct $name<'a> {
|
$vis struct $name<'a> {
|
||||||
$($vis $qname: rusqlite::Statement<'a>,)*
|
$($vis $qname: rusqlite::Statement<'a>,)*
|
||||||
}
|
}
|
||||||
|
@ -694,7 +693,7 @@ mod db {
|
||||||
fetch_deps: "
|
fetch_deps: "
|
||||||
WITH RECURSIVE roots(name, author, code) AS (
|
WITH RECURSIVE roots(name, author, code) AS (
|
||||||
SELECT name, author, code FROM post WHERE name = ? AND author = ?
|
SELECT name, author, code FROM post WHERE name = ? AND author = ?
|
||||||
UNION ALL
|
UNION
|
||||||
SELECT post.name, post.author, post.code FROM
|
SELECT post.name, post.author, post.code FROM
|
||||||
post JOIN import ON post.name = import.to_name
|
post JOIN import ON post.name = import.to_name
|
||||||
AND post.author = import.to_author
|
AND post.author = import.to_author
|
||||||
|
|
|
@ -19,7 +19,7 @@ unsafe extern "C" fn fmt() {
|
||||||
let code = core::str::from_raw_parts(core::ptr::addr_of!(INPUT).cast(), INPUT_LEN);
|
let code = core::str::from_raw_parts(core::ptr::addr_of!(INPUT).cast(), INPUT_LEN);
|
||||||
|
|
||||||
let arena = parser::Arena::with_capacity(code.len() * parser::SOURCE_TO_AST_FACTOR);
|
let arena = parser::Arena::with_capacity(code.len() * parser::SOURCE_TO_AST_FACTOR);
|
||||||
let mut ctx = parser::ParserCtx::default();
|
let mut ctx = parser::Ctx::default();
|
||||||
let exprs = parser::Parser::parse(&mut ctx, code, "source.hb", &mut parser::no_loader, &arena);
|
let exprs = parser::Parser::parse(&mut ctx, code, "source.hb", &mut parser::no_loader, &arena);
|
||||||
|
|
||||||
let mut f = wasm_rt::Write(&mut OUTPUT[..]);
|
let mut f = wasm_rt::Write(&mut OUTPUT[..]);
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
use {
|
use {
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::{string::String, vec::Vec},
|
||||||
hblang::{codegen::Codegen, parser::FileId},
|
hblang::{
|
||||||
|
parser::FileId,
|
||||||
|
son::{hbvm::HbvmBackend, Codegen, CodegenCtx},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
@ -52,8 +55,9 @@ unsafe fn compile_and_run(mut fuel: usize) {
|
||||||
files
|
files
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut ctx = CodegenCtx::default();
|
||||||
|
|
||||||
let files = {
|
let files = {
|
||||||
let mut ctx = hblang::parser::ParserCtx::default();
|
|
||||||
let paths = files.iter().map(|f| f.path).collect::<Vec<_>>();
|
let paths = files.iter().map(|f| f.path).collect::<Vec<_>>();
|
||||||
let mut loader = |path: &str, _: &str, kind| match kind {
|
let mut loader = |path: &str, _: &str, kind| match kind {
|
||||||
hblang::parser::FileKind::Module => Ok(paths.binary_search(&path).unwrap() as FileId),
|
hblang::parser::FileKind::Module => Ok(paths.binary_search(&path).unwrap() as FileId),
|
||||||
|
@ -66,7 +70,7 @@ unsafe fn compile_and_run(mut fuel: usize) {
|
||||||
f.path,
|
f.path,
|
||||||
// since 'free' does nothing this is fine
|
// since 'free' does nothing this is fine
|
||||||
String::from_raw_parts(f.code.as_mut_ptr(), f.code.len(), f.code.len()),
|
String::from_raw_parts(f.code.as_mut_ptr(), f.code.len(), f.code.len()),
|
||||||
&mut ctx,
|
&mut ctx.parser,
|
||||||
&mut loader,
|
&mut loader,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -74,9 +78,15 @@ unsafe fn compile_and_run(mut fuel: usize) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ct = {
|
let mut ct = {
|
||||||
let mut c = Codegen::default();
|
let mut backend = HbvmBackend::default();
|
||||||
c.files = files;
|
Codegen::new(&mut backend, &files, &mut ctx).generate(root as FileId);
|
||||||
c.generate(root as FileId);
|
|
||||||
|
if !ctx.parser.errors.borrow().is_empty() {
|
||||||
|
log::error!("{}", ctx.parser.errors.borrow());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut c = Codegen::new(&mut backend, &files, &mut ctx);
|
||||||
c.assemble_comptime()
|
c.assemble_comptime()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ pub struct ArenaAllocator<const SIZE: usize> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const SIZE: usize> ArenaAllocator<SIZE> {
|
impl<const SIZE: usize> ArenaAllocator<SIZE> {
|
||||||
#[allow(clippy::new_without_default)]
|
#[expect(clippy::new_without_default)]
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
ArenaAllocator {
|
ArenaAllocator {
|
||||||
arena: UnsafeCell::new([0; SIZE]),
|
arena: UnsafeCell::new([0; SIZE]),
|
||||||
|
@ -112,7 +112,7 @@ impl<const SIZE: usize> ArenaAllocator<SIZE> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::missing_safety_doc)]
|
#[expect(clippy::missing_safety_doc)]
|
||||||
pub unsafe fn reset(&self) {
|
pub unsafe fn reset(&self) {
|
||||||
(*self.head.get()) = self.arena.get().cast::<u8>().add(SIZE);
|
(*self.head.get()) = self.arena.get().cast::<u8>().add(SIZE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,12 @@ edition = "2021"
|
||||||
name = "hbc"
|
name = "hbc"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "fuzz"
|
||||||
|
path = "src/fuzz_main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hashbrown = { version = "0.15.0", default-features = false, features = ["raw-entry"] }
|
hashbrown = { version = "0.15.0", default-features = false, features = ["raw-entry", "allocator-api2"] }
|
||||||
hbbytecode = { workspace = true, features = ["disasm"] }
|
hbbytecode = { workspace = true, features = ["disasm"] }
|
||||||
hbvm = { workspace = true, features = ["nightly"] }
|
hbvm = { workspace = true, features = ["nightly"] }
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
|
@ -16,11 +20,9 @@ log = "0.4.22"
|
||||||
[dependencies.regalloc2]
|
[dependencies.regalloc2]
|
||||||
git = "https://github.com/jakubDoka/regalloc2"
|
git = "https://github.com/jakubDoka/regalloc2"
|
||||||
branch = "reuse-allocations"
|
branch = "reuse-allocations"
|
||||||
optional = true
|
default-features = false
|
||||||
features = ["trace-log"]
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "opts"]
|
default = ["std", "regalloc2/trace-log"]
|
||||||
std = []
|
std = []
|
||||||
opts = ["regalloc2"]
|
|
||||||
no_log = ["log/max_level_off"]
|
no_log = ["log/max_level_off"]
|
||||||
|
|
748
lang/README.md
748
lang/README.md
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
--fmt - format all source files
|
--fmt - format all imported source files
|
||||||
--fmt-stdout - dont write the formatted file but print it
|
--fmt-stdout - dont write the formatted file but print it
|
||||||
--dump-asm - output assembly instead of raw code, (the assembly is more for debugging the compiler)
|
--dump-asm - output assembly instead of raw code, (the assembly is more for debugging the compiler)
|
||||||
--threads <1...> - number of threads compiler can use [default: 1]
|
--threads <1...> - number of extra threads compiler can use [default: 0]
|
||||||
|
|
2733
lang/src/codegen.rs
2733
lang/src/codegen.rs
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,9 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
ident,
|
|
||||||
lexer::{self, Lexer, TokenKind},
|
lexer::{self, Lexer, TokenKind},
|
||||||
parser::{self, CommentOr, CtorField, Expr, Poser, Radix, StructField},
|
parser::{self, CommentOr, CtorField, Expr, Poser, Radix, StructField},
|
||||||
},
|
},
|
||||||
core::fmt,
|
core::fmt::{self},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn display_radix(radix: Radix, mut value: u64, buf: &mut [u8; 64]) -> &str {
|
pub fn display_radix(radix: Radix, mut value: u64, buf: &mut [u8; 64]) -> &str {
|
||||||
|
@ -256,7 +255,7 @@ impl<'a> Formatter<'a> {
|
||||||
fields,
|
fields,
|
||||||
|s: &mut Self, CtorField { name, value, .. }: &_, f| {
|
|s: &mut Self, CtorField { name, value, .. }: &_, f| {
|
||||||
f.write_str(name)?;
|
f.write_str(name)?;
|
||||||
if !matches!(value, &Expr::Ident { id, .. } if *name == &self.source[ident::range(id)]) {
|
if !matches!(value, &Expr::Ident { id, .. } if *name == &self.source[id.range()]) {
|
||||||
f.write_str(": ")?;
|
f.write_str(": ")?;
|
||||||
s.fmt(value, f)?;
|
s.fmt(value, f)?;
|
||||||
}
|
}
|
||||||
|
@ -264,6 +263,20 @@ impl<'a> Formatter<'a> {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Expr::Tupl {
|
||||||
|
pos,
|
||||||
|
ty: Some(&Expr::Slice { pos: spos, size: Some(&Expr::Number { value, .. }), item }),
|
||||||
|
fields,
|
||||||
|
trailing_comma,
|
||||||
|
} if value as usize == fields.len() => self.fmt(
|
||||||
|
&Expr::Tupl {
|
||||||
|
pos,
|
||||||
|
ty: Some(&Expr::Slice { pos: spos, size: None, item }),
|
||||||
|
fields,
|
||||||
|
trailing_comma,
|
||||||
|
},
|
||||||
|
f,
|
||||||
|
),
|
||||||
Expr::Tupl { ty, fields, trailing_comma, .. } => {
|
Expr::Tupl { ty, fields, trailing_comma, .. } => {
|
||||||
if let Some(ty) = ty {
|
if let Some(ty) = ty {
|
||||||
self.fmt_paren(ty, f, unary)?;
|
self.fmt_paren(ty, f, unary)?;
|
||||||
|
@ -333,6 +346,7 @@ impl<'a> Formatter<'a> {
|
||||||
self.fmt(val, f)
|
self.fmt(val, f)
|
||||||
}
|
}
|
||||||
Expr::Return { val: None, .. } => f.write_str("return"),
|
Expr::Return { val: None, .. } => f.write_str("return"),
|
||||||
|
Expr::Wildcard { .. } => f.write_str("_"),
|
||||||
Expr::Ident { pos, is_ct, .. } => {
|
Expr::Ident { pos, is_ct, .. } => {
|
||||||
if is_ct {
|
if is_ct {
|
||||||
f.write_str("$")?;
|
f.write_str("$")?;
|
||||||
|
@ -353,12 +367,18 @@ impl<'a> Formatter<'a> {
|
||||||
let mut buf = [0u8; 64];
|
let mut buf = [0u8; 64];
|
||||||
f.write_str(display_radix(radix, value as u64, &mut buf))
|
f.write_str(display_radix(radix, value as u64, &mut buf))
|
||||||
}
|
}
|
||||||
|
Expr::Float { pos, .. } => {
|
||||||
|
f.write_str(&self.source[Lexer::restore(self.source, pos).eat().range()])
|
||||||
|
}
|
||||||
Expr::Bool { value, .. } => f.write_str(if value { "true" } else { "false" }),
|
Expr::Bool { value, .. } => f.write_str(if value { "true" } else { "false" }),
|
||||||
Expr::Idk { .. } => f.write_str("idk"),
|
Expr::Idk { .. } => f.write_str("idk"),
|
||||||
|
Expr::Die { .. } => f.write_str("die"),
|
||||||
|
Expr::Null { .. } => f.write_str("null"),
|
||||||
Expr::BinOp {
|
Expr::BinOp {
|
||||||
left,
|
left,
|
||||||
op: TokenKind::Assign,
|
op: TokenKind::Assign,
|
||||||
right: &Expr::BinOp { left: lleft, op, right },
|
right: &Expr::BinOp { left: lleft, op, right, .. },
|
||||||
|
..
|
||||||
} if left.pos() == lleft.pos() => {
|
} if left.pos() == lleft.pos() => {
|
||||||
self.fmt(left, f)?;
|
self.fmt(left, f)?;
|
||||||
f.write_str(" ")?;
|
f.write_str(" ")?;
|
||||||
|
@ -366,7 +386,7 @@ impl<'a> Formatter<'a> {
|
||||||
f.write_str("= ")?;
|
f.write_str("= ")?;
|
||||||
self.fmt(right, f)
|
self.fmt(right, f)
|
||||||
}
|
}
|
||||||
Expr::BinOp { right, op, left } => {
|
Expr::BinOp { right, op, left, .. } => {
|
||||||
let prec_miss_left = |e: &Expr| {
|
let prec_miss_left = |e: &Expr| {
|
||||||
matches!(
|
matches!(
|
||||||
e, Expr::BinOp { op: lop, .. } if op.precedence() > lop.precedence()
|
e, Expr::BinOp { op: lop, .. } if op.precedence() > lop.precedence()
|
||||||
|
@ -450,7 +470,7 @@ pub fn fmt_file(exprs: &[Expr], file: &str, f: &mut impl fmt::Write) -> fmt::Res
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test {
|
pub mod test {
|
||||||
use {
|
use {
|
||||||
crate::parser::{self, ParserCtx},
|
crate::parser::{self, Ctx},
|
||||||
alloc::borrow::ToOwned,
|
alloc::borrow::ToOwned,
|
||||||
std::{fmt::Write, string::String},
|
std::{fmt::Write, string::String},
|
||||||
};
|
};
|
||||||
|
@ -460,8 +480,8 @@ pub mod test {
|
||||||
let len = crate::fmt::minify(&mut minned);
|
let len = crate::fmt::minify(&mut minned);
|
||||||
minned.truncate(len);
|
minned.truncate(len);
|
||||||
|
|
||||||
let ast =
|
let mut ctx = Ctx::default();
|
||||||
parser::Ast::new(ident, minned, &mut ParserCtx::default(), &mut parser::no_loader);
|
let ast = parser::Ast::new(ident, minned, &mut ctx, &mut parser::no_loader);
|
||||||
//log::error!(
|
//log::error!(
|
||||||
// "{} / {} = {} | {} / {} = {}",
|
// "{} / {} = {} | {} / {} = {}",
|
||||||
// ast.mem.size(),
|
// ast.mem.size(),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
codegen,
|
parser::{self, Ast, Ctx, FileKind},
|
||||||
parser::{self, Ast, FileKind, ParserCtx},
|
son::{self, hbvm::HbvmBackend},
|
||||||
},
|
},
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::{string::String, vec::Vec},
|
||||||
core::{fmt::Write, num::NonZeroUsize},
|
core::{fmt::Write, num::NonZeroUsize, ops::Deref},
|
||||||
hashbrown::hash_map,
|
hashbrown::hash_map,
|
||||||
std::{
|
std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
|
@ -74,7 +74,9 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
|
||||||
fn format_ast(ast: parser::Ast) -> std::io::Result<()> {
|
fn format_ast(ast: parser::Ast) -> std::io::Result<()> {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
write!(output, "{ast}").unwrap();
|
write!(output, "{ast}").unwrap();
|
||||||
std::fs::write(&*ast.path, output)?;
|
if ast.file.deref().trim() != output.as_str().trim() {
|
||||||
|
std::fs::write(&*ast.path, output)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,17 +88,25 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
|
||||||
let ast = parsed.ast.into_iter().next().unwrap();
|
let ast = parsed.ast.into_iter().next().unwrap();
|
||||||
write!(out, "{ast}").unwrap();
|
write!(out, "{ast}").unwrap();
|
||||||
} else {
|
} else {
|
||||||
let mut codegen = codegen::Codegen::default();
|
let mut backend = HbvmBackend::default();
|
||||||
codegen.files = parsed.ast;
|
let mut ctx = crate::son::CodegenCtx::default();
|
||||||
codegen.push_embeds(parsed.embeds);
|
*ctx.parser.errors.get_mut() = parsed.errors;
|
||||||
|
let mut codegen = son::Codegen::new(&mut backend, &parsed.ast, &mut ctx);
|
||||||
|
|
||||||
|
codegen.push_embeds(parsed.embeds);
|
||||||
codegen.generate(0);
|
codegen.generate(0);
|
||||||
|
|
||||||
|
if !codegen.errors.borrow().is_empty() {
|
||||||
|
log::error!("{}", codegen.errors.borrow());
|
||||||
|
return Err(std::io::Error::other("compilation faoled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
codegen.assemble(out);
|
||||||
|
|
||||||
if options.dump_asm {
|
if options.dump_asm {
|
||||||
codegen
|
let mut disasm = String::new();
|
||||||
.disasm(unsafe { std::mem::transmute::<&mut Vec<u8>, &mut String>(out) })
|
codegen.disasm(&mut disasm, out).map_err(|e| io::Error::other(e.to_string()))?;
|
||||||
.map_err(|e| io::Error::other(e.to_string()))?;
|
*out = disasm.into_bytes();
|
||||||
} else {
|
|
||||||
codegen.assemble(out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +201,7 @@ impl<T> TaskQueueInner<T> {
|
||||||
pub struct Loaded {
|
pub struct Loaded {
|
||||||
ast: Vec<Ast>,
|
ast: Vec<Ast>,
|
||||||
embeds: Vec<Vec<u8>>,
|
embeds: Vec<Vec<u8>>,
|
||||||
|
errors: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Loaded> {
|
pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Loaded> {
|
||||||
|
@ -312,7 +323,7 @@ pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Loaded> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let thread = || {
|
let thread = || {
|
||||||
let mut ctx = ParserCtx::default();
|
let mut ctx = Ctx::default();
|
||||||
let mut tmp = PathBuf::new();
|
let mut tmp = PathBuf::new();
|
||||||
while let Some(task @ (indx, ..)) = tasks.pop() {
|
while let Some(task @ (indx, ..)) = tasks.pop() {
|
||||||
let res = execute_task(&mut ctx, task, &mut tmp);
|
let res = execute_task(&mut ctx, task, &mut tmp);
|
||||||
|
@ -321,6 +332,7 @@ pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Loaded> {
|
||||||
ast.resize_with(len, || Err(io::ErrorKind::InvalidData.into()));
|
ast.resize_with(len, || Err(io::ErrorKind::InvalidData.into()));
|
||||||
ast[indx as usize] = res;
|
ast[indx as usize] = res;
|
||||||
}
|
}
|
||||||
|
ctx.errors.into_inner()
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = Path::new(root).canonicalize().map_err(|e| {
|
let path = Path::new(root).canonicalize().map_err(|e| {
|
||||||
|
@ -329,15 +341,23 @@ pub fn parse_from_fs(extra_threads: usize, root: &str) -> io::Result<Loaded> {
|
||||||
seen_modules.lock().unwrap().insert(path.clone(), 0);
|
seen_modules.lock().unwrap().insert(path.clone(), 0);
|
||||||
tasks.push((0, path));
|
tasks.push((0, path));
|
||||||
|
|
||||||
if extra_threads == 0 {
|
let errors = if extra_threads == 0 {
|
||||||
thread();
|
thread()
|
||||||
} else {
|
} else {
|
||||||
std::thread::scope(|s| (0..extra_threads + 1).for_each(|_| _ = s.spawn(thread)));
|
std::thread::scope(|s| {
|
||||||
}
|
(0..extra_threads + 1)
|
||||||
|
.map(|_| s.spawn(thread))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter()
|
||||||
|
.map(|t| t.join().unwrap())
|
||||||
|
.collect::<String>()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Loaded {
|
Ok(Loaded {
|
||||||
ast: ast.into_inner().unwrap().into_iter().collect::<io::Result<Vec<_>>>()?,
|
ast: ast.into_inner().unwrap().into_iter().collect::<io::Result<Vec<_>>>()?,
|
||||||
embeds: embeds.into_inner().unwrap(),
|
embeds: embeds.into_inner().unwrap(),
|
||||||
|
errors,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
140
lang/src/fuzz.rs
Normal file
140
lang/src/fuzz.rs
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
lexer::TokenKind,
|
||||||
|
parser,
|
||||||
|
son::{hbvm::HbvmBackend, Codegen, CodegenCtx},
|
||||||
|
},
|
||||||
|
alloc::string::String,
|
||||||
|
core::{fmt::Write, hash::BuildHasher, ops::Range},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Rand(pub u64);
|
||||||
|
|
||||||
|
impl Rand {
|
||||||
|
pub fn next(&mut self) -> u64 {
|
||||||
|
self.0 = crate::FnvBuildHasher::default().hash_one(self.0);
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn range(&mut self, min: u64, max: u64) -> u64 {
|
||||||
|
self.next() % (max - min) + min
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bool(&mut self) -> bool {
|
||||||
|
self.next() % 2 == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct FuncGen {
|
||||||
|
rand: Rand,
|
||||||
|
buf: String,
|
||||||
|
vars: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FuncGen {
|
||||||
|
fn gen(&mut self, seed: u64) -> &str {
|
||||||
|
self.rand = Rand(seed);
|
||||||
|
self.buf.clear();
|
||||||
|
self.buf.push_str("main := fn(): void ");
|
||||||
|
self.block().unwrap();
|
||||||
|
&self.buf
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block(&mut self) -> core::fmt::Result {
|
||||||
|
let prev_vars = self.vars;
|
||||||
|
self.buf.push('{');
|
||||||
|
for _ in 0..self.rand.range(1, 10) {
|
||||||
|
self.stmt()?;
|
||||||
|
}
|
||||||
|
self.buf.push('}');
|
||||||
|
self.vars = prev_vars;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stmt(&mut self) -> core::fmt::Result {
|
||||||
|
match self.rand.range(0, 100) {
|
||||||
|
0..4 => _ = self.block(),
|
||||||
|
4..10 => {
|
||||||
|
write!(self.buf, "var{} := ", self.vars)?;
|
||||||
|
self.expr()?;
|
||||||
|
self.vars += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
10..20 if self.vars != 0 => {
|
||||||
|
write!(self.buf, "var{} = ", self.rand.range(0, self.vars))?;
|
||||||
|
self.expr()?;
|
||||||
|
}
|
||||||
|
20..23 => {
|
||||||
|
self.buf.push_str("if ");
|
||||||
|
self.expr()?;
|
||||||
|
self.block()?;
|
||||||
|
if self.rand.bool() {
|
||||||
|
self.buf.push_str(" else ");
|
||||||
|
self.block()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.buf.push_str("return ");
|
||||||
|
self.expr()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.buf.push(';');
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr(&mut self) -> core::fmt::Result {
|
||||||
|
match self.rand.range(0, 100) {
|
||||||
|
0..80 => {
|
||||||
|
write!(self.buf, "{}", self.rand.next())
|
||||||
|
}
|
||||||
|
80..90 if self.vars != 0 => {
|
||||||
|
write!(self.buf, "var{}", self.rand.range(0, self.vars))
|
||||||
|
}
|
||||||
|
80..100 => {
|
||||||
|
self.expr()?;
|
||||||
|
let ops = [
|
||||||
|
TokenKind::Add,
|
||||||
|
TokenKind::Sub,
|
||||||
|
TokenKind::Mul,
|
||||||
|
TokenKind::Div,
|
||||||
|
TokenKind::Shl,
|
||||||
|
TokenKind::Eq,
|
||||||
|
TokenKind::Ne,
|
||||||
|
TokenKind::Lt,
|
||||||
|
TokenKind::Gt,
|
||||||
|
TokenKind::Le,
|
||||||
|
TokenKind::Ge,
|
||||||
|
TokenKind::Band,
|
||||||
|
TokenKind::Bor,
|
||||||
|
TokenKind::Xor,
|
||||||
|
TokenKind::Mod,
|
||||||
|
TokenKind::Shr,
|
||||||
|
];
|
||||||
|
let op = ops[self.rand.range(0, ops.len() as u64) as usize];
|
||||||
|
write!(self.buf, " {op} ")?;
|
||||||
|
self.expr()
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fuzz(seed_range: Range<u64>) {
|
||||||
|
let mut gen = FuncGen::default();
|
||||||
|
let mut ctx = CodegenCtx::default();
|
||||||
|
for i in seed_range {
|
||||||
|
ctx.clear();
|
||||||
|
let src = gen.gen(i);
|
||||||
|
let parsed = parser::Ast::new("fuzz", src, &mut ctx.parser, &mut parser::no_loader);
|
||||||
|
|
||||||
|
assert!(ctx.parser.errors.get_mut().is_empty());
|
||||||
|
|
||||||
|
let mut backend = HbvmBackend::default();
|
||||||
|
let mut cdg = Codegen::new(&mut backend, core::slice::from_ref(&parsed), &mut ctx);
|
||||||
|
cdg.generate(0);
|
||||||
|
}
|
||||||
|
}
|
3
lang/src/fuzz_main.rs
Normal file
3
lang/src/fuzz_main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
hblang::fuzz::fuzz(0..1000000);
|
||||||
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::EncodedInstr;
|
|
||||||
|
|
||||||
const fn ascii_mask(chars: &[u8]) -> u128 {
|
const fn ascii_mask(chars: &[u8]) -> u128 {
|
||||||
let mut eq = 0;
|
let mut eq = 0;
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
@ -51,6 +49,8 @@ macro_rules! gen_token_kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $name {
|
impl $name {
|
||||||
|
pub const OPS: &[Self] = &[$($(Self::$op),*),*];
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
let sf = unsafe { &*(self as *const _ as *const u8) } ;
|
let sf = unsafe { &*(self as *const _ as *const u8) } ;
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -116,6 +116,7 @@ pub enum TokenKind {
|
||||||
|
|
||||||
Ident,
|
Ident,
|
||||||
Number,
|
Number,
|
||||||
|
Float,
|
||||||
Eof,
|
Eof,
|
||||||
|
|
||||||
Ct,
|
Ct,
|
||||||
|
@ -131,7 +132,9 @@ pub enum TokenKind {
|
||||||
Packed,
|
Packed,
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
|
Null,
|
||||||
Idk,
|
Idk,
|
||||||
|
Die,
|
||||||
|
|
||||||
Ctor,
|
Ctor,
|
||||||
Tupl,
|
Tupl,
|
||||||
|
@ -145,6 +148,7 @@ pub enum TokenKind {
|
||||||
RBrack = b']',
|
RBrack = b']',
|
||||||
Xor = b'^',
|
Xor = b'^',
|
||||||
Tick = b'`',
|
Tick = b'`',
|
||||||
|
Under = b'_',
|
||||||
// Unused = a-z
|
// Unused = a-z
|
||||||
LBrace = b'{',
|
LBrace = b'{',
|
||||||
Bor = b'|',
|
Bor = b'|',
|
||||||
|
@ -176,87 +180,6 @@ impl core::fmt::Debug for TokenKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenKind {
|
impl TokenKind {
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
pub fn cond_op(self, signed: bool) -> Option<(fn(u8, u8, i16) -> EncodedInstr, bool)> {
|
|
||||||
use crate::instrs;
|
|
||||||
Some((
|
|
||||||
match self {
|
|
||||||
Self::Le if signed => instrs::jgts,
|
|
||||||
Self::Le => instrs::jgtu,
|
|
||||||
Self::Lt if signed => instrs::jlts,
|
|
||||||
Self::Lt => instrs::jltu,
|
|
||||||
Self::Ge if signed => instrs::jlts,
|
|
||||||
Self::Ge => instrs::jltu,
|
|
||||||
Self::Gt if signed => instrs::jgts,
|
|
||||||
Self::Gt => instrs::jgtu,
|
|
||||||
Self::Eq => instrs::jne,
|
|
||||||
Self::Ne => instrs::jeq,
|
|
||||||
_ => return None,
|
|
||||||
},
|
|
||||||
matches!(self, Self::Lt | TokenKind::Gt),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn binop(self, signed: bool, size: u32) -> Option<fn(u8, u8, u8) -> EncodedInstr> {
|
|
||||||
use crate::instrs::*;
|
|
||||||
|
|
||||||
macro_rules! div { ($($op:ident),*) => {[$(|a, b, c| $op(a, 0, b, c)),*]}; }
|
|
||||||
macro_rules! rem { ($($op:ident),*) => {[$(|a, b, c| $op(0, a, b, c)),*]}; }
|
|
||||||
|
|
||||||
let ops = match self {
|
|
||||||
Self::Add => [add8, add16, add32, add64],
|
|
||||||
Self::Sub => [sub8, sub16, sub32, sub64],
|
|
||||||
Self::Mul => [mul8, mul16, mul32, mul64],
|
|
||||||
Self::Div if signed => div!(dirs8, dirs16, dirs32, dirs64),
|
|
||||||
Self::Div => div!(diru8, diru16, diru32, diru64),
|
|
||||||
Self::Mod if signed => rem!(dirs8, dirs16, dirs32, dirs64),
|
|
||||||
Self::Mod => rem!(diru8, diru16, diru32, diru64),
|
|
||||||
Self::Band => return Some(and),
|
|
||||||
Self::Bor => return Some(or),
|
|
||||||
Self::Xor => return Some(xor),
|
|
||||||
Self::Shl => [slu8, slu16, slu32, slu64],
|
|
||||||
Self::Shr if signed => [srs8, srs16, srs32, srs64],
|
|
||||||
Self::Shr => [sru8, sru16, sru32, sru64],
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(ops[size.ilog2() as usize])
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
|
||||||
pub fn imm_binop(self, signed: bool, size: u32) -> Option<fn(u8, u8, u64) -> EncodedInstr> {
|
|
||||||
use crate::instrs::*;
|
|
||||||
macro_rules! def_op {
|
|
||||||
($name:ident |$a:ident, $b:ident, $c:ident| $($tt:tt)*) => {
|
|
||||||
macro_rules! $name {
|
|
||||||
($$($$op:ident),*) => {
|
|
||||||
[$$(
|
|
||||||
|$a, $b, $c: u64| $$op($($tt)*),
|
|
||||||
)*]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
def_op!(basic_op | a, b, c | a, b, c as _);
|
|
||||||
def_op!(sub_op | a, b, c | a, b, c.wrapping_neg() as _);
|
|
||||||
|
|
||||||
let ops = match self {
|
|
||||||
Self::Add => basic_op!(addi8, addi16, addi32, addi64),
|
|
||||||
Self::Sub => sub_op!(addi8, addi16, addi32, addi64),
|
|
||||||
Self::Mul => basic_op!(muli8, muli16, muli32, muli64),
|
|
||||||
Self::Band => return Some(andi),
|
|
||||||
Self::Bor => return Some(ori),
|
|
||||||
Self::Xor => return Some(xori),
|
|
||||||
Self::Shr if signed => basic_op!(srui8, srui16, srui32, srui64),
|
|
||||||
Self::Shr => basic_op!(srui8, srui16, srui32, srui64),
|
|
||||||
Self::Shl => basic_op!(slui8, slui16, slui32, slui64),
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(ops[size.ilog2() as usize])
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ass_op(self) -> Option<Self> {
|
pub fn ass_op(self) -> Option<Self> {
|
||||||
let id = (self as u8).saturating_sub(128);
|
let id = (self as u8).saturating_sub(128);
|
||||||
if ascii_mask(b"|+-*/%^&79") & (1u128 << id) == 0 {
|
if ascii_mask(b"|+-*/%^&79") & (1u128 << id) == 0 {
|
||||||
|
@ -270,17 +193,62 @@ impl TokenKind {
|
||||||
matches!(self, S::Eq | S::Ne | S::Bor | S::Xor | S::Band | S::Add | S::Mul)
|
matches!(self, S::Eq | S::Ne | S::Bor | S::Xor | S::Band | S::Add | S::Mul)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_binop(self, a: i64, b: i64) -> i64 {
|
pub fn is_supported_float_op(self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::Add
|
||||||
|
| Self::Sub
|
||||||
|
| Self::Mul
|
||||||
|
| Self::Div
|
||||||
|
| Self::Eq
|
||||||
|
| Self::Ne
|
||||||
|
| Self::Le
|
||||||
|
| Self::Ge
|
||||||
|
| Self::Lt
|
||||||
|
| Self::Gt
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_binop(self, a: i64, b: i64, float: bool) -> i64 {
|
||||||
|
if float {
|
||||||
|
debug_assert!(self.is_supported_float_op());
|
||||||
|
let [a, b] = [f64::from_bits(a as _), f64::from_bits(b as _)];
|
||||||
|
let res = match self {
|
||||||
|
Self::Add => a + b,
|
||||||
|
Self::Sub => a - b,
|
||||||
|
Self::Mul => a * b,
|
||||||
|
Self::Div => a / b,
|
||||||
|
Self::Eq => return (a == b) as i64,
|
||||||
|
Self::Ne => return (a != b) as i64,
|
||||||
|
Self::Lt => return (a < b) as i64,
|
||||||
|
Self::Gt => return (a > b) as i64,
|
||||||
|
Self::Le => return (a >= b) as i64,
|
||||||
|
Self::Ge => return (a <= b) as i64,
|
||||||
|
_ => todo!("floating point op: {self}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
return res.to_bits() as _;
|
||||||
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Add => a.wrapping_add(b),
|
Self::Add => a.wrapping_add(b),
|
||||||
Self::Sub => a.wrapping_sub(b),
|
Self::Sub => a.wrapping_sub(b),
|
||||||
Self::Mul => a.wrapping_mul(b),
|
Self::Mul => a.wrapping_mul(b),
|
||||||
|
Self::Div if b == 0 => 0,
|
||||||
Self::Div => a.wrapping_div(b),
|
Self::Div => a.wrapping_div(b),
|
||||||
Self::Shl => a.wrapping_shl(b as _),
|
Self::Shl => a.wrapping_shl(b as _),
|
||||||
Self::Eq => (a == b) as i64,
|
Self::Eq => (a == b) as i64,
|
||||||
Self::Ne => (a != b) as i64,
|
Self::Ne => (a != b) as i64,
|
||||||
|
Self::Lt => (a < b) as i64,
|
||||||
|
Self::Gt => (a > b) as i64,
|
||||||
|
Self::Le => (a >= b) as i64,
|
||||||
|
Self::Ge => (a <= b) as i64,
|
||||||
Self::Band => a & b,
|
Self::Band => a & b,
|
||||||
Self::Shr => a >> b,
|
Self::Bor => a | b,
|
||||||
|
Self::Xor => a ^ b,
|
||||||
|
Self::Mod if b == 0 => 0,
|
||||||
|
Self::Mod => a.wrapping_rem(b),
|
||||||
|
Self::Shr => a.wrapping_shr(b as _),
|
||||||
s => todo!("{s}"),
|
s => todo!("{s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,19 +259,30 @@ impl TokenKind {
|
||||||
&& self.precedence() != Self::Eof.precedence()
|
&& self.precedence() != Self::Eof.precedence()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unop(&self) -> Option<fn(u8, u8) -> EncodedInstr> {
|
pub fn apply_unop(&self, value: i64, float: bool) -> i64 {
|
||||||
Some(match self {
|
|
||||||
Self::Sub => crate::instrs::neg,
|
|
||||||
_ => return None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_unop(&self, value: i64) -> i64 {
|
|
||||||
match self {
|
match self {
|
||||||
|
Self::Sub if float => (-f64::from_bits(value as _)).to_bits() as _,
|
||||||
Self::Sub => value.wrapping_neg(),
|
Self::Sub => value.wrapping_neg(),
|
||||||
|
Self::Float if float => value,
|
||||||
|
Self::Float => (value as f64).to_bits() as _,
|
||||||
|
Self::Number => {
|
||||||
|
debug_assert!(float);
|
||||||
|
f64::from_bits(value as _).to_bits() as _
|
||||||
|
}
|
||||||
s => todo!("{s}"),
|
s => todo!("{s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn closing(&self) -> Option<TokenKind> {
|
||||||
|
Some(match self {
|
||||||
|
Self::Ctor => Self::RBrace,
|
||||||
|
Self::Tupl => Self::RParen,
|
||||||
|
Self::LParen => Self::RParen,
|
||||||
|
Self::LBrack => Self::RBrack,
|
||||||
|
Self::LBrace => Self::RBrace,
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_token_kind! {
|
gen_token_kind! {
|
||||||
|
@ -312,6 +291,7 @@ gen_token_kind! {
|
||||||
CtIdent,
|
CtIdent,
|
||||||
Ident,
|
Ident,
|
||||||
Number,
|
Number,
|
||||||
|
Float,
|
||||||
Eof,
|
Eof,
|
||||||
Directive,
|
Directive,
|
||||||
#[keywords]
|
#[keywords]
|
||||||
|
@ -326,7 +306,10 @@ gen_token_kind! {
|
||||||
Packed = b"packed",
|
Packed = b"packed",
|
||||||
True = b"true",
|
True = b"true",
|
||||||
False = b"false",
|
False = b"false",
|
||||||
Idk = b"idk",
|
Null = b"null",
|
||||||
|
Idk = b"idk",
|
||||||
|
Die = b"die",
|
||||||
|
Under = b"_",
|
||||||
#[punkt]
|
#[punkt]
|
||||||
Ctor = ".{",
|
Ctor = ".{",
|
||||||
Tupl = ".(",
|
Tupl = ".(",
|
||||||
|
@ -475,7 +458,15 @@ impl<'a> Lexer<'a> {
|
||||||
while let Some(b'0'..=b'9') = self.peek() {
|
while let Some(b'0'..=b'9') = self.peek() {
|
||||||
self.advance();
|
self.advance();
|
||||||
}
|
}
|
||||||
T::Number
|
|
||||||
|
if self.advance_if(b'.') {
|
||||||
|
while let Some(b'0'..=b'9') = self.peek() {
|
||||||
|
self.advance();
|
||||||
|
}
|
||||||
|
T::Float
|
||||||
|
} else {
|
||||||
|
T::Number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
b'a'..=b'z' | b'A'..=b'Z' | b'_' | 127.. => {
|
b'a'..=b'z' | b'A'..=b'Z' | b'_' | 127.. => {
|
||||||
advance_ident(self);
|
advance_ident(self);
|
||||||
|
|
912
lang/src/lib.rs
912
lang/src/lib.rs
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,7 @@ fn main() -> std::io::Result<()> {
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
log::set_logger(&hblang::Logger).unwrap();
|
log::set_logger(&hblang::Logger).unwrap();
|
||||||
log::set_max_level(log::LevelFilter::Error);
|
log::set_max_level(log::LevelFilter::Info);
|
||||||
|
|
||||||
let args = std::env::args().collect::<Vec<_>>();
|
let args = std::env::args().collect::<Vec<_>>();
|
||||||
let args = args.iter().map(String::as_str).collect::<Vec<_>>();
|
let args = args.iter().map(String::as_str).collect::<Vec<_>>();
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
fmt::Formatter,
|
fmt::Formatter,
|
||||||
ident::{self, Ident},
|
|
||||||
lexer::{self, Lexer, Token, TokenKind},
|
lexer::{self, Lexer, Token, TokenKind},
|
||||||
|
Ident,
|
||||||
},
|
},
|
||||||
alloc::{boxed::Box, string::String, vec::Vec},
|
alloc::{boxed::Box, string::String, vec::Vec},
|
||||||
core::{
|
core::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
cell::UnsafeCell,
|
cell::{RefCell, UnsafeCell},
|
||||||
fmt::{self},
|
fmt::{self},
|
||||||
intrinsics::unlikely,
|
intrinsics::unlikely,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
@ -19,7 +19,6 @@ use {
|
||||||
|
|
||||||
pub type Pos = u32;
|
pub type Pos = u32;
|
||||||
pub type IdentFlags = u32;
|
pub type IdentFlags = u32;
|
||||||
pub type Symbols = Vec<Symbol>;
|
|
||||||
pub type FileId = u32;
|
pub type FileId = u32;
|
||||||
pub type IdentIndex = u16;
|
pub type IdentIndex = u16;
|
||||||
pub type LoaderError = String;
|
pub type LoaderError = String;
|
||||||
|
@ -31,6 +30,20 @@ pub enum FileKind {
|
||||||
Embed,
|
Embed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait Trans {
|
||||||
|
fn trans(self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Trans for Option<Option<T>> {
|
||||||
|
fn trans(self) -> Self {
|
||||||
|
match self {
|
||||||
|
Some(None) => None,
|
||||||
|
Some(Some(v)) => Some(Some(v)),
|
||||||
|
None => Some(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const SOURCE_TO_AST_FACTOR: usize = 7 * (core::mem::size_of::<usize>() / 4) + 1;
|
pub const SOURCE_TO_AST_FACTOR: usize = 7 * (core::mem::size_of::<usize>() / 4) + 1;
|
||||||
|
|
||||||
pub mod idfl {
|
pub mod idfl {
|
||||||
|
@ -73,7 +86,7 @@ pub struct Parser<'a, 'b> {
|
||||||
loader: Loader<'b>,
|
loader: Loader<'b>,
|
||||||
lexer: Lexer<'a>,
|
lexer: Lexer<'a>,
|
||||||
arena: &'a Arena,
|
arena: &'a Arena,
|
||||||
ctx: &'b mut ParserCtx,
|
ctx: &'b mut Ctx,
|
||||||
token: Token,
|
token: Token,
|
||||||
ns_bound: usize,
|
ns_bound: usize,
|
||||||
trailing_sep: bool,
|
trailing_sep: bool,
|
||||||
|
@ -82,7 +95,7 @@ pub struct Parser<'a, 'b> {
|
||||||
|
|
||||||
impl<'a, 'b> Parser<'a, 'b> {
|
impl<'a, 'b> Parser<'a, 'b> {
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
ctx: &'b mut ParserCtx,
|
ctx: &'b mut Ctx,
|
||||||
input: &'a str,
|
input: &'a str,
|
||||||
path: &'b str,
|
path: &'b str,
|
||||||
loader: Loader<'b>,
|
loader: Loader<'b>,
|
||||||
|
@ -110,23 +123,14 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
|
|
||||||
if !self.ctx.idents.is_empty() {
|
if !self.ctx.idents.is_empty() {
|
||||||
// TODO: we need error recovery
|
// TODO: we need error recovery
|
||||||
log::error!("{}", {
|
let mut idents = core::mem::take(&mut self.ctx.idents);
|
||||||
let mut errors = String::new();
|
for id in idents.drain(..) {
|
||||||
for id in self.ctx.idents.drain(..) {
|
self.report(
|
||||||
report_to(
|
id.ident.pos(),
|
||||||
self.lexer.source(),
|
format_args!("undeclared identifier: {}", self.lexer.slice(id.ident.range())),
|
||||||
self.path,
|
);
|
||||||
ident::pos(id.ident),
|
}
|
||||||
&format_args!(
|
self.ctx.idents = idents;
|
||||||
"undeclared identifier: {}",
|
|
||||||
self.lexer.slice(ident::range(id.ident))
|
|
||||||
),
|
|
||||||
&mut errors,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
errors
|
|
||||||
});
|
|
||||||
unreachable!();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f
|
f
|
||||||
|
@ -136,53 +140,56 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
core::mem::replace(&mut self.token, self.lexer.eat())
|
core::mem::replace(&mut self.token, self.lexer.eat())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ptr_expr(&mut self) -> &'a Expr<'a> {
|
fn ptr_expr(&mut self) -> Option<&'a Expr<'a>> {
|
||||||
self.arena.alloc(self.expr())
|
Some(self.arena.alloc(self.expr()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_low(&mut self, top_level: bool) -> Expr<'a> {
|
fn expr_low(&mut self, top_level: bool) -> Option<Expr<'a>> {
|
||||||
let left = self.unit_expr();
|
let left = self.unit_expr()?;
|
||||||
self.bin_expr(left, 0, top_level)
|
self.bin_expr(left, 0, top_level)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr(&mut self) -> Expr<'a> {
|
fn expr(&mut self) -> Option<Expr<'a>> {
|
||||||
self.expr_low(false)
|
self.expr_low(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bin_expr(&mut self, mut fold: Expr<'a>, min_prec: u8, top_level: bool) -> Expr<'a> {
|
fn bin_expr(&mut self, mut fold: Expr<'a>, min_prec: u8, top_level: bool) -> Option<Expr<'a>> {
|
||||||
loop {
|
loop {
|
||||||
let Some(prec) = self.token.kind.precedence() else {
|
let Some(prec) = self.token.kind.precedence() else { break };
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
if prec <= min_prec {
|
if prec <= min_prec {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let op = self.next().kind;
|
let Token { kind: op, start: pos, .. } = self.next();
|
||||||
|
|
||||||
if op == TokenKind::Decl {
|
if op == TokenKind::Decl {
|
||||||
self.declare_rec(&fold, top_level);
|
self.declare_rec(&fold, top_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
let right = self.unit_expr();
|
let right = self.unit_expr()?;
|
||||||
let right = self.bin_expr(right, prec, false);
|
let right = self.bin_expr(right, prec, false)?;
|
||||||
let right = self.arena.alloc(right);
|
let right = self.arena.alloc(right);
|
||||||
let left = self.arena.alloc(fold);
|
let left = self.arena.alloc(fold);
|
||||||
|
|
||||||
if let Some(op) = op.ass_op() {
|
if let Some(op) = op.ass_op() {
|
||||||
self.flag_idents(*left, idfl::MUTABLE);
|
self.flag_idents(*left, idfl::MUTABLE);
|
||||||
let right = Expr::BinOp { left: self.arena.alloc(fold), op, right };
|
let right = Expr::BinOp { left: self.arena.alloc(fold), pos, op, right };
|
||||||
fold = Expr::BinOp { left, op: TokenKind::Assign, right: self.arena.alloc(right) };
|
fold = Expr::BinOp {
|
||||||
|
left,
|
||||||
|
pos,
|
||||||
|
op: TokenKind::Assign,
|
||||||
|
right: self.arena.alloc(right),
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
fold = Expr::BinOp { left, right, op };
|
fold = Expr::BinOp { left, right, pos, op };
|
||||||
if op == TokenKind::Assign {
|
if op == TokenKind::Assign {
|
||||||
self.flag_idents(*left, idfl::MUTABLE);
|
self.flag_idents(*left, idfl::MUTABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fold
|
Some(fold)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declare_rec(&mut self, expr: &Expr, top_level: bool) {
|
fn declare_rec(&mut self, expr: &Expr, top_level: bool) {
|
||||||
|
@ -195,7 +202,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
self.declare_rec(value, top_level)
|
self.declare_rec(value, top_level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self.report(expr.pos(), "cant declare this shit (yet)"),
|
_ => _ = self.report(expr.pos(), "cant declare this shit (yet)"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,19 +212,21 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
pos,
|
pos,
|
||||||
format_args!(
|
format_args!(
|
||||||
"out of order declaration not allowed: {}",
|
"out of order declaration not allowed: {}",
|
||||||
self.lexer.slice(ident::range(id))
|
self.lexer.slice(id.range())
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Ok(index) = self.ctx.idents.binary_search_by_key(&id, |s| s.ident) else {
|
let Ok(index) = self.ctx.idents.binary_search_by_key(&id, |s| s.ident) else {
|
||||||
self.report(pos, "the identifier is rezerved for a builtin (proably)");
|
self.report(pos, "the identifier is rezerved for a builtin (proably)");
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
if core::mem::replace(&mut self.ctx.idents[index].declared, true) {
|
if core::mem::replace(&mut self.ctx.idents[index].declared, true) {
|
||||||
self.report(
|
self.report(
|
||||||
pos,
|
pos,
|
||||||
format_args!("redeclaration of identifier: {}", self.lexer.slice(ident::range(id))),
|
format_args!("redeclaration of identifier: {}", self.lexer.slice(id.range())),
|
||||||
)
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ctx.idents[index].ordered = ordered;
|
self.ctx.idents[index].ordered = ordered;
|
||||||
|
@ -228,7 +237,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
let name = self.lexer.slice(token.range());
|
let name = self.lexer.slice(token.range());
|
||||||
|
|
||||||
if let Some(builtin) = crate::ty::from_str(name) {
|
if let Some(builtin) = crate::ty::from_str(name) {
|
||||||
return (builtin, false);
|
return (Ident::builtin(builtin), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (i, id, bl) = match self
|
let (i, id, bl) = match self
|
||||||
|
@ -236,15 +245,20 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
.idents
|
.idents
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.rfind(|(_, elem)| self.lexer.slice(ident::range(elem.ident)) == name)
|
.rfind(|(_, elem)| self.lexer.slice(elem.ident.range()) == name)
|
||||||
{
|
{
|
||||||
Some((i, elem)) => (i, elem, false),
|
Some((i, elem)) => (i, elem, false),
|
||||||
None => {
|
None => {
|
||||||
let Some(id) = ident::new(token.start, name.len() as _) else {
|
let ident = match Ident::new(token.start, name.len() as _) {
|
||||||
self.report(token.start, "identifier can at most have 64 characters");
|
None => {
|
||||||
|
self.report(token.start, "identifier can at most have 64 characters");
|
||||||
|
Ident::new(token.start, 63).unwrap()
|
||||||
|
}
|
||||||
|
Some(id) => id,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.ctx.idents.push(ScopeIdent {
|
self.ctx.idents.push(ScopeIdent {
|
||||||
ident: id,
|
ident,
|
||||||
declared: false,
|
declared: false,
|
||||||
ordered: false,
|
ordered: false,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
|
@ -266,18 +280,18 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
self.lexer.slice(range.range())
|
self.lexer.slice(range.range())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unit_expr(&mut self) -> Expr<'a> {
|
fn unit_expr(&mut self) -> Option<Expr<'a>> {
|
||||||
use {Expr as E, TokenKind as T};
|
use {Expr as E, TokenKind as T};
|
||||||
let frame = self.ctx.idents.len();
|
let frame = self.ctx.idents.len();
|
||||||
let token @ Token { start: pos, .. } = self.next();
|
let token @ Token { start: pos, .. } = self.next();
|
||||||
let prev_boundary = self.ns_bound;
|
let prev_boundary = self.ns_bound;
|
||||||
let prev_captured = self.ctx.captured.len();
|
let prev_captured = self.ctx.captured.len();
|
||||||
let mut expr = match token.kind {
|
let mut expr = match token.kind {
|
||||||
T::Ct => E::Ct { pos, value: self.ptr_expr() },
|
T::Ct => E::Ct { pos, value: self.ptr_expr()? },
|
||||||
T::Directive if self.lexer.slice(token.range()) == "use" => {
|
T::Directive if self.lexer.slice(token.range()) == "use" => {
|
||||||
self.expect_advance(TokenKind::LParen);
|
self.expect_advance(TokenKind::LParen)?;
|
||||||
let str = self.expect_advance(TokenKind::DQuote);
|
let str = self.expect_advance(TokenKind::DQuote)?;
|
||||||
self.expect_advance(TokenKind::RParen);
|
self.expect_advance(TokenKind::RParen)?;
|
||||||
let path = self.lexer.slice(str.range());
|
let path = self.lexer.slice(str.range());
|
||||||
let path = &path[1..path.len() - 1];
|
let path = &path[1..path.len() - 1];
|
||||||
|
|
||||||
|
@ -287,15 +301,15 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
id: match (self.loader)(path, self.path, FileKind::Module) {
|
id: match (self.loader)(path, self.path, FileKind::Module) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.report(str.start, format_args!("error loading dependency: {e:#}"))
|
self.report(str.start, format_args!("error loading dependency: {e:#}"))?
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
T::Directive if self.lexer.slice(token.range()) == "embed" => {
|
T::Directive if self.lexer.slice(token.range()) == "embed" => {
|
||||||
self.expect_advance(TokenKind::LParen);
|
self.expect_advance(TokenKind::LParen)?;
|
||||||
let str = self.expect_advance(TokenKind::DQuote);
|
let str = self.expect_advance(TokenKind::DQuote)?;
|
||||||
self.expect_advance(TokenKind::RParen);
|
self.expect_advance(TokenKind::RParen)?;
|
||||||
let path = self.lexer.slice(str.range());
|
let path = self.lexer.slice(str.range());
|
||||||
let path = &path[1..path.len() - 1];
|
let path = &path[1..path.len() - 1];
|
||||||
|
|
||||||
|
@ -304,8 +318,10 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
path,
|
path,
|
||||||
id: match (self.loader)(path, self.path, FileKind::Embed) {
|
id: match (self.loader)(path, self.path, FileKind::Embed) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(e) => self
|
Err(e) => self.report(
|
||||||
.report(str.start, format_args!("error loading embedded file: {e:#}")),
|
str.start,
|
||||||
|
format_args!("error loading embedded file: {e:#}"),
|
||||||
|
)?,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,17 +329,19 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
pos: pos - 1, // need to undo the directive shift
|
pos: pos - 1, // need to undo the directive shift
|
||||||
name: self.tok_str(token),
|
name: self.tok_str(token),
|
||||||
args: {
|
args: {
|
||||||
self.expect_advance(T::LParen);
|
self.expect_advance(T::LParen)?;
|
||||||
self.collect_list(T::Comma, T::RParen, Self::expr)
|
self.collect_list(T::Comma, T::RParen, Self::expr)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
T::True => E::Bool { pos, value: true },
|
T::True => E::Bool { pos, value: true },
|
||||||
T::False => E::Bool { pos, value: false },
|
T::False => E::Bool { pos, value: false },
|
||||||
|
T::Null => E::Null { pos },
|
||||||
T::Idk => E::Idk { pos },
|
T::Idk => E::Idk { pos },
|
||||||
|
T::Die => E::Die { pos },
|
||||||
T::DQuote => E::String { pos, literal: self.tok_str(token) },
|
T::DQuote => E::String { pos, literal: self.tok_str(token) },
|
||||||
T::Packed => {
|
T::Packed => {
|
||||||
self.packed = true;
|
self.packed = true;
|
||||||
let expr = self.unit_expr();
|
let expr = self.unit_expr()?;
|
||||||
if self.packed {
|
if self.packed {
|
||||||
self.report(
|
self.report(
|
||||||
expr.pos(),
|
expr.pos(),
|
||||||
|
@ -337,20 +355,20 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
packed: core::mem::take(&mut self.packed),
|
packed: core::mem::take(&mut self.packed),
|
||||||
fields: {
|
fields: {
|
||||||
self.ns_bound = self.ctx.idents.len();
|
self.ns_bound = self.ctx.idents.len();
|
||||||
self.expect_advance(T::LBrace);
|
self.expect_advance(T::LBrace)?;
|
||||||
self.collect_list(T::Comma, T::RBrace, |s| {
|
self.collect_list(T::Comma, T::RBrace, |s| {
|
||||||
let tok = s.token;
|
let tok = s.token;
|
||||||
if s.advance_if(T::Comment) {
|
Some(if s.advance_if(T::Comment) {
|
||||||
CommentOr::Comment { literal: s.tok_str(tok), pos: tok.start }
|
CommentOr::Comment { literal: s.tok_str(tok), pos: tok.start }
|
||||||
} else {
|
} else {
|
||||||
let name = s.expect_advance(T::Ident);
|
let name = s.expect_advance(T::Ident)?;
|
||||||
s.expect_advance(T::Colon);
|
s.expect_advance(T::Colon)?;
|
||||||
CommentOr::Or(StructField {
|
CommentOr::Or(StructField {
|
||||||
pos: name.start,
|
pos: name.start,
|
||||||
name: s.tok_str(name),
|
name: s.tok_str(name),
|
||||||
ty: s.expr(),
|
ty: s.expr()?,
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
captured: {
|
captured: {
|
||||||
|
@ -374,13 +392,14 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
let (id, is_first) = self.resolve_ident(token);
|
let (id, is_first) = self.resolve_ident(token);
|
||||||
E::Ident { pos, is_ct: token.kind == T::CtIdent, id, is_first }
|
E::Ident { pos, is_ct: token.kind == T::CtIdent, id, is_first }
|
||||||
}
|
}
|
||||||
|
T::Under => E::Wildcard { pos },
|
||||||
T::If => E::If {
|
T::If => E::If {
|
||||||
pos,
|
pos,
|
||||||
cond: self.ptr_expr(),
|
cond: self.ptr_expr()?,
|
||||||
then: self.ptr_expr(),
|
then: self.ptr_expr()?,
|
||||||
else_: self.advance_if(T::Else).then(|| self.ptr_expr()),
|
else_: self.advance_if(T::Else).then(|| self.ptr_expr()).trans()?,
|
||||||
},
|
},
|
||||||
T::Loop => E::Loop { pos, body: self.ptr_expr() },
|
T::Loop => E::Loop { pos, body: self.ptr_expr()? },
|
||||||
T::Break => E::Break { pos },
|
T::Break => E::Break { pos },
|
||||||
T::Continue => E::Continue { pos },
|
T::Continue => E::Continue { pos },
|
||||||
T::Return => E::Return {
|
T::Return => E::Return {
|
||||||
|
@ -389,47 +408,48 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
self.token.kind,
|
self.token.kind,
|
||||||
T::Semi | T::RBrace | T::RBrack | T::RParen | T::Comma
|
T::Semi | T::RBrace | T::RBrack | T::RParen | T::Comma
|
||||||
))
|
))
|
||||||
.then(|| self.ptr_expr()),
|
.then(|| self.ptr_expr())
|
||||||
|
.trans()?,
|
||||||
},
|
},
|
||||||
T::Fn => E::Closure {
|
T::Fn => E::Closure {
|
||||||
pos,
|
pos,
|
||||||
args: {
|
args: {
|
||||||
self.expect_advance(T::LParen);
|
self.expect_advance(T::LParen)?;
|
||||||
self.collect_list(T::Comma, T::RParen, |s| {
|
self.collect_list(T::Comma, T::RParen, |s| {
|
||||||
let name = s.advance_ident();
|
let name = s.advance_ident()?;
|
||||||
let (id, _) = s.resolve_ident(name);
|
let (id, _) = s.resolve_ident(name);
|
||||||
s.declare(name.start, id, true, true);
|
s.declare(name.start, id, true, true);
|
||||||
s.expect_advance(T::Colon);
|
s.expect_advance(T::Colon)?;
|
||||||
Arg {
|
Some(Arg {
|
||||||
pos: name.start,
|
pos: name.start,
|
||||||
name: s.tok_str(name),
|
name: s.tok_str(name),
|
||||||
is_ct: name.kind == T::CtIdent,
|
is_ct: name.kind == T::CtIdent,
|
||||||
id,
|
id,
|
||||||
ty: s.expr(),
|
ty: s.expr()?,
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
ret: {
|
ret: {
|
||||||
self.expect_advance(T::Colon);
|
self.expect_advance(T::Colon)?;
|
||||||
self.ptr_expr()
|
self.ptr_expr()?
|
||||||
},
|
},
|
||||||
body: self.ptr_expr(),
|
body: self.ptr_expr()?,
|
||||||
},
|
},
|
||||||
T::Ctor => self.ctor(pos, None),
|
T::Ctor => self.ctor(pos, None),
|
||||||
T::Tupl => self.tupl(pos, None),
|
T::Tupl => self.tupl(pos, None),
|
||||||
T::LBrack => E::Slice {
|
T::LBrack => E::Slice {
|
||||||
item: self.ptr_unit_expr(),
|
item: self.ptr_unit_expr()?,
|
||||||
size: self.advance_if(T::Semi).then(|| self.ptr_expr()),
|
size: self.advance_if(T::Semi).then(|| self.ptr_expr()).trans()?,
|
||||||
pos: {
|
pos: {
|
||||||
self.expect_advance(T::RBrack);
|
self.expect_advance(T::RBrack)?;
|
||||||
pos
|
pos
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
T::Band | T::Mul | T::Xor | T::Sub => E::UnOp {
|
T::Band | T::Mul | T::Xor | T::Sub | T::Que => E::UnOp {
|
||||||
pos,
|
pos,
|
||||||
op: token.kind,
|
op: token.kind,
|
||||||
val: {
|
val: {
|
||||||
let expr = self.ptr_unit_expr();
|
let expr = self.ptr_unit_expr()?;
|
||||||
if token.kind == T::Band {
|
if token.kind == T::Band {
|
||||||
self.flag_idents(*expr, idfl::REFERENCED);
|
self.flag_idents(*expr, idfl::REFERENCED);
|
||||||
}
|
}
|
||||||
|
@ -449,18 +469,26 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
pos,
|
pos,
|
||||||
value: match u64::from_str_radix(slice, radix as u32) {
|
value: match u64::from_str_radix(slice, radix as u32) {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(e) => self.report(token.start, format_args!("invalid number: {e}")),
|
Err(e) => self.report(token.start, format_args!("invalid number: {e}"))?,
|
||||||
} as i64,
|
} as i64,
|
||||||
radix,
|
radix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
T::Float => E::Float {
|
||||||
|
pos,
|
||||||
|
value: match <f64 as core::str::FromStr>::from_str(self.lexer.slice(token.range()))
|
||||||
|
{
|
||||||
|
Ok(f) => f.to_bits(),
|
||||||
|
Err(e) => self.report(token.start, format_args!("invalid float: {e}"))?,
|
||||||
|
},
|
||||||
|
},
|
||||||
T::LParen => {
|
T::LParen => {
|
||||||
let expr = self.expr();
|
let expr = self.expr()?;
|
||||||
self.expect_advance(T::RParen);
|
self.expect_advance(T::RParen)?;
|
||||||
expr
|
expr
|
||||||
}
|
}
|
||||||
T::Comment => Expr::Comment { pos, literal: self.tok_str(token) },
|
T::Comment => Expr::Comment { pos, literal: self.tok_str(token) },
|
||||||
tok => self.report(token.start, format_args!("unexpected token: {tok}")),
|
tok => self.report(token.start, format_args!("unexpected token: {tok}"))?,
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -480,8 +508,8 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
T::LBrack => E::Index {
|
T::LBrack => E::Index {
|
||||||
base: self.arena.alloc(expr),
|
base: self.arena.alloc(expr),
|
||||||
index: {
|
index: {
|
||||||
let index = self.expr();
|
let index = self.expr()?;
|
||||||
self.expect_advance(T::RBrack);
|
self.expect_advance(T::RBrack)?;
|
||||||
self.arena.alloc(index)
|
self.arena.alloc(index)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -489,7 +517,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
target: self.arena.alloc(expr),
|
target: self.arena.alloc(expr),
|
||||||
pos: token.start,
|
pos: token.start,
|
||||||
name: {
|
name: {
|
||||||
let token = self.expect_advance(T::Ident);
|
let token = self.expect_advance(T::Ident)?;
|
||||||
self.tok_str(token)
|
self.tok_str(token)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -501,7 +529,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
self.pop_scope(frame);
|
self.pop_scope(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr
|
Some(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tupl(&mut self, pos: Pos, ty: Option<Expr<'a>>) -> Expr<'a> {
|
fn tupl(&mut self, pos: Pos, ty: Option<Expr<'a>>) -> Expr<'a> {
|
||||||
|
@ -518,31 +546,29 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
pos,
|
pos,
|
||||||
ty: ty.map(|ty| self.arena.alloc(ty)),
|
ty: ty.map(|ty| self.arena.alloc(ty)),
|
||||||
fields: self.collect_list(TokenKind::Comma, TokenKind::RBrace, |s| {
|
fields: self.collect_list(TokenKind::Comma, TokenKind::RBrace, |s| {
|
||||||
let name_tok = s.advance_ident();
|
let name_tok = s.advance_ident()?;
|
||||||
let name = s.tok_str(name_tok);
|
let name = s.tok_str(name_tok);
|
||||||
CtorField {
|
Some(CtorField {
|
||||||
pos: name_tok.start,
|
pos: name_tok.start,
|
||||||
name,
|
name,
|
||||||
value: if s.advance_if(TokenKind::Colon) {
|
value: if s.advance_if(TokenKind::Colon) {
|
||||||
s.expr()
|
s.expr()?
|
||||||
} else {
|
} else {
|
||||||
let (id, is_first) = s.resolve_ident(name_tok);
|
let (id, is_first) = s.resolve_ident(name_tok);
|
||||||
Expr::Ident { pos: name_tok.start, is_ct: false, id, is_first }
|
Expr::Ident { pos: name_tok.start, is_ct: false, id, is_first }
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}),
|
}),
|
||||||
trailing_comma: core::mem::take(&mut self.trailing_sep),
|
trailing_comma: core::mem::take(&mut self.trailing_sep),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance_ident(&mut self) -> Token {
|
fn advance_ident(&mut self) -> Option<Token> {
|
||||||
if matches!(self.token.kind, TokenKind::Ident | TokenKind::CtIdent) {
|
let next = self.next();
|
||||||
self.next()
|
if matches!(next.kind, TokenKind::Ident | TokenKind::CtIdent) {
|
||||||
|
Some(next)
|
||||||
} else {
|
} else {
|
||||||
self.report(
|
self.report(self.token.start, format_args!("expected identifier, found {}", next.kind))?
|
||||||
self.token.start,
|
|
||||||
format_args!("expected identifier, found {}", self.token.kind),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,20 +588,49 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
.collect_into(&mut self.ctx.symbols);
|
.collect_into(&mut self.ctx.symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ptr_unit_expr(&mut self) -> &'a Expr<'a> {
|
fn ptr_unit_expr(&mut self) -> Option<&'a Expr<'a>> {
|
||||||
self.arena.alloc(self.unit_expr())
|
Some(self.arena.alloc(self.unit_expr()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_list<T: Copy>(
|
fn collect_list<T: Copy>(
|
||||||
&mut self,
|
&mut self,
|
||||||
delim: TokenKind,
|
delim: TokenKind,
|
||||||
end: TokenKind,
|
end: TokenKind,
|
||||||
mut f: impl FnMut(&mut Self) -> T,
|
mut f: impl FnMut(&mut Self) -> Option<T>,
|
||||||
) -> &'a [T] {
|
) -> &'a [T] {
|
||||||
let mut trailing_sep = false;
|
let mut trailing_sep = false;
|
||||||
let mut view = self.ctx.stack.view();
|
let mut view = self.ctx.stack.view();
|
||||||
while !self.advance_if(end) {
|
'o: while !self.advance_if(end) {
|
||||||
let val = f(self);
|
let val = match f(self) {
|
||||||
|
Some(val) => val,
|
||||||
|
None => {
|
||||||
|
let mut paren = None::<TokenKind>;
|
||||||
|
let mut depth = 0;
|
||||||
|
loop {
|
||||||
|
let tok = self.next();
|
||||||
|
if tok.kind == TokenKind::Eof {
|
||||||
|
break 'o;
|
||||||
|
}
|
||||||
|
if let Some(par) = paren {
|
||||||
|
if par == tok.kind {
|
||||||
|
depth += 1;
|
||||||
|
} else if tok.kind.closing() == par.closing() {
|
||||||
|
depth -= 1;
|
||||||
|
if depth == 0 {
|
||||||
|
paren = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if tok.kind == delim {
|
||||||
|
continue 'o;
|
||||||
|
} else if tok.kind == end {
|
||||||
|
break 'o;
|
||||||
|
} else if tok.kind.closing().is_some() && paren.is_none() {
|
||||||
|
paren = Some(tok.kind);
|
||||||
|
depth = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
trailing_sep = self.advance_if(delim);
|
trailing_sep = self.advance_if(delim);
|
||||||
unsafe { self.ctx.stack.push(&mut view, val) };
|
unsafe { self.ctx.stack.push(&mut view, val) };
|
||||||
}
|
}
|
||||||
|
@ -592,20 +647,28 @@ impl<'a, 'b> Parser<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expect_advance(&mut self, kind: TokenKind) -> Token {
|
#[must_use]
|
||||||
if self.token.kind != kind {
|
fn expect_advance(&mut self, kind: TokenKind) -> Option<Token> {
|
||||||
self.report(
|
let next = self.next();
|
||||||
self.token.start,
|
if next.kind != kind {
|
||||||
format_args!("expected {}, found {}", kind, self.token.kind),
|
self.report(next.start, format_args!("expected {}, found {}", kind, next.kind))?
|
||||||
);
|
} else {
|
||||||
|
Some(next)
|
||||||
}
|
}
|
||||||
self.next()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn report(&self, pos: Pos, msg: impl fmt::Display) -> ! {
|
fn report(&mut self, pos: Pos, msg: impl fmt::Display) -> Option<!> {
|
||||||
log::error!("{}", Report::new(self.lexer.source(), self.path, pos, msg));
|
if log::log_enabled!(log::Level::Error) {
|
||||||
unreachable!();
|
use core::fmt::Write;
|
||||||
|
writeln!(
|
||||||
|
self.ctx.errors.get_mut(),
|
||||||
|
"{}",
|
||||||
|
Report::new(self.lexer.source(), self.path, pos, msg)
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flag_idents(&mut self, e: Expr<'a>, flags: IdentFlags) {
|
fn flag_idents(&mut self, e: Expr<'a>, flags: IdentFlags) {
|
||||||
|
@ -668,7 +731,7 @@ macro_rules! generate_expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pos(&self) -> Pos {
|
pub fn pos(&self) -> Pos {
|
||||||
#[allow(unused_variables)]
|
#[expect(unused_variables)]
|
||||||
match self {
|
match self {
|
||||||
$(Self::$variant { $($field),* } => generate_expr!(@first $(($field),)*).posi(),)*
|
$(Self::$variant { $($field),* } => generate_expr!(@first $(($field),)*).posi(),)*
|
||||||
}
|
}
|
||||||
|
@ -738,6 +801,9 @@ generate_expr! {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
val: Option<&'a Self>,
|
val: Option<&'a Self>,
|
||||||
},
|
},
|
||||||
|
Wildcard {
|
||||||
|
pos: Pos,
|
||||||
|
},
|
||||||
/// note: ':unicode:' is any utf-8 character except ascii
|
/// note: ':unicode:' is any utf-8 character except ascii
|
||||||
/// `'[a-zA-Z_:unicode:][a-zA-Z0-9_:unicode:]*'`
|
/// `'[a-zA-Z_:unicode:][a-zA-Z0-9_:unicode:]*'`
|
||||||
Ident {
|
Ident {
|
||||||
|
@ -758,10 +824,16 @@ generate_expr! {
|
||||||
value: i64,
|
value: i64,
|
||||||
radix: Radix,
|
radix: Radix,
|
||||||
},
|
},
|
||||||
|
/// `'[0-9]+.[0-9]*'`
|
||||||
|
Float {
|
||||||
|
pos: Pos,
|
||||||
|
value: u64,
|
||||||
|
},
|
||||||
/// node: precedence defined in `OP` applies
|
/// node: precedence defined in `OP` applies
|
||||||
/// `Expr OP Expr`
|
/// `Expr OP Expr`
|
||||||
BinOp {
|
BinOp {
|
||||||
left: &'a Self,
|
left: &'a Self,
|
||||||
|
pos: Pos,
|
||||||
op: TokenKind,
|
op: TokenKind,
|
||||||
right: &'a Self,
|
right: &'a Self,
|
||||||
},
|
},
|
||||||
|
@ -828,10 +900,18 @@ generate_expr! {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
value: bool,
|
value: bool,
|
||||||
},
|
},
|
||||||
|
/// `'null'`
|
||||||
|
Null {
|
||||||
|
pos: Pos,
|
||||||
|
},
|
||||||
/// `'idk'`
|
/// `'idk'`
|
||||||
Idk {
|
Idk {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
},
|
},
|
||||||
|
/// `'die'`
|
||||||
|
Die {
|
||||||
|
pos: Pos,
|
||||||
|
},
|
||||||
/// `'@' Ident List('(', ',', ')', Expr)`
|
/// `'@' Ident List('(', ',', ')', Expr)`
|
||||||
Directive {
|
Directive {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
|
@ -856,7 +936,7 @@ generate_expr! {
|
||||||
impl Expr<'_> {
|
impl Expr<'_> {
|
||||||
pub fn declares(&self, iden: Result<Ident, &str>, source: &str) -> Option<Ident> {
|
pub fn declares(&self, iden: Result<Ident, &str>, source: &str) -> Option<Ident> {
|
||||||
match *self {
|
match *self {
|
||||||
Self::Ident { id, .. } if iden == Ok(id) || iden == Err(&source[ident::range(id)]) => {
|
Self::Ident { id, .. } if iden == Ok(id) || iden == Err(&source[id.range()]) => {
|
||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
Self::Ctor { fields, .. } => fields.iter().find_map(|f| f.value.declares(iden, source)),
|
Self::Ctor { fields, .. } => fields.iter().find_map(|f| f.value.declares(iden, source)),
|
||||||
|
@ -982,13 +1062,25 @@ impl core::fmt::Display for Display<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ParserCtx {
|
pub struct Ctx {
|
||||||
symbols: Symbols,
|
pub errors: RefCell<String>,
|
||||||
|
symbols: Vec<Symbol>,
|
||||||
stack: StackAlloc,
|
stack: StackAlloc,
|
||||||
idents: Vec<ScopeIdent>,
|
idents: Vec<ScopeIdent>,
|
||||||
captured: Vec<Ident>,
|
captured: Vec<Ident>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Ctx {
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.errors.get_mut().clear();
|
||||||
|
|
||||||
|
debug_assert_eq!(self.symbols.len(), 0);
|
||||||
|
debug_assert_eq!(self.stack.len, 0);
|
||||||
|
debug_assert_eq!(self.idents.len(), 0);
|
||||||
|
debug_assert_eq!(self.captured.len(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct AstInner<T: ?Sized> {
|
pub struct AstInner<T: ?Sized> {
|
||||||
ref_count: AtomicUsize,
|
ref_count: AtomicUsize,
|
||||||
|
@ -1008,12 +1100,12 @@ impl AstInner<[Symbol]> {
|
||||||
.0
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(file: Box<str>, path: &str, ctx: &mut ParserCtx, loader: Loader) -> NonNull<Self> {
|
fn new(file: Box<str>, path: Box<str>, ctx: &mut Ctx, loader: Loader) -> NonNull<Self> {
|
||||||
let arena = Arena::with_capacity(
|
let arena = Arena::with_capacity(
|
||||||
SOURCE_TO_AST_FACTOR * file.bytes().filter(|b| !b.is_ascii_whitespace()).count(),
|
SOURCE_TO_AST_FACTOR * file.bytes().filter(|b| !b.is_ascii_whitespace()).count(),
|
||||||
);
|
);
|
||||||
let exprs =
|
let exprs =
|
||||||
unsafe { core::mem::transmute(Parser::parse(ctx, &file, path, loader, &arena)) };
|
unsafe { core::mem::transmute(Parser::parse(ctx, &file, &path, loader, &arena)) };
|
||||||
|
|
||||||
crate::quad_sort(&mut ctx.symbols, |a, b| a.name.cmp(&b.name));
|
crate::quad_sort(&mut ctx.symbols, |a, b| a.name.cmp(&b.name));
|
||||||
|
|
||||||
|
@ -1027,13 +1119,14 @@ impl AstInner<[Symbol]> {
|
||||||
ref_count: AtomicUsize::new(1),
|
ref_count: AtomicUsize::new(1),
|
||||||
mem: arena.chunk.into_inner(),
|
mem: arena.chunk.into_inner(),
|
||||||
exprs,
|
exprs,
|
||||||
path: path.into(),
|
path,
|
||||||
file,
|
file,
|
||||||
symbols: (),
|
symbols: (),
|
||||||
});
|
});
|
||||||
core::ptr::addr_of_mut!((*inner).symbols)
|
core::ptr::addr_of_mut!((*inner).symbols)
|
||||||
.as_mut_ptr()
|
.as_mut_ptr()
|
||||||
.copy_from_nonoverlapping(ctx.symbols.as_ptr(), ctx.symbols.len());
|
.copy_from_nonoverlapping(ctx.symbols.as_ptr(), ctx.symbols.len());
|
||||||
|
ctx.symbols.clear();
|
||||||
|
|
||||||
NonNull::new_unchecked(inner)
|
NonNull::new_unchecked(inner)
|
||||||
}
|
}
|
||||||
|
@ -1074,18 +1167,35 @@ fn report_to(file: &str, path: &str, pos: Pos, msg: &dyn fmt::Display, out: &mut
|
||||||
|
|
||||||
let line = &file[file[..pos as usize].rfind('\n').map_or(0, |i| i + 1)
|
let line = &file[file[..pos as usize].rfind('\n').map_or(0, |i| i + 1)
|
||||||
..file[pos as usize..].find('\n').map_or(file.len(), |i| i + pos as usize)];
|
..file[pos as usize..].find('\n').map_or(file.len(), |i| i + pos as usize)];
|
||||||
col += line.matches('\t').count() * 3;
|
col += line.chars().take_while(|c| c.is_whitespace()).filter(|&c| c == '\t').count() * 3;
|
||||||
|
|
||||||
_ = writeln!(out, "{}", line.replace("\t", " "));
|
let mut has_non_whitespace = false;
|
||||||
_ = writeln!(out, "{}^", " ".repeat(col - 1));
|
for char in line.chars() {
|
||||||
|
if char == '\t' && !has_non_whitespace {
|
||||||
|
_ = out.write_str(" ");
|
||||||
|
} else {
|
||||||
|
_ = out.write_char(char);
|
||||||
|
}
|
||||||
|
has_non_whitespace |= !char.is_whitespace();
|
||||||
|
}
|
||||||
|
_ = out.write_char('\n');
|
||||||
|
for _ in 0..col - 1 {
|
||||||
|
_ = out.write_str(" ");
|
||||||
|
}
|
||||||
|
_ = out.write_str("^\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash)]
|
#[derive(PartialEq, Eq, Hash)]
|
||||||
pub struct Ast(NonNull<AstInner<[Symbol]>>);
|
pub struct Ast(NonNull<AstInner<[Symbol]>>);
|
||||||
|
|
||||||
impl Ast {
|
impl Ast {
|
||||||
pub fn new(path: &str, content: String, ctx: &mut ParserCtx, loader: Loader) -> Self {
|
pub fn new(
|
||||||
Self(AstInner::new(content.into(), path, ctx, loader))
|
path: impl Into<Box<str>>,
|
||||||
|
content: impl Into<Box<str>>,
|
||||||
|
ctx: &mut Ctx,
|
||||||
|
loader: Loader,
|
||||||
|
) -> Self {
|
||||||
|
Self(AstInner::new(content.into(), path.into(), ctx, loader))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exprs(&self) -> &[Expr] {
|
pub fn exprs(&self) -> &[Expr] {
|
||||||
|
@ -1106,13 +1216,13 @@ impl Ast {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ident_str(&self, ident: Ident) -> &str {
|
pub fn ident_str(&self, ident: Ident) -> &str {
|
||||||
&self.file[ident::range(ident)]
|
&self.file[ident.range()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Ast {
|
impl Default for Ast {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(AstInner::new("".into(), "", &mut ParserCtx::default(), &mut no_loader))
|
Self(AstInner::new("".into(), "".into(), &mut Ctx::default(), &mut no_loader))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1125,12 +1235,12 @@ impl ExprRef {
|
||||||
Self(NonNull::from(expr).cast())
|
Self(NonNull::from(expr).cast())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<'a>(&self, from: &'a Ast) -> Option<&'a Expr<'a>> {
|
pub fn get<'a>(&self, from: &'a Ast) -> &'a Expr<'a> {
|
||||||
from.mem.contains(self.0.as_ptr() as _).then_some(())?;
|
assert!(from.mem.contains(self.0.as_ptr() as _));
|
||||||
// SAFETY: the pointer is or was a valid reference in the past, if it points within one of
|
// SAFETY: the pointer is or was a valid reference in the past, if it points within one of
|
||||||
// arenas regions, it muts be walid, since arena does not give invalid pointers to its
|
// arenas regions, it muts be walid, since arena does not give invalid pointers to its
|
||||||
// allocations
|
// allocations
|
||||||
Some(unsafe { { self.0 }.as_ref() })
|
unsafe { { self.0 }.as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dangling() -> Self {
|
pub fn dangling() -> Self {
|
||||||
|
@ -1321,6 +1431,15 @@ impl Arena {
|
||||||
|
|
||||||
chunk.alloc(layout).unwrap()
|
chunk.alloc(layout).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
let size = self.chunk.get_mut().size();
|
||||||
|
if self.chunk.get_mut().next().is_some() {
|
||||||
|
self.chunk = ArenaChunk::new(size + 1024, Default::default()).into();
|
||||||
|
} else {
|
||||||
|
self.chunk.get_mut().reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ArenaChunk {
|
pub struct ArenaChunk {
|
||||||
|
@ -1379,6 +1498,10 @@ impl ArenaChunk {
|
||||||
pub fn size(&self) -> usize {
|
pub fn size(&self) -> usize {
|
||||||
self.base as usize + self.size - self.end as usize + self.next().map_or(0, Self::size)
|
self.base as usize + self.size - self.end as usize + self.next().map_or(0, Self::size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reset(&mut self) {
|
||||||
|
self.end = unsafe { self.base.add(self.size) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ArenaChunk {
|
impl Drop for ArenaChunk {
|
||||||
|
|
150
lang/src/regalloc.rs
Normal file
150
lang/src/regalloc.rs
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
use {crate::reg::Reg, alloc::vec::Vec, core::ops::Range};
|
||||||
|
|
||||||
|
type Nid = u16;
|
||||||
|
|
||||||
|
pub trait Ctx {
|
||||||
|
fn uses_of(&self, nid: Nid) -> impl Iterator<Item = Nid>;
|
||||||
|
fn params_of(&self, nid: Nid) -> impl Iterator<Item = Nid>;
|
||||||
|
fn args_of(&self, nid: Nid) -> impl Iterator<Item = Nid>;
|
||||||
|
fn dom_of(&self, nid: Nid) -> Nid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Env<'a, C: Ctx> {
|
||||||
|
ctx: &'a C,
|
||||||
|
func: &'a Func,
|
||||||
|
res: &'a mut Res,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, C: Ctx> Env<'a, C> {
|
||||||
|
pub fn new(ctx: &'a C, func: &'a Func, res: &'a mut Res) -> Self {
|
||||||
|
Self { ctx, func, res }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self) {
|
||||||
|
self.res.reg_to_node.clear();
|
||||||
|
self.res.reg_to_node.resize(self.func.instrs.len(), 0);
|
||||||
|
|
||||||
|
let mut bundle = Bundle::new(self.func.instrs.len());
|
||||||
|
for &inst in &self.func.instrs {
|
||||||
|
for uinst in self.ctx.uses_of(inst) {
|
||||||
|
let mut cursor = self.ctx.dom_of(uinst);
|
||||||
|
while cursor != self.ctx.dom_of(inst) {
|
||||||
|
let mut range = self.func.blocks
|
||||||
|
[self.func.id_to_block[cursor as usize] as usize]
|
||||||
|
.range
|
||||||
|
.clone();
|
||||||
|
range.start = range.start.max(inst as usize);
|
||||||
|
range.end = range.end.min(uinst as usize);
|
||||||
|
bundle.add(range);
|
||||||
|
cursor = self.ctx.dom_of(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.res.bundles.iter_mut().enumerate().find(|(_, b)| !b.overlaps(&bundle)) {
|
||||||
|
Some((i, other)) => {
|
||||||
|
other.merge(&bundle);
|
||||||
|
bundle.clear();
|
||||||
|
self.res.reg_to_node[inst as usize] = i as Reg;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.res.reg_to_node[inst as usize] = self.res.bundles.len() as Reg;
|
||||||
|
self.res.bundles.push(bundle);
|
||||||
|
bundle = Bundle::new(self.func.instrs.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Res {
|
||||||
|
bundles: Vec<Bundle>,
|
||||||
|
pub reg_to_node: Vec<Reg>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Bundle {
|
||||||
|
//unit_range: Range<usize>,
|
||||||
|
//set: BitSet,
|
||||||
|
taken: Vec<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bundle {
|
||||||
|
fn new(size: usize) -> Self {
|
||||||
|
Self { taken: vec![false; size] }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(&mut self, range: Range<usize>) {
|
||||||
|
self.taken[range].fill(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn overlaps(&self, other: &Self) -> bool {
|
||||||
|
self.taken.iter().zip(other.taken.iter()).any(|(a, b)| a & b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge(&mut self, other: &Self) {
|
||||||
|
debug_assert!(!self.overlaps(other));
|
||||||
|
self.taken.iter_mut().zip(other.taken.iter()).for_each(|(a, b)| *a = *b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.taken.fill(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//fn overlaps(&self, other: &Self) -> bool {
|
||||||
|
// if self.unit_range.start >= other.unit_range.end
|
||||||
|
// || self.unit_range.end <= other.unit_range.start
|
||||||
|
// {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let [mut a, mut b] = [self, other];
|
||||||
|
// if a.unit_range.start > b.unit_range.start {
|
||||||
|
// mem::swap(&mut a, &mut b);
|
||||||
|
// }
|
||||||
|
// let [mut tmp_a, mut tmp_b] = [0; 2];
|
||||||
|
// let [units_a, units_b] = [a.set.units(&mut tmp_a), b.set.units(&mut tmp_b)];
|
||||||
|
// let len = a.unit_range.len().min(b.unit_range.len());
|
||||||
|
// let [units_a, units_b] =
|
||||||
|
// [&units_a[b.unit_range.start - a.unit_range.start..][..len], &units_b[..len]];
|
||||||
|
// units_a.iter().zip(units_b).any(|(&a, &b)| a & b != 0)
|
||||||
|
//}
|
||||||
|
|
||||||
|
//fn merge(mut self, mut other: Self) -> Self {
|
||||||
|
// debug_assert!(!self.overlaps(&other));
|
||||||
|
|
||||||
|
// if self.unit_range.start > other.unit_range.start {
|
||||||
|
// mem::swap(&mut self, &mut other);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let final_range = self.unit_range.start..self.unit_range.end.max(other.unit_range.end);
|
||||||
|
|
||||||
|
// self.set.reserve(final_range.len());
|
||||||
|
|
||||||
|
// let mut tmp = 0;
|
||||||
|
// let other_units = other.set.units(&mut tmp);
|
||||||
|
|
||||||
|
// match self.set.units_mut() {
|
||||||
|
// Ok(units) => {
|
||||||
|
// units[other.unit_range.start - self.unit_range.start..]
|
||||||
|
// .iter_mut()
|
||||||
|
// .zip(other_units)
|
||||||
|
// .for_each(|(a, b)| *a |= b);
|
||||||
|
// }
|
||||||
|
// Err(view) => view.add_mask(tmp),
|
||||||
|
// }
|
||||||
|
|
||||||
|
// self
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Func {
|
||||||
|
pub blocks: Vec<Block>,
|
||||||
|
pub instrs: Vec<Nid>,
|
||||||
|
pub id_to_instr: Vec<Nid>,
|
||||||
|
pub id_to_block: Vec<Nid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Block {
|
||||||
|
pub range: Range<usize>,
|
||||||
|
pub start_id: Nid,
|
||||||
|
pub eld_id: Nid,
|
||||||
|
}
|
5148
lang/src/son.rs
5148
lang/src/son.rs
File diff suppressed because it is too large
Load diff
1763
lang/src/son/hbvm.rs
Normal file
1763
lang/src/son/hbvm.rs
Normal file
File diff suppressed because it is too large
Load diff
528
lang/src/utils.rs
Normal file
528
lang/src/utils.rs
Normal file
|
@ -0,0 +1,528 @@
|
||||||
|
#![expect(dead_code)]
|
||||||
|
use {
|
||||||
|
alloc::alloc,
|
||||||
|
core::{
|
||||||
|
alloc::Layout,
|
||||||
|
fmt::Debug,
|
||||||
|
hint::unreachable_unchecked,
|
||||||
|
mem::MaybeUninit,
|
||||||
|
ops::{Deref, DerefMut, Not},
|
||||||
|
ptr::Unique,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
type Nid = u16;
|
||||||
|
|
||||||
|
pub union BitSet {
|
||||||
|
inline: usize,
|
||||||
|
alloced: Unique<AllocedBitSet>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for BitSet {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_list().entries(self.iter()).finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for BitSet {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
if self.is_inline() {
|
||||||
|
Self { inline: unsafe { self.inline } }
|
||||||
|
} else {
|
||||||
|
let (data, _) = self.data_and_len();
|
||||||
|
let (layout, _) = Self::layout(data.len());
|
||||||
|
unsafe {
|
||||||
|
let ptr = alloc::alloc(layout);
|
||||||
|
ptr.copy_from_nonoverlapping(self.alloced.as_ptr() as _, layout.size());
|
||||||
|
Self { alloced: Unique::new_unchecked(ptr as _) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for BitSet {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.is_inline() {
|
||||||
|
unsafe {
|
||||||
|
let cap = self.alloced.as_ref().cap;
|
||||||
|
alloc::dealloc(self.alloced.as_ptr() as _, Self::layout(cap).0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BitSet {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { inline: Self::FLAG }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitSet {
|
||||||
|
const FLAG: usize = 1 << (Self::UNIT - 1);
|
||||||
|
const INLINE_ELEMS: usize = Self::UNIT - 1;
|
||||||
|
const UNIT: usize = core::mem::size_of::<usize>() * 8;
|
||||||
|
|
||||||
|
fn is_inline(&self) -> bool {
|
||||||
|
unsafe { self.inline & Self::FLAG != 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_and_len(&self) -> (&[usize], usize) {
|
||||||
|
unsafe {
|
||||||
|
if self.is_inline() {
|
||||||
|
(core::slice::from_ref(&self.inline), Self::INLINE_ELEMS)
|
||||||
|
} else {
|
||||||
|
let small_vec = self.alloced.as_ref();
|
||||||
|
(
|
||||||
|
core::slice::from_raw_parts(
|
||||||
|
&small_vec.data as *const _ as *const usize,
|
||||||
|
small_vec.cap,
|
||||||
|
),
|
||||||
|
small_vec.cap * core::mem::size_of::<usize>() * 8,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn data_mut_and_len(&mut self) -> (&mut [usize], usize) {
|
||||||
|
unsafe {
|
||||||
|
if self.is_inline() {
|
||||||
|
(core::slice::from_mut(&mut self.inline), INLINE_ELEMS)
|
||||||
|
} else {
|
||||||
|
let small_vec = self.alloced.as_mut();
|
||||||
|
(
|
||||||
|
core::slice::from_raw_parts_mut(
|
||||||
|
&mut small_vec.data as *mut _ as *mut usize,
|
||||||
|
small_vec.cap,
|
||||||
|
),
|
||||||
|
small_vec.cap * Self::UNIT,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn indexes(index: usize) -> (usize, usize) {
|
||||||
|
(index / Self::UNIT, index % Self::UNIT)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, index: Nid) -> bool {
|
||||||
|
let index = index as usize;
|
||||||
|
let (data, len) = self.data_and_len();
|
||||||
|
if index >= len {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let (elem, bit) = Self::indexes(index);
|
||||||
|
(unsafe { *data.get_unchecked(elem) }) & (1 << bit) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, index: Nid) -> bool {
|
||||||
|
let index = index as usize;
|
||||||
|
let (mut data, len) = self.data_mut_and_len();
|
||||||
|
if core::intrinsics::unlikely(index >= len) {
|
||||||
|
self.grow(index.next_power_of_two().max(4 * Self::UNIT));
|
||||||
|
(data, _) = self.data_mut_and_len();
|
||||||
|
}
|
||||||
|
|
||||||
|
let (elem, bit) = Self::indexes(index);
|
||||||
|
let elem = unsafe { data.get_unchecked_mut(elem) };
|
||||||
|
let prev = *elem;
|
||||||
|
*elem |= 1 << bit;
|
||||||
|
*elem != prev
|
||||||
|
}
|
||||||
|
|
||||||
|
fn grow(&mut self, size: usize) {
|
||||||
|
debug_assert!(size.is_power_of_two());
|
||||||
|
let slot_count = size / Self::UNIT;
|
||||||
|
let (layout, off) = Self::layout(slot_count);
|
||||||
|
let (ptr, prev_len) = unsafe {
|
||||||
|
if self.is_inline() {
|
||||||
|
let ptr = alloc::alloc(layout);
|
||||||
|
*ptr.add(off).cast::<usize>() = self.inline & !Self::FLAG;
|
||||||
|
(ptr, 1)
|
||||||
|
} else {
|
||||||
|
let prev_len = self.alloced.as_ref().cap;
|
||||||
|
let (prev_layout, _) = Self::layout(prev_len);
|
||||||
|
(alloc::realloc(self.alloced.as_ptr() as _, prev_layout, layout.size()), prev_len)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
MaybeUninit::fill(
|
||||||
|
core::slice::from_raw_parts_mut(
|
||||||
|
ptr.add(off).cast::<MaybeUninit<usize>>().add(prev_len),
|
||||||
|
slot_count - prev_len,
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
*ptr.cast::<usize>() = slot_count;
|
||||||
|
core::ptr::write(self, Self { alloced: Unique::new_unchecked(ptr as _) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(slot_count: usize) -> (core::alloc::Layout, usize) {
|
||||||
|
unsafe {
|
||||||
|
core::alloc::Layout::new::<AllocedBitSet>()
|
||||||
|
.extend(Layout::array::<usize>(slot_count).unwrap_unchecked())
|
||||||
|
.unwrap_unchecked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> BitSetIter {
|
||||||
|
if self.is_inline() {
|
||||||
|
BitSetIter { index: 0, current: unsafe { self.inline & !Self::FLAG }, remining: &[] }
|
||||||
|
} else {
|
||||||
|
let &[current, ref remining @ ..] = self.data_and_len().0 else {
|
||||||
|
unsafe { unreachable_unchecked() }
|
||||||
|
};
|
||||||
|
BitSetIter { index: 0, current, remining }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self, len: usize) {
|
||||||
|
self.reserve(len);
|
||||||
|
if self.is_inline() {
|
||||||
|
unsafe { self.inline &= Self::FLAG };
|
||||||
|
} else {
|
||||||
|
self.data_mut_and_len().0.fill(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn units<'a>(&'a self, slot: &'a mut usize) -> &'a [usize] {
|
||||||
|
if self.is_inline() {
|
||||||
|
*slot = unsafe { self.inline } & !Self::FLAG;
|
||||||
|
core::slice::from_ref(slot)
|
||||||
|
} else {
|
||||||
|
self.data_and_len().0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reserve(&mut self, len: usize) {
|
||||||
|
if len > self.data_and_len().1 {
|
||||||
|
self.grow(len.next_power_of_two().max(4 * Self::UNIT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn units_mut(&mut self) -> Result<&mut [usize], &mut InlineBitSetView> {
|
||||||
|
if self.is_inline() {
|
||||||
|
Err(unsafe {
|
||||||
|
core::mem::transmute::<&mut usize, &mut InlineBitSetView>(&mut self.inline)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Ok(self.data_mut_and_len().0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InlineBitSetView(usize);
|
||||||
|
|
||||||
|
impl InlineBitSetView {
|
||||||
|
pub(crate) fn add_mask(&mut self, tmp: usize) {
|
||||||
|
debug_assert!(tmp & BitSet::FLAG == 0);
|
||||||
|
self.0 |= tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BitSetIter<'a> {
|
||||||
|
index: usize,
|
||||||
|
current: usize,
|
||||||
|
remining: &'a [usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for BitSetIter<'_> {
|
||||||
|
type Item = usize;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
while self.current == 0 {
|
||||||
|
self.current = *self.remining.take_first()?;
|
||||||
|
self.index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sub_idx = self.current.trailing_zeros() as usize;
|
||||||
|
self.current &= self.current - 1;
|
||||||
|
Some(self.index * BitSet::UNIT + sub_idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AllocedBitSet {
|
||||||
|
cap: usize,
|
||||||
|
data: [usize; 0],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[test]
|
||||||
|
fn test_small_bit_set() {
|
||||||
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
let mut sv = BitSet::default();
|
||||||
|
|
||||||
|
sv.set(10);
|
||||||
|
debug_assert!(sv.get(10));
|
||||||
|
sv.set(100);
|
||||||
|
debug_assert!(sv.get(100));
|
||||||
|
sv.set(10000);
|
||||||
|
debug_assert!(sv.get(10000));
|
||||||
|
debug_assert_eq!(sv.iter().collect::<Vec<_>>(), &[10, 100, 10000]);
|
||||||
|
sv.clear(10000);
|
||||||
|
debug_assert_eq!(sv.iter().collect::<Vec<_>>(), &[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub union Vc {
|
||||||
|
inline: InlineVc,
|
||||||
|
alloced: AllocedVc,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Vc {
|
||||||
|
fn default() -> Self {
|
||||||
|
Vc { inline: InlineVc { elems: MaybeUninit::uninit(), cap: Default::default() } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Vc {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
self.as_slice().fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromIterator<Nid> for Vc {
|
||||||
|
fn from_iter<T: IntoIterator<Item = Nid>>(iter: T) -> Self {
|
||||||
|
let mut slf = Self::default();
|
||||||
|
for i in iter {
|
||||||
|
slf.push(i);
|
||||||
|
}
|
||||||
|
slf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const INLINE_ELEMS: usize = VC_SIZE / 2 - 1;
|
||||||
|
const VC_SIZE: usize = 16;
|
||||||
|
|
||||||
|
impl Vc {
|
||||||
|
fn is_inline(&self) -> bool {
|
||||||
|
unsafe { self.inline.cap <= INLINE_ELEMS as Nid }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(&self) -> Option<core::alloc::Layout> {
|
||||||
|
unsafe {
|
||||||
|
self.is_inline().not().then(|| {
|
||||||
|
core::alloc::Layout::array::<Nid>(self.alloced.cap as _).unwrap_unchecked()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
if self.is_inline() {
|
||||||
|
self.inline.cap as _
|
||||||
|
} else {
|
||||||
|
self.alloced.len as _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len_mut(&mut self) -> &mut Nid {
|
||||||
|
unsafe {
|
||||||
|
if self.is_inline() {
|
||||||
|
&mut self.inline.cap
|
||||||
|
} else {
|
||||||
|
&mut self.alloced.len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_ptr(&self) -> *const Nid {
|
||||||
|
unsafe {
|
||||||
|
match self.is_inline() {
|
||||||
|
true => self.inline.elems.as_ptr().cast(),
|
||||||
|
false => self.alloced.base.as_ptr(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_mut_ptr(&mut self) -> *mut Nid {
|
||||||
|
unsafe {
|
||||||
|
match self.is_inline() {
|
||||||
|
true => self.inline.elems.as_mut_ptr().cast(),
|
||||||
|
false => self.alloced.base.as_ptr(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice(&self) -> &[Nid] {
|
||||||
|
unsafe { core::slice::from_raw_parts(self.as_ptr(), self.len()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_slice_mut(&mut self) -> &mut [Nid] {
|
||||||
|
unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, value: Nid) {
|
||||||
|
if let Some(layout) = self.layout()
|
||||||
|
&& unsafe { self.alloced.len == self.alloced.cap }
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
self.alloced.cap *= 2;
|
||||||
|
self.alloced.base = Unique::new_unchecked(
|
||||||
|
alloc::realloc(
|
||||||
|
self.alloced.base.as_ptr().cast(),
|
||||||
|
layout,
|
||||||
|
self.alloced.cap as usize * core::mem::size_of::<Nid>(),
|
||||||
|
)
|
||||||
|
.cast(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if self.len() == INLINE_ELEMS {
|
||||||
|
unsafe {
|
||||||
|
let mut allcd =
|
||||||
|
Self::alloc((self.inline.cap + 1).next_power_of_two() as _, self.len());
|
||||||
|
core::ptr::copy_nonoverlapping(self.as_ptr(), allcd.as_mut_ptr(), self.len());
|
||||||
|
*self = allcd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
*self.len_mut() += 1;
|
||||||
|
self.as_mut_ptr().add(self.len() - 1).write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn alloc(cap: usize, len: usize) -> Self {
|
||||||
|
debug_assert!(cap > INLINE_ELEMS);
|
||||||
|
let layout = unsafe { core::alloc::Layout::array::<Nid>(cap).unwrap_unchecked() };
|
||||||
|
let alloc = unsafe { alloc::alloc(layout) };
|
||||||
|
unsafe {
|
||||||
|
Vc {
|
||||||
|
alloced: AllocedVc {
|
||||||
|
base: Unique::new_unchecked(alloc.cast()),
|
||||||
|
len: len as _,
|
||||||
|
cap: cap as _,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn swap_remove(&mut self, index: usize) {
|
||||||
|
let len = self.len() - 1;
|
||||||
|
self.as_slice_mut().swap(index, len);
|
||||||
|
*self.len_mut() -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, index: usize) {
|
||||||
|
self.as_slice_mut().copy_within(index + 1.., index);
|
||||||
|
*self.len_mut() -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Vc {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Some(layout) = self.layout() {
|
||||||
|
unsafe {
|
||||||
|
alloc::dealloc(self.alloced.base.as_ptr().cast(), layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Vc {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
self.as_slice().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoIterator for Vc {
|
||||||
|
type IntoIter = VcIntoIter;
|
||||||
|
type Item = Nid;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
VcIntoIter { start: 0, end: self.len(), vc: self }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VcIntoIter {
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
vc: Vc,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for VcIntoIter {
|
||||||
|
type Item = Nid;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.start == self.end {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ret = unsafe { core::ptr::read(self.vc.as_slice().get_unchecked(self.start)) };
|
||||||
|
self.start += 1;
|
||||||
|
Some(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let len = self.end - self.start;
|
||||||
|
(len, Some(len))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DoubleEndedIterator for VcIntoIter {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.start == self.end {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.end -= 1;
|
||||||
|
Some(unsafe { core::ptr::read(self.vc.as_slice().get_unchecked(self.end)) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExactSizeIterator for VcIntoIter {}
|
||||||
|
|
||||||
|
impl<const SIZE: usize> From<[Nid; SIZE]> for Vc {
|
||||||
|
fn from(value: [Nid; SIZE]) -> Self {
|
||||||
|
value.as_slice().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a [Nid]> for Vc {
|
||||||
|
fn from(value: &'a [Nid]) -> Self {
|
||||||
|
if value.len() <= INLINE_ELEMS {
|
||||||
|
let mut dflt = Self::default();
|
||||||
|
unsafe {
|
||||||
|
core::ptr::copy_nonoverlapping(value.as_ptr(), dflt.as_mut_ptr(), value.len())
|
||||||
|
};
|
||||||
|
dflt.inline.cap = value.len() as _;
|
||||||
|
dflt
|
||||||
|
} else {
|
||||||
|
let mut allcd = unsafe { Self::alloc(value.len(), value.len()) };
|
||||||
|
unsafe {
|
||||||
|
core::ptr::copy_nonoverlapping(value.as_ptr(), allcd.as_mut_ptr(), value.len())
|
||||||
|
};
|
||||||
|
allcd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Vc {
|
||||||
|
type Target = [Nid];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
self.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Vc {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
self.as_slice_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct InlineVc {
|
||||||
|
cap: Nid,
|
||||||
|
elems: MaybeUninit<[Nid; INLINE_ELEMS]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct AllocedVc {
|
||||||
|
cap: Nid,
|
||||||
|
len: Nid,
|
||||||
|
base: Unique<Nid>,
|
||||||
|
}
|
292
lang/src/vc.rs
292
lang/src/vc.rs
|
@ -1,292 +0,0 @@
|
||||||
use {
|
|
||||||
alloc::vec::Vec,
|
|
||||||
core::{
|
|
||||||
fmt::Debug,
|
|
||||||
mem::MaybeUninit,
|
|
||||||
ops::{Deref, DerefMut, Not},
|
|
||||||
ptr::Unique,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
type Nid = u16;
|
|
||||||
|
|
||||||
const VC_SIZE: usize = 16;
|
|
||||||
const INLINE_ELEMS: usize = VC_SIZE / 2 - 1;
|
|
||||||
|
|
||||||
pub union Vc {
|
|
||||||
inline: InlineVc,
|
|
||||||
alloced: AllocedVc,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Vc {
|
|
||||||
fn default() -> Self {
|
|
||||||
Vc { inline: InlineVc { elems: MaybeUninit::uninit(), cap: Default::default() } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Vc {
|
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
||||||
self.as_slice().fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Vc {
|
|
||||||
fn is_inline(&self) -> bool {
|
|
||||||
unsafe { self.inline.cap <= INLINE_ELEMS as Nid }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(&self) -> Option<core::alloc::Layout> {
|
|
||||||
unsafe {
|
|
||||||
self.is_inline().not().then(|| {
|
|
||||||
core::alloc::Layout::array::<Nid>(self.alloced.cap as _).unwrap_unchecked()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
unsafe {
|
|
||||||
if self.is_inline() {
|
|
||||||
self.inline.cap as _
|
|
||||||
} else {
|
|
||||||
self.alloced.len as _
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn len_mut(&mut self) -> &mut Nid {
|
|
||||||
unsafe {
|
|
||||||
if self.is_inline() {
|
|
||||||
&mut self.inline.cap
|
|
||||||
} else {
|
|
||||||
&mut self.alloced.len
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_ptr(&self) -> *const Nid {
|
|
||||||
unsafe {
|
|
||||||
match self.is_inline() {
|
|
||||||
true => self.inline.elems.as_ptr().cast(),
|
|
||||||
false => self.alloced.base.as_ptr(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_mut_ptr(&mut self) -> *mut Nid {
|
|
||||||
unsafe {
|
|
||||||
match self.is_inline() {
|
|
||||||
true => self.inline.elems.as_mut_ptr().cast(),
|
|
||||||
false => self.alloced.base.as_ptr(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &[Nid] {
|
|
||||||
unsafe { core::slice::from_raw_parts(self.as_ptr(), self.len()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [Nid] {
|
|
||||||
unsafe { core::slice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(&mut self, value: Nid) {
|
|
||||||
if let Some(layout) = self.layout()
|
|
||||||
&& unsafe { self.alloced.len == self.alloced.cap }
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
self.alloced.cap *= 2;
|
|
||||||
self.alloced.base = Unique::new_unchecked(
|
|
||||||
alloc::alloc::realloc(
|
|
||||||
self.alloced.base.as_ptr().cast(),
|
|
||||||
layout,
|
|
||||||
self.alloced.cap as usize * core::mem::size_of::<Nid>(),
|
|
||||||
)
|
|
||||||
.cast(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if self.len() == INLINE_ELEMS {
|
|
||||||
unsafe {
|
|
||||||
let mut allcd =
|
|
||||||
Self::alloc((self.inline.cap + 1).next_power_of_two() as _, self.len());
|
|
||||||
core::ptr::copy_nonoverlapping(self.as_ptr(), allcd.as_mut_ptr(), self.len());
|
|
||||||
*self = allcd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
*self.len_mut() += 1;
|
|
||||||
self.as_mut_ptr().add(self.len() - 1).write(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn alloc(cap: usize, len: usize) -> Self {
|
|
||||||
debug_assert!(cap > INLINE_ELEMS);
|
|
||||||
let layout = unsafe { core::alloc::Layout::array::<Nid>(cap).unwrap_unchecked() };
|
|
||||||
let alloc = unsafe { alloc::alloc::alloc(layout) };
|
|
||||||
unsafe {
|
|
||||||
Vc {
|
|
||||||
alloced: AllocedVc {
|
|
||||||
base: Unique::new_unchecked(alloc.cast()),
|
|
||||||
len: len as _,
|
|
||||||
cap: cap as _,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn swap_remove(&mut self, index: usize) {
|
|
||||||
let len = self.len() - 1;
|
|
||||||
self.as_slice_mut().swap(index, len);
|
|
||||||
*self.len_mut() -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove(&mut self, index: usize) {
|
|
||||||
self.as_slice_mut().copy_within(index + 1.., index);
|
|
||||||
*self.len_mut() -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Vc {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Some(layout) = self.layout() {
|
|
||||||
unsafe {
|
|
||||||
alloc::alloc::dealloc(self.alloced.base.as_ptr().cast(), layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for Vc {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
self.as_slice().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoIterator for Vc {
|
|
||||||
type IntoIter = VcIntoIter;
|
|
||||||
type Item = Nid;
|
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
VcIntoIter { start: 0, end: self.len(), vc: self }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VcIntoIter {
|
|
||||||
start: usize,
|
|
||||||
end: usize,
|
|
||||||
vc: Vc,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for VcIntoIter {
|
|
||||||
type Item = Nid;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.start == self.end {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ret = unsafe { core::ptr::read(self.vc.as_slice().get_unchecked(self.start)) };
|
|
||||||
self.start += 1;
|
|
||||||
Some(ret)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
let len = self.end - self.start;
|
|
||||||
(len, Some(len))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DoubleEndedIterator for VcIntoIter {
|
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
|
||||||
if self.start == self.end {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.end -= 1;
|
|
||||||
Some(unsafe { core::ptr::read(self.vc.as_slice().get_unchecked(self.end)) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExactSizeIterator for VcIntoIter {}
|
|
||||||
|
|
||||||
impl<const SIZE: usize> From<[Nid; SIZE]> for Vc {
|
|
||||||
fn from(value: [Nid; SIZE]) -> Self {
|
|
||||||
value.as_slice().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a [Nid]> for Vc {
|
|
||||||
fn from(value: &'a [Nid]) -> Self {
|
|
||||||
if value.len() <= INLINE_ELEMS {
|
|
||||||
let mut dflt = Self::default();
|
|
||||||
unsafe {
|
|
||||||
core::ptr::copy_nonoverlapping(value.as_ptr(), dflt.as_mut_ptr(), value.len())
|
|
||||||
};
|
|
||||||
dflt.inline.cap = value.len() as _;
|
|
||||||
dflt
|
|
||||||
} else {
|
|
||||||
let mut allcd = unsafe { Self::alloc(value.len(), value.len()) };
|
|
||||||
unsafe {
|
|
||||||
core::ptr::copy_nonoverlapping(value.as_ptr(), allcd.as_mut_ptr(), value.len())
|
|
||||||
};
|
|
||||||
allcd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Vc {
|
|
||||||
type Target = [Nid];
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
if self.as_slice().iter().position(|&i| i == 1) == Some(2) {
|
|
||||||
log::info!("foo {}", std::backtrace::Backtrace::capture());
|
|
||||||
}
|
|
||||||
self.as_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DerefMut for Vc {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
self.as_slice_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
struct InlineVc {
|
|
||||||
cap: Nid,
|
|
||||||
elems: MaybeUninit<[Nid; INLINE_ELEMS]>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
#[repr(C)]
|
|
||||||
struct AllocedVc {
|
|
||||||
cap: Nid,
|
|
||||||
len: Nid,
|
|
||||||
base: Unique<Nid>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct BitSet {
|
|
||||||
data: Vec<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitSet {
|
|
||||||
const ELEM_SIZE: usize = core::mem::size_of::<usize>() * 8;
|
|
||||||
|
|
||||||
pub fn clear(&mut self, bit_size: usize) {
|
|
||||||
let new_len = bit_size.div_ceil(Self::ELEM_SIZE);
|
|
||||||
self.data.clear();
|
|
||||||
self.data.resize(new_len, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[track_caller]
|
|
||||||
pub fn set(&mut self, idx: Nid) -> bool {
|
|
||||||
let idx = idx as usize;
|
|
||||||
let data_idx = idx / Self::ELEM_SIZE;
|
|
||||||
let sub_idx = idx % Self::ELEM_SIZE;
|
|
||||||
let prev = self.data[data_idx] & (1 << sub_idx);
|
|
||||||
self.data[data_idx] |= 1 << sub_idx;
|
|
||||||
prev == 0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
LI64 r32, 10d
|
|
||||||
LI64 r33, 20d
|
|
||||||
LI64 r34, 2d
|
|
||||||
DIRS64 r33, r0, r33, r34
|
|
||||||
SUB64 r32, r32, r33
|
|
||||||
LI64 r33, 4d
|
|
||||||
LI64 r34, 2d
|
|
||||||
ADDI64 r34, r34, 2d
|
|
||||||
MUL64 r33, r33, r34
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
LI64 r33, 4d
|
|
||||||
MULI64 r33, r33, 4d
|
|
||||||
SUB64 r32, r32, r33
|
|
||||||
LI64 r33, 1d
|
|
||||||
SLUI64 r33, r33, 0b
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
LI64 r33, 1d
|
|
||||||
NEG r33, r33
|
|
||||||
ADD64 r1, r32, r33
|
|
||||||
LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 205
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,67 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -76d
|
|
||||||
ST r31, r254, 28a, 48h
|
|
||||||
LI64 r32, 511d
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r254, 0a, 1h
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r254, 1a, 1h
|
|
||||||
CP r33, r32
|
|
||||||
ANDI r33, r33, 255d
|
|
||||||
ST r33, r254, 2a, 1h
|
|
||||||
CP r33, r32
|
|
||||||
SRUI16 r33, r33, 8b
|
|
||||||
ANDI r33, r33, 255d
|
|
||||||
ST r33, r254, 3a, 1h
|
|
||||||
ADDI64 r33, r254, 0d
|
|
||||||
LI64 r34, 1d
|
|
||||||
ST r34, r254, 4a, 8h
|
|
||||||
LI64 r34, 2d
|
|
||||||
ST r34, r254, 12a, 8h
|
|
||||||
LI64 r34, 4d
|
|
||||||
ST r34, r254, 20a, 8h
|
|
||||||
ADDI64 r34, r254, 4d
|
|
||||||
CP r2, r34
|
|
||||||
JAL r31, r0, :pass
|
|
||||||
CP r34, r1
|
|
||||||
ADDI64 r35, r254, 0d
|
|
||||||
LI64 r36, 3d
|
|
||||||
ADD64 r35, r35, r36
|
|
||||||
CP r36, r0
|
|
||||||
LD r36, r35, 0a, 1h
|
|
||||||
SXT8 r36, r36
|
|
||||||
ADD64 r1, r34, r36
|
|
||||||
LD r31, r254, 28a, 48h
|
|
||||||
ADDI64 r254, r254, 76d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
pass:
|
|
||||||
ADDI64 r254, r254, -48d
|
|
||||||
ST r31, r254, 0a, 48h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r32
|
|
||||||
LI64 r34, 0d
|
|
||||||
MULI64 r34, r34, 8d
|
|
||||||
ADD64 r33, r33, r34
|
|
||||||
LD r34, r33, 0a, 8h
|
|
||||||
CP r33, r32
|
|
||||||
LI64 r35, 1d
|
|
||||||
MULI64 r35, r35, 8d
|
|
||||||
ADD64 r33, r33, r35
|
|
||||||
LD r35, r33, 0a, 8h
|
|
||||||
ADD64 r34, r34, r35
|
|
||||||
CP r33, r32
|
|
||||||
CP r35, r32
|
|
||||||
LI64 r36, 1d
|
|
||||||
MULI64 r36, r36, 8d
|
|
||||||
ADD64 r35, r35, r36
|
|
||||||
LD r36, r35, 0a, 8h
|
|
||||||
MULI64 r36, r36, 8d
|
|
||||||
ADD64 r33, r33, r36
|
|
||||||
LD r36, r33, 0a, 8h
|
|
||||||
ADD64 r1, r34, r36
|
|
||||||
LD r31, r254, 0a, 48h
|
|
||||||
ADDI64 r254, r254, 48d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 557
|
|
||||||
ret: 8
|
|
||||||
status: Ok(())
|
|
|
@ -1,36 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -40d
|
|
||||||
ST r31, r254, 0a, 40h
|
|
||||||
LRA r32, r0, :"abඞ\n\r\t56789\0"
|
|
||||||
CP r2, r32
|
|
||||||
JAL r31, r0, :str_len
|
|
||||||
CP r33, r1
|
|
||||||
LRA r34, r0, :"fff\0"
|
|
||||||
CP r2, r34
|
|
||||||
JAL r31, r0, :str_len
|
|
||||||
CP r35, r1
|
|
||||||
ADD64 r1, r35, r33
|
|
||||||
LD r31, r254, 0a, 40h
|
|
||||||
ADDI64 r254, r254, 40d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
str_len:
|
|
||||||
ADDI64 r254, r254, -48d
|
|
||||||
ST r31, r254, 0a, 48h
|
|
||||||
CP r32, r2
|
|
||||||
LI64 r33, 0d
|
|
||||||
2: CP r34, r32
|
|
||||||
CP r35, r0
|
|
||||||
LD r35, r34, 0a, 1h
|
|
||||||
LI64 r36, 0d
|
|
||||||
JNE r35, r36, :0
|
|
||||||
JMP :1
|
|
||||||
0: ADDI64 r33, r33, 1d
|
|
||||||
ADDI64 r32, r32, 1d
|
|
||||||
JMP :2
|
|
||||||
1: CP r1, r33
|
|
||||||
LD r31, r254, 0a, 48h
|
|
||||||
ADDI64 r254, r254, 48d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 270
|
|
||||||
ret: 16
|
|
||||||
status: Ok(())
|
|
|
@ -1,17 +0,0 @@
|
||||||
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
|
|
||||||
JAL r31, r0, :foo
|
|
||||||
LI64 r1, 0d
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 143
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,11 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -16d
|
|
||||||
ST r31, r254, 0a, 16h
|
|
||||||
LRA r32, r0, :a
|
|
||||||
LD r1, r32, 0a, 8h
|
|
||||||
LD r31, r254, 0a, 16h
|
|
||||||
ADDI64 r254, r254, 16d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 95
|
|
||||||
ret: 50
|
|
||||||
status: Ok(())
|
|
|
@ -1,11 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -16d
|
|
||||||
ST r31, r254, 0a, 16h
|
|
||||||
LRA r32, r0, :a
|
|
||||||
LD r1, r32, 0a, 8h
|
|
||||||
LD r31, r254, 0a, 16h
|
|
||||||
ADDI64 r254, r254, 16d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 218
|
|
||||||
ret: 50
|
|
||||||
status: Ok(())
|
|
|
@ -1,57 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -52d
|
|
||||||
ST r31, r254, 12a, 40h
|
|
||||||
LI64 r32, 255d
|
|
||||||
ST r32, r254, 0a, 1h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 1a, 1h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 2a, 1h
|
|
||||||
LI64 r32, 255d
|
|
||||||
ST r32, r254, 3a, 1h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 4a, 4h
|
|
||||||
LI64 r32, 2d
|
|
||||||
ST r32, r254, 8a, 4h
|
|
||||||
LI64 r32, 1d
|
|
||||||
ADDI64 r33, r254, 4d
|
|
||||||
CP r34, r32
|
|
||||||
MULI64 r34, r34, 4d
|
|
||||||
ADD64 r33, r33, r34
|
|
||||||
CP r34, r0
|
|
||||||
LD r34, r33, 0a, 4h
|
|
||||||
LI64 r35, 2d
|
|
||||||
JEQ r34, r35, :0
|
|
||||||
LI64 r1, 0d
|
|
||||||
JMP :1
|
|
||||||
0: ADDI64 r35, r254, 8d
|
|
||||||
ADDI64 r35, r35, -4d
|
|
||||||
CP r34, r0
|
|
||||||
LD r34, r35, 0a, 4h
|
|
||||||
LI64 r33, 0d
|
|
||||||
JEQ r34, r33, :2
|
|
||||||
LI64 r1, 64d
|
|
||||||
JMP :1
|
|
||||||
2: CP r33, r0
|
|
||||||
LD r33, r254, 4a, 4h
|
|
||||||
CP r34, r0
|
|
||||||
LD r34, r254, 8a, 4h
|
|
||||||
ADD32 r33, r33, r34
|
|
||||||
CP r34, r0
|
|
||||||
LD r34, r254, 0a, 1h
|
|
||||||
ADD32 r33, r33, r34
|
|
||||||
CP r34, r0
|
|
||||||
LD r34, r254, 1a, 1h
|
|
||||||
ADD32 r33, r33, r34
|
|
||||||
CP r34, r0
|
|
||||||
LD r34, r254, 2a, 1h
|
|
||||||
ADD32 r33, r33, r34
|
|
||||||
CP r34, r0
|
|
||||||
LD r34, r254, 3a, 1h
|
|
||||||
ADD32 r1, r33, r34
|
|
||||||
1: LD r31, r254, 12a, 40h
|
|
||||||
ADDI64 r254, r254, 52d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 474
|
|
||||||
ret: 512
|
|
||||||
status: Ok(())
|
|
|
@ -1,30 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -96d
|
|
||||||
ST r31, r254, 16a, 80h
|
|
||||||
LI64 r32, 10d
|
|
||||||
LI64 r33, 30d
|
|
||||||
LI64 r34, 40d
|
|
||||||
CP r35, r34
|
|
||||||
LI64 r36, 16d
|
|
||||||
LI64 r37, 8d
|
|
||||||
LI64 r38, 10d
|
|
||||||
LI64 r2, 1d
|
|
||||||
LI64 r39, 10d
|
|
||||||
ST r39, r254, 0a, 8h
|
|
||||||
LI64 r39, 20d
|
|
||||||
ST r39, r254, 8a, 8h
|
|
||||||
LD r3, r254, 0a, 16h
|
|
||||||
LI64 r5, 5d
|
|
||||||
LI64 r6, 6d
|
|
||||||
ECA
|
|
||||||
CP r39, r1
|
|
||||||
LRA r40, r0, :arbitrary text
|
|
||||||
|
|
||||||
LI64 r1, 0d
|
|
||||||
LD r31, r254, 16a, 80h
|
|
||||||
ADDI64 r254, r254, 96d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
ev: Ecall
|
|
||||||
code size: 255
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,74 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -80d
|
|
||||||
ST r31, r254, 0a, 80h
|
|
||||||
JAL r31, r0, :check_platform
|
|
||||||
CP r32, r1
|
|
||||||
LI64 r33, 100d
|
|
||||||
LI64 r34, 30d
|
|
||||||
LI64 r35, 0d
|
|
||||||
LI64 r36, 0d
|
|
||||||
4: CP r37, r35
|
|
||||||
CP r38, r34
|
|
||||||
ADDI64 r38, r38, 1d
|
|
||||||
CMPS r37, r37, r38
|
|
||||||
CMPUI r37, r37, 1d
|
|
||||||
JEQ r37, r0, :0
|
|
||||||
CP r2, r35
|
|
||||||
CP r3, r36
|
|
||||||
CP r4, r33
|
|
||||||
JAL r31, r0, :set_pixel
|
|
||||||
CP r37, r1
|
|
||||||
CP r38, r35
|
|
||||||
ADDI64 r38, r38, 1d
|
|
||||||
CP r35, r38
|
|
||||||
JMP :1
|
|
||||||
0: CP r2, r35
|
|
||||||
CP r3, r36
|
|
||||||
CP r4, r33
|
|
||||||
JAL r31, r0, :set_pixel
|
|
||||||
CP r38, r1
|
|
||||||
LI64 r35, 0d
|
|
||||||
CP r39, r36
|
|
||||||
ADDI64 r39, r39, 1d
|
|
||||||
CP r36, r39
|
|
||||||
1: CP r39, r36
|
|
||||||
CP r40, r33
|
|
||||||
CMPS r39, r39, r40
|
|
||||||
CMPUI r39, r39, 0d
|
|
||||||
NOT r39, r39
|
|
||||||
JEQ r39, r0, :2
|
|
||||||
JMP :3
|
|
||||||
2: JMP :4
|
|
||||||
3: LI64 r1, 0d
|
|
||||||
LD r31, r254, 0a, 80h
|
|
||||||
ADDI64 r254, r254, 80d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
set_pixel:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
CP r34, r4
|
|
||||||
MUL64 r33, r33, r34
|
|
||||||
ADD64 r33, r33, r32
|
|
||||||
LI64 r1, 0d
|
|
||||||
LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
check_platform:
|
|
||||||
ADDI64 r254, r254, -8d
|
|
||||||
ST r31, r254, 0a, 8h
|
|
||||||
JAL r31, r0, :x86_fb_ptr
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
x86_fb_ptr:
|
|
||||||
ADDI64 r254, r254, -8d
|
|
||||||
ST r31, r254, 0a, 8h
|
|
||||||
LI64 r1, 100d
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 511
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,32 +0,0 @@
|
||||||
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
|
|
||||||
LI64 r2, 10d
|
|
||||||
JAL r31, r0, :add_one
|
|
||||||
CP r32, r1
|
|
||||||
LI64 r2, 20d
|
|
||||||
JAL r31, r0, :add_two
|
|
||||||
CP r33, r1
|
|
||||||
ADD64 r1, r32, r33
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 257
|
|
||||||
ret: 33
|
|
||||||
status: Ok(())
|
|
|
@ -1,38 +0,0 @@
|
||||||
add:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
ADD64 r1, r32, r33
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
add:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
ADD32 r1, r32, r33
|
|
||||||
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(())
|
|
|
@ -1,144 +0,0 @@
|
||||||
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 r33, r32
|
|
||||||
CP r1, r33
|
|
||||||
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
|
|
||||||
ADDI64 r1, r254, 0d
|
|
||||||
JAL r31, r0, :new
|
|
||||||
ADDI64 r32, r254, 0d
|
|
||||||
CP r2, r32
|
|
||||||
LI64 r3, 69d
|
|
||||||
JAL r31, r0, :push
|
|
||||||
CP r32, r1
|
|
||||||
LD r32, r254, 0a, 8h
|
|
||||||
LD r33, r32, 0a, 8h
|
|
||||||
ADDI64 r32, r254, 0d
|
|
||||||
CP r2, r32
|
|
||||||
JAL r31, r0, :deinit
|
|
||||||
CP r1, r33
|
|
||||||
LD r31, r254, 24a, 24h
|
|
||||||
ADDI64 r254, r254, 48d
|
|
||||||
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
|
|
||||||
new:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
CP r32, r1
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r32, 0a, 8h
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r32, 8a, 8h
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r32, 16a, 8h
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
push:
|
|
||||||
ADDI64 r254, r254, -80d
|
|
||||||
ST r31, r254, 0a, 80h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
LD r34, r32, 8a, 8h
|
|
||||||
LD r35, r32, 16a, 8h
|
|
||||||
JNE r34, r35, :0
|
|
||||||
LD r35, r32, 16a, 8h
|
|
||||||
LI64 r34, 0d
|
|
||||||
JNE r35, r34, :1
|
|
||||||
LI64 r34, 1d
|
|
||||||
ST r34, r32, 16a, 8h
|
|
||||||
JMP :2
|
|
||||||
1: LD r34, r32, 16a, 8h
|
|
||||||
MULI64 r34, r34, 2d
|
|
||||||
ST r34, r32, 16a, 8h
|
|
||||||
2: LD r34, r32, 16a, 8h
|
|
||||||
MULI64 r34, r34, 8d
|
|
||||||
CP r2, r34
|
|
||||||
LI64 r3, 8d
|
|
||||||
JAL r31, r0, :malloc
|
|
||||||
CP r34, r1
|
|
||||||
LI64 r35, 0d
|
|
||||||
JNE r34, r35, :3
|
|
||||||
LI64 r1, 0d
|
|
||||||
JMP :4
|
|
||||||
3: LD r35, r32, 0a, 8h
|
|
||||||
CP r36, r34
|
|
||||||
LD r37, r32, 0a, 8h
|
|
||||||
LD r38, r32, 8a, 8h
|
|
||||||
MULI64 r38, r38, 8d
|
|
||||||
ADD64 r37, r37, r38
|
|
||||||
7: JNE r35, r37, :5
|
|
||||||
JMP :6
|
|
||||||
5: CP r38, r36
|
|
||||||
CP r39, r35
|
|
||||||
LD r40, r39, 0a, 8h
|
|
||||||
ST r40, r38, 0a, 8h
|
|
||||||
ADDI64 r35, r35, 8d
|
|
||||||
ADDI64 r36, r36, 8d
|
|
||||||
JMP :7
|
|
||||||
6: LD r38, r32, 8a, 8h
|
|
||||||
LI64 r39, 0d
|
|
||||||
JEQ r38, r39, :8
|
|
||||||
LD r2, r32, 0a, 8h
|
|
||||||
LD r39, r32, 8a, 8h
|
|
||||||
MULI64 r39, r39, 8d
|
|
||||||
CP r3, r39
|
|
||||||
LI64 r4, 8d
|
|
||||||
JAL r31, r0, :free
|
|
||||||
8: ST r34, r32, 0a, 8h
|
|
||||||
0: LD r39, r32, 0a, 8h
|
|
||||||
LD r38, r32, 8a, 8h
|
|
||||||
MULI64 r38, r38, 8d
|
|
||||||
ADD64 r39, r39, r38
|
|
||||||
CP r38, r39
|
|
||||||
ST r33, r38, 0a, 8h
|
|
||||||
LD r38, r32, 8a, 8h
|
|
||||||
ADDI64 r38, r38, 1d
|
|
||||||
ST r38, r32, 8a, 8h
|
|
||||||
CP r1, r39
|
|
||||||
4: LD r31, r254, 0a, 80h
|
|
||||||
ADDI64 r254, r254, 80d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 1225
|
|
||||||
ret: 69
|
|
||||||
status: Ok(())
|
|
|
@ -1,16 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
LRA r32, r0, :complex_global_var
|
|
||||||
LRA r33, r0, :complex_global_var
|
|
||||||
LD r34, r33, 0a, 8h
|
|
||||||
ADDI64 r34, r34, 5d
|
|
||||||
ST r34, r32, 0a, 8h
|
|
||||||
LRA r32, r0, :complex_global_var
|
|
||||||
LD r1, r32, 0a, 8h
|
|
||||||
LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 146
|
|
||||||
ret: 55
|
|
||||||
status: Ok(())
|
|
|
@ -1,31 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -56d
|
|
||||||
ST r31, r254, 0a, 56h
|
|
||||||
LI64 r32, 255d
|
|
||||||
LI64 r33, 255d
|
|
||||||
LI64 r34, 255d
|
|
||||||
LI64 r35, 255d
|
|
||||||
CP r36, r32
|
|
||||||
CMPS r36, r36, r33
|
|
||||||
CMPUI r36, r36, 0d
|
|
||||||
NOT r36, r36
|
|
||||||
CP r37, r34
|
|
||||||
CMPS r37, r37, r33
|
|
||||||
CMPUI r37, r37, 0d
|
|
||||||
NOT r37, r37
|
|
||||||
AND r36, r36, r37
|
|
||||||
CP r37, r35
|
|
||||||
CMPS r37, r37, r33
|
|
||||||
CMPUI r37, r37, 0d
|
|
||||||
NOT r37, r37
|
|
||||||
AND r36, r36, r37
|
|
||||||
JEQ r36, r0, :0
|
|
||||||
LI64 r1, 0d
|
|
||||||
JMP :1
|
|
||||||
0: LI64 r1, 1d
|
|
||||||
1: LD r31, r254, 0a, 56h
|
|
||||||
ADDI64 r254, r254, 56d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 208
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,25 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -160d
|
|
||||||
ST r31, r254, 128a, 32h
|
|
||||||
LI64 r32, 0d
|
|
||||||
2: LI64 r33, 128d
|
|
||||||
JLTS r32, r33, :0
|
|
||||||
JMP :1
|
|
||||||
0: ADDI64 r33, r254, 0d
|
|
||||||
CP r34, r32
|
|
||||||
ADD64 r33, r33, r34
|
|
||||||
LI64 r34, 69d
|
|
||||||
ST r34, r33, 0a, 1h
|
|
||||||
ADDI64 r32, r32, 1d
|
|
||||||
JMP :2
|
|
||||||
1: ADDI64 r33, r254, 0d
|
|
||||||
LI64 r34, 42d
|
|
||||||
ADD64 r33, r33, r34
|
|
||||||
CP r1, r0
|
|
||||||
LD r1, r33, 0a, 1h
|
|
||||||
LD r31, r254, 128a, 32h
|
|
||||||
ADDI64 r254, r254, 160d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 195
|
|
||||||
ret: 69
|
|
||||||
status: Ok(())
|
|
|
@ -1,33 +0,0 @@
|
||||||
fib:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
CP r32, r2
|
|
||||||
LI64 r33, 2d
|
|
||||||
JGTS r32, r33, :0
|
|
||||||
LI64 r1, 1d
|
|
||||||
JMP :1
|
|
||||||
0: CP r33, r32
|
|
||||||
ADDI64 r33, r33, -1d
|
|
||||||
CP r2, r33
|
|
||||||
JAL r31, r0, :fib
|
|
||||||
CP r33, r1
|
|
||||||
CP r34, r32
|
|
||||||
ADDI64 r34, r34, -2d
|
|
||||||
CP r2, r34
|
|
||||||
JAL r31, r0, :fib
|
|
||||||
CP r34, r1
|
|
||||||
ADD64 r1, r33, r34
|
|
||||||
1: LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
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: 234
|
|
||||||
ret: 55
|
|
||||||
status: Ok(())
|
|
|
@ -1,13 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
LI64 r33, 1d
|
|
||||||
ADDI64 r33, r33, 2d
|
|
||||||
ADDI64 r32, r33, 3d
|
|
||||||
ADDI64 r1, r32, -6d
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 110
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,162 +0,0 @@
|
||||||
example:
|
|
||||||
ADDI64 r254, r254, -48d
|
|
||||||
ST r31, r254, 0a, 48h
|
|
||||||
LI64 r2, 3d
|
|
||||||
LI64 r3, 4d
|
|
||||||
ECA
|
|
||||||
CP r33, r1
|
|
||||||
LI64 r34, 0d
|
|
||||||
LI64 r35, 0d
|
|
||||||
CMPS r34, r34, r35
|
|
||||||
CMPUI r34, r34, 0d
|
|
||||||
LI64 r35, 1024d
|
|
||||||
LI64 r36, 0d
|
|
||||||
CMPS r35, r35, r36
|
|
||||||
CMPUI r35, r35, 0d
|
|
||||||
OR r34, r34, r35
|
|
||||||
JEQ r34, r0, :0
|
|
||||||
CP r34, r33
|
|
||||||
LI64 r35, 1024d
|
|
||||||
ADDI64 r35, r35, 0d
|
|
||||||
ADDI64 r35, r35, 1d
|
|
||||||
DIRS64 r0, r34, r34, r35
|
|
||||||
ADDI64 r32, r34, 0d
|
|
||||||
JMP :1
|
|
||||||
0: CP r32, r33
|
|
||||||
1: LI64 r2, 0d
|
|
||||||
LI64 r3, 768d
|
|
||||||
JAL r31, r0, :integer
|
|
||||||
CP r33, r1
|
|
||||||
CP r34, r32
|
|
||||||
JMP :2
|
|
||||||
2: LD r31, r254, 0a, 48h
|
|
||||||
ADDI64 r254, r254, 48d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
integer:
|
|
||||||
ADDI64 r254, r254, -56d
|
|
||||||
ST r31, r254, 0a, 56h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
LI64 r2, 3d
|
|
||||||
LI64 r3, 4d
|
|
||||||
ECA
|
|
||||||
CP r34, r1
|
|
||||||
CP r35, r32
|
|
||||||
LI64 r36, 0d
|
|
||||||
CMPS r35, r35, r36
|
|
||||||
CMPUI r35, r35, 0d
|
|
||||||
CP r36, r33
|
|
||||||
LI64 r37, 0d
|
|
||||||
CMPS r36, r36, r37
|
|
||||||
CMPUI r36, r36, 0d
|
|
||||||
OR r35, r35, r36
|
|
||||||
JEQ r35, r0, :0
|
|
||||||
CP r35, r34
|
|
||||||
CP r36, r33
|
|
||||||
SUB64 r36, r36, r32
|
|
||||||
ADDI64 r36, r36, 1d
|
|
||||||
DIRS64 r0, r35, r35, r36
|
|
||||||
ADD64 r1, r35, r32
|
|
||||||
JMP :1
|
|
||||||
0: CP r1, r34
|
|
||||||
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, 0a, 16h
|
|
||||||
ST r4, r254, 16a, 16h
|
|
||||||
ST r6, r254, 32a, 16h
|
|
||||||
CP r32, r8
|
|
||||||
LI64 r33, 1d
|
|
||||||
JEQ r33, r0, :0
|
|
||||||
LD r33, r254, 0a, 8h
|
|
||||||
LD r34, r254, 16a, 8h
|
|
||||||
JGTS r33, r34, :1
|
|
||||||
JMP :1
|
|
||||||
1: JMP :2
|
|
||||||
0: LD r34, r254, 8a, 8h
|
|
||||||
LD r33, r254, 24a, 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, -112d
|
|
||||||
ST r31, r254, 96a, 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, 48a, 8h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 56a, 8h
|
|
||||||
LD r2, r254, 48a, 16h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 64a, 8h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 72a, 8h
|
|
||||||
LD r4, r254, 64a, 16h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 80a, 8h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 88a, 8h
|
|
||||||
LD r6, r254, 80a, 16h
|
|
||||||
LI64 r8, 10d
|
|
||||||
JAL r31, r0, :rect_line
|
|
||||||
JAL r31, r0, :example
|
|
||||||
LI64 r1, 0d
|
|
||||||
LD r31, r254, 96a, 16h
|
|
||||||
ADDI64 r254, r254, 112d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
rect_line:
|
|
||||||
ADDI64 r254, r254, -112d
|
|
||||||
ST r31, r254, 48a, 64h
|
|
||||||
ST r2, r254, 0a, 16h
|
|
||||||
ST r4, r254, 16a, 16h
|
|
||||||
ST r6, r254, 32a, 16h
|
|
||||||
CP r32, r8
|
|
||||||
LI64 r33, 0d
|
|
||||||
LI64 r34, 0d
|
|
||||||
LI64 r35, 0d
|
|
||||||
5: JNE r33, r32, :0
|
|
||||||
JMP :1
|
|
||||||
0: LD r34, r254, 8a, 8h
|
|
||||||
LD r35, r254, 0a, 8h
|
|
||||||
4: LD r36, r254, 8a, 8h
|
|
||||||
LD r37, r254, 16a, 8h
|
|
||||||
ADD64 r36, r36, r37
|
|
||||||
JNE r34, r36, :2
|
|
||||||
JMP :3
|
|
||||||
2: LI64 r36, 1d
|
|
||||||
LI64 r37, 10d
|
|
||||||
ADD64 r36, r36, r37
|
|
||||||
LI64 r37, 1d
|
|
||||||
LI64 r38, 2d
|
|
||||||
ADD64 r36, r37, r38
|
|
||||||
ADDI64 r34, r34, 1d
|
|
||||||
JMP :4
|
|
||||||
3: ADDI64 r33, r33, 1d
|
|
||||||
JMP :5
|
|
||||||
1: LD r31, r254, 48a, 64h
|
|
||||||
ADDI64 r254, r254, 112d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 1403
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,18 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
LI64 r32, 10d
|
|
||||||
NEG r32, r32
|
|
||||||
CP r33, r32
|
|
||||||
LI64 r34, 8d
|
|
||||||
ADDI64 r34, r34, -1d
|
|
||||||
SRS64 r33, r33, r34
|
|
||||||
CP r34, r32
|
|
||||||
XOR r34, r34, r33
|
|
||||||
SUB64 r1, r34, r33
|
|
||||||
LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 119
|
|
||||||
ret: 10
|
|
||||||
status: Ok(())
|
|
|
@ -1,30 +0,0 @@
|
||||||
integer_range:
|
|
||||||
ADDI64 r254, r254, -40d
|
|
||||||
ST r31, r254, 0a, 40h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
LI64 r2, 3d
|
|
||||||
LI64 r3, 4d
|
|
||||||
ECA
|
|
||||||
CP r34, r1
|
|
||||||
CP r35, r33
|
|
||||||
SUB64 r35, r35, r32
|
|
||||||
ADDI64 r35, r35, 1d
|
|
||||||
DIRU64 r0, r34, r34, r35
|
|
||||||
ADD64 r1, r34, r32
|
|
||||||
LD r31, r254, 0a, 40h
|
|
||||||
ADDI64 r254, r254, 40d
|
|
||||||
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: 213
|
|
||||||
ret: 42
|
|
||||||
status: Ok(())
|
|
|
@ -1,30 +0,0 @@
|
||||||
fib:
|
|
||||||
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, -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(())
|
|
|
@ -1,47 +0,0 @@
|
||||||
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, -48d
|
|
||||||
ST r31, r254, 8a, 40h
|
|
||||||
LI64 r32, 1d
|
|
||||||
ST r32, r254, 0a, 8h
|
|
||||||
ADDI64 r32, r254, 0d
|
|
||||||
LI64 r33, 1000d
|
|
||||||
CP r34, r32
|
|
||||||
CP r35, r33
|
|
||||||
MULI64 r35, r35, 8d
|
|
||||||
ADD64 r34, r34, r35
|
|
||||||
ADDI64 r32, r34, -16d
|
|
||||||
CP r34, r33
|
|
||||||
ADDI64 r34, r34, -2d
|
|
||||||
CP r35, r34
|
|
||||||
MULI64 r35, r35, 8d
|
|
||||||
SUB64 r32, r32, r35
|
|
||||||
CP r2, r32
|
|
||||||
JAL r31, r0, :modify
|
|
||||||
LD r2, r254, 0a, 8h
|
|
||||||
JAL r31, r0, :drop
|
|
||||||
CP r34, r32
|
|
||||||
LD r35, r34, 0a, 8h
|
|
||||||
ADDI64 r1, r35, -2d
|
|
||||||
LD r31, r254, 8a, 40h
|
|
||||||
ADDI64 r254, r254, 48d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
modify:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r32
|
|
||||||
LI64 r34, 2d
|
|
||||||
ST r34, r33, 0a, 8h
|
|
||||||
LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 382
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,61 +0,0 @@
|
||||||
create_back_buffer:
|
|
||||||
ADDI64 r254, r254, -40d
|
|
||||||
ST r31, r254, 0a, 40h
|
|
||||||
CP r32, r2
|
|
||||||
LI64 r33, 255d
|
|
||||||
JGTS r32, r33, :0
|
|
||||||
CP r2, r32
|
|
||||||
JAL r31, r0, :request_page
|
|
||||||
JMP :1
|
|
||||||
0: LI64 r2, 255d
|
|
||||||
JAL r31, r0, :request_page
|
|
||||||
CP r33, r1
|
|
||||||
CP r34, r32
|
|
||||||
ADDI64 r34, r34, -255d
|
|
||||||
6: LI64 r35, 0d
|
|
||||||
JGTS r34, r35, :2
|
|
||||||
JMP :3
|
|
||||||
2: LI64 r35, 255d
|
|
||||||
JLTS r34, r35, :4
|
|
||||||
LI64 r2, 255d
|
|
||||||
JAL r31, r0, :request_page
|
|
||||||
CP r35, r1
|
|
||||||
JMP :5
|
|
||||||
4: CP r2, r34
|
|
||||||
JAL r31, r0, :request_page
|
|
||||||
CP r35, r1
|
|
||||||
5: ADDI64 r34, r34, -255d
|
|
||||||
JMP :6
|
|
||||||
3: CP r1, r33
|
|
||||||
1: LD r31, r254, 0a, 40h
|
|
||||||
ADDI64 r254, r254, 40d
|
|
||||||
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, -40d
|
|
||||||
ST r31, r254, 0a, 40h
|
|
||||||
CP r32, r2
|
|
||||||
LRA r33, r0, :"\0\u{1}xxxxxxxx\0"
|
|
||||||
CP r34, r33
|
|
||||||
ADDI64 r34, r34, 1d
|
|
||||||
CP r35, r34
|
|
||||||
ST r32, r35, 0a, 1h
|
|
||||||
LI64 r2, 3d
|
|
||||||
LI64 r3, 2d
|
|
||||||
CP r4, r33
|
|
||||||
LI64 r5, 12d
|
|
||||||
ECA
|
|
||||||
LD r31, r254, 0a, 40h
|
|
||||||
ADDI64 r254, r254, 40d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 449
|
|
||||||
ret: 42
|
|
||||||
status: Ok(())
|
|
|
@ -1,36 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -8d
|
|
||||||
ST r31, r254, 0a, 8h
|
|
||||||
LI64 r2, 1d
|
|
||||||
JAL r31, r0, :sqrt
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
sqrt:
|
|
||||||
ADDI64 r254, r254, -56d
|
|
||||||
ST r31, r254, 0a, 56h
|
|
||||||
CP r32, r2
|
|
||||||
LI64 r33, 0d
|
|
||||||
LI64 r34, 0d
|
|
||||||
LI64 r35, 32768d
|
|
||||||
LI64 r36, 15d
|
|
||||||
3: LI64 r37, 0d
|
|
||||||
JNE r35, r37, :0
|
|
||||||
JMP :1
|
|
||||||
0: ADDI64 r36, r36, -1d
|
|
||||||
CP r37, r34
|
|
||||||
SLUI64 r37, r37, 1b
|
|
||||||
ADD64 r33, r35, r37
|
|
||||||
SLU64 r33, r33, r36
|
|
||||||
JLTS r32, r33, :2
|
|
||||||
ADD64 r34, r34, r35
|
|
||||||
SUB64 r32, r32, r33
|
|
||||||
2: SRUI64 r35, r35, 1b
|
|
||||||
JMP :3
|
|
||||||
1: CP r1, r34
|
|
||||||
LD r31, r254, 0a, 56h
|
|
||||||
ADDI64 r254, r254, 56d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 257
|
|
||||||
ret: 1
|
|
||||||
status: Ok(())
|
|
|
@ -1,130 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -160d
|
|
||||||
ST r31, r254, 136a, 24h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 0a, 1h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 1a, 1h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 2a, 1h
|
|
||||||
LI64 r32, 0d
|
|
||||||
ST r32, r254, 3a, 1h
|
|
||||||
LI64 r32, 1d
|
|
||||||
ST r32, r254, 4a, 1h
|
|
||||||
LI64 r32, 1d
|
|
||||||
ST r32, r254, 5a, 1h
|
|
||||||
LI64 r32, 1d
|
|
||||||
ST r32, r254, 6a, 1h
|
|
||||||
LI64 r32, 1d
|
|
||||||
ST r32, r254, 7a, 1h
|
|
||||||
CP r32, r0
|
|
||||||
LD r32, r254, 0a, 1h
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 4a, 1h
|
|
||||||
ADD8 r32, r32, r33
|
|
||||||
ST r32, r254, 0a, 1h
|
|
||||||
CP r32, r0
|
|
||||||
LD r32, r254, 1a, 1h
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 5a, 1h
|
|
||||||
ADD8 r32, r32, r33
|
|
||||||
ST r32, r254, 1a, 1h
|
|
||||||
CP r32, r0
|
|
||||||
LD r32, r254, 2a, 1h
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 6a, 1h
|
|
||||||
ADD8 r32, r32, r33
|
|
||||||
ST r32, r254, 2a, 1h
|
|
||||||
CP r32, r0
|
|
||||||
LD r32, r254, 3a, 1h
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 7a, 1h
|
|
||||||
ADD8 r32, r32, r33
|
|
||||||
ST r32, r254, 3a, 1h
|
|
||||||
CP r32, r0
|
|
||||||
LD r32, r254, 2a, 1h
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 1a, 1h
|
|
||||||
ADD8 r32, r32, r33
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 0a, 1h
|
|
||||||
ADD8 r32, r32, r33
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 3a, 1h
|
|
||||||
ADD8 r32, r32, r33
|
|
||||||
LI64 r33, 4d
|
|
||||||
JEQ r32, r33, :0
|
|
||||||
LI64 r1, 1008d
|
|
||||||
JMP :1
|
|
||||||
0: LI64 r33, 1d
|
|
||||||
ST r33, r254, 8a, 8h
|
|
||||||
LI64 r33, 2d
|
|
||||||
ST r33, r254, 16a, 8h
|
|
||||||
LI64 r33, 3d
|
|
||||||
ST r33, r254, 24a, 8h
|
|
||||||
LI64 r33, 4d
|
|
||||||
ST r33, r254, 32a, 8h
|
|
||||||
LD r33, r254, 8a, 8h
|
|
||||||
LD r32, r254, 24a, 8h
|
|
||||||
ADD64 r33, r33, r32
|
|
||||||
ST r33, r254, 40a, 8h
|
|
||||||
LD r33, r254, 16a, 8h
|
|
||||||
LD r32, r254, 32a, 8h
|
|
||||||
ADD64 r33, r33, r32
|
|
||||||
ST r33, r254, 48a, 8h
|
|
||||||
LD r33, r254, 24a, 8h
|
|
||||||
LD r32, r254, 8a, 8h
|
|
||||||
SUB64 r33, r33, r32
|
|
||||||
ST r33, r254, 56a, 8h
|
|
||||||
LD r33, r254, 32a, 8h
|
|
||||||
LD r32, r254, 16a, 8h
|
|
||||||
SUB64 r33, r33, r32
|
|
||||||
ST r33, r254, 64a, 8h
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r254, 72a, 8h
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r254, 80a, 8h
|
|
||||||
LD r33, r254, 72a, 8h
|
|
||||||
LD r32, r254, 24a, 8h
|
|
||||||
SUB64 r33, r33, r32
|
|
||||||
ST r33, r254, 88a, 8h
|
|
||||||
LD r33, r254, 80a, 8h
|
|
||||||
LD r32, r254, 32a, 8h
|
|
||||||
SUB64 r33, r33, r32
|
|
||||||
ST r33, r254, 96a, 8h
|
|
||||||
ADDI64 r33, r254, 8d
|
|
||||||
ADDI64 r32, r254, 104d
|
|
||||||
BMC r33, r32, 16h
|
|
||||||
LD r32, r254, 88a, 8h
|
|
||||||
LD r33, r254, 40a, 8h
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
ST r32, r254, 88a, 8h
|
|
||||||
LD r32, r254, 96a, 8h
|
|
||||||
LD r33, r254, 48a, 8h
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
ST r32, r254, 96a, 8h
|
|
||||||
LD r32, r254, 104a, 8h
|
|
||||||
LD r33, r254, 56a, 8h
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
ST r32, r254, 104a, 8h
|
|
||||||
LD r32, r254, 112a, 8h
|
|
||||||
LD r33, r254, 64a, 8h
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
ST r32, r254, 112a, 8h
|
|
||||||
LD r32, r254, 88a, 8h
|
|
||||||
LD r33, r254, 104a, 8h
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
ST r32, r254, 120a, 8h
|
|
||||||
LD r32, r254, 96a, 8h
|
|
||||||
LD r33, r254, 112a, 8h
|
|
||||||
ADD64 r32, r32, r33
|
|
||||||
ST r32, r254, 128a, 8h
|
|
||||||
LD r32, r254, 120a, 8h
|
|
||||||
LD r33, r254, 128a, 8h
|
|
||||||
ADD64 r1, r32, r33
|
|
||||||
1: LD r31, r254, 136a, 24h
|
|
||||||
ADDI64 r254, r254, 160d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 1264
|
|
||||||
ret: 10
|
|
||||||
status: Ok(())
|
|
|
@ -1,64 +0,0 @@
|
||||||
fib:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
CP r32, r2
|
|
||||||
LI64 r33, 2d
|
|
||||||
JLTS r32, r33, :0
|
|
||||||
CP r33, r32
|
|
||||||
ADDI64 r33, r33, -1d
|
|
||||||
CP r2, r33
|
|
||||||
JAL r31, r0, :fib
|
|
||||||
CP r33, r1
|
|
||||||
CP r34, r32
|
|
||||||
ADDI64 r34, r34, -2d
|
|
||||||
CP r2, r34
|
|
||||||
JAL r31, r0, :fib
|
|
||||||
CP r34, r1
|
|
||||||
ADD64 r1, r33, r34
|
|
||||||
JMP :1
|
|
||||||
0: CP r1, r32
|
|
||||||
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, -34d
|
|
||||||
ST r31, r254, 2a, 32h
|
|
||||||
LI64 r32, 10d
|
|
||||||
ST r32, r254, 0a, 1h
|
|
||||||
LI64 r32, 10d
|
|
||||||
ST r32, r254, 1a, 1h
|
|
||||||
CP r32, r0
|
|
||||||
LD r32, r254, 1a, 1h
|
|
||||||
CP r2, r0
|
|
||||||
LD r2, r254, 0a, 1h
|
|
||||||
JAL r31, r0, :fib
|
|
||||||
CP r33, r1
|
|
||||||
CP r2, r32
|
|
||||||
JAL r31, r0, :fib_iter
|
|
||||||
CP r34, r1
|
|
||||||
SUB64 r1, r33, r34
|
|
||||||
LD r31, r254, 2a, 32h
|
|
||||||
ADDI64 r254, r254, 34d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 449
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,39 +0,0 @@
|
||||||
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, -72d
|
|
||||||
ST r31, r254, 48a, 24h
|
|
||||||
LI64 r32, 7d
|
|
||||||
JAL r31, r0, :foo
|
|
||||||
ST r1, r254, 0a, 16h
|
|
||||||
LD r33, r254, 0a, 8h
|
|
||||||
SUB64 r32, r32, r33
|
|
||||||
JAL r31, r0, :foo
|
|
||||||
ST r1, r254, 16a, 16h
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 24a, 4h
|
|
||||||
SXT32 r33, r33
|
|
||||||
SUB64 r32, r32, r33
|
|
||||||
JAL r31, r0, :foo
|
|
||||||
ST r1, r254, 32a, 16h
|
|
||||||
CP r33, r0
|
|
||||||
LD r33, r254, 44a, 4h
|
|
||||||
SXT32 r33, r33
|
|
||||||
SUB64 r1, r32, r33
|
|
||||||
LD r31, r254, 48a, 24h
|
|
||||||
ADDI64 r254, r254, 72d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 341
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,52 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -72d
|
|
||||||
ST r31, r254, 48a, 24h
|
|
||||||
LI64 r32, 3d
|
|
||||||
LI64 r33, 3d
|
|
||||||
JEQ r32, r33, :0
|
|
||||||
LI64 r1, 9001d
|
|
||||||
JMP :1
|
|
||||||
0: LI64 r33, 4d
|
|
||||||
ST r33, r254, 0a, 8h
|
|
||||||
LI64 r33, 1d
|
|
||||||
ST r33, r254, 8a, 8h
|
|
||||||
LI64 r33, 3d
|
|
||||||
ST r33, r254, 16a, 8h
|
|
||||||
ADDI64 r2, r254, 0d
|
|
||||||
ADDI64 r1, r254, 24d
|
|
||||||
JAL r31, r0, :odher_pass
|
|
||||||
LD r33, r254, 40a, 8h
|
|
||||||
LI64 r32, 3d
|
|
||||||
JNE r33, r32, :2
|
|
||||||
ADDI64 r32, r254, 24d
|
|
||||||
CP r2, r32
|
|
||||||
JAL r31, r0, :pass
|
|
||||||
JMP :1
|
|
||||||
2: LI64 r1, 0d
|
|
||||||
1: LD r31, r254, 48a, 24h
|
|
||||||
ADDI64 r254, r254, 72d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
odher_pass:
|
|
||||||
ADDI64 r254, r254, -40d
|
|
||||||
ST r31, r254, 0a, 40h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r1
|
|
||||||
CP r34, r32
|
|
||||||
CP r35, r33
|
|
||||||
BMC r34, r35, 24h
|
|
||||||
LD r31, r254, 0a, 40h
|
|
||||||
ADDI64 r254, r254, 40d
|
|
||||||
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: 437
|
|
||||||
ret: 3
|
|
||||||
status: Ok(())
|
|
|
@ -1,38 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -10272d
|
|
||||||
ST r31, r254, 10240a, 32h
|
|
||||||
LI64 r32, 0d
|
|
||||||
2: LI64 r33, 1024d
|
|
||||||
JLTS r32, r33, :0
|
|
||||||
JMP :1
|
|
||||||
0: ADDI64 r33, r254, 0d
|
|
||||||
CP r34, r32
|
|
||||||
ADD64 r33, r33, r34
|
|
||||||
LI64 r34, 64d
|
|
||||||
ST r34, r33, 0a, 1h
|
|
||||||
ADDI64 r32, r32, 1d
|
|
||||||
JMP :2
|
|
||||||
1: LI64 r32, 1d
|
|
||||||
5: LI64 r33, 10d
|
|
||||||
JLTS r32, r33, :3
|
|
||||||
JMP :4
|
|
||||||
3: ADDI64 r33, r254, 0d
|
|
||||||
CP r34, r32
|
|
||||||
MULI64 r34, r34, 1024d
|
|
||||||
ADD64 r33, r33, r34
|
|
||||||
ADDI64 r34, r254, 0d
|
|
||||||
BMC r34, r33, 1024h
|
|
||||||
ADDI64 r32, r32, 1d
|
|
||||||
JMP :5
|
|
||||||
4: LI64 r33, 1024d
|
|
||||||
MULI64 r33, r33, 2d
|
|
||||||
ADDI64 r34, r254, 0d
|
|
||||||
ADD64 r34, r34, r33
|
|
||||||
CP r1, r0
|
|
||||||
LD r1, r34, 0a, 1h
|
|
||||||
LD r31, r254, 10240a, 32h
|
|
||||||
ADDI64 r254, r254, 10272d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 297
|
|
||||||
ret: 64
|
|
||||||
status: Ok(())
|
|
|
@ -1,13 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
LI64 r32, 1d
|
|
||||||
LI64 r33, 2d
|
|
||||||
ADDI64 r32, r32, 1d
|
|
||||||
SUB64 r1, r32, r33
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 102
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,46 +0,0 @@
|
||||||
main:
|
|
||||||
ADDI64 r254, r254, -56d
|
|
||||||
ST r31, r254, 24a, 32h
|
|
||||||
CP r32, r3
|
|
||||||
CP r33, r4
|
|
||||||
JAL r31, r0, :small_struct
|
|
||||||
CP r34, r1
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 0a, 1h
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 1a, 1h
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 2a, 1h
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 3a, 1h
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 4a, 1h
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 5a, 1h
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 6a, 1h
|
|
||||||
LI64 r34, 0d
|
|
||||||
ST r34, r254, 7a, 1h
|
|
||||||
LD r34, r254, 0a, 8h
|
|
||||||
ST r34, r254, 8a, 8h
|
|
||||||
LD r34, r254, 0a, 8h
|
|
||||||
ST r34, r254, 16a, 8h
|
|
||||||
LD r1, r254, 8a, 16h
|
|
||||||
LD r31, r254, 24a, 32h
|
|
||||||
ADDI64 r254, r254, 56d
|
|
||||||
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: 453
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
|
@ -1,26 +0,0 @@
|
||||||
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
|
|
||||||
JAL r31, r0, :outl
|
|
||||||
JAL r31, r0, :inl
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
outl:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
LRA r32, r0, :"whahaha\0"
|
|
||||||
LI64 r33, 0d
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 239
|
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
|
6
lang/tests/son_tests_aliasing_overoptimization.txt
Normal file
6
lang/tests/son_tests_aliasing_overoptimization.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
main:
|
||||||
|
LI64 r1, 0d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 29
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -1,37 +1,27 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -108d
|
ADDI64 r254, r254, -56d
|
||||||
ST r31, r254, 28a, 80h
|
ST r31, r254, 24a, 32h
|
||||||
LI64 r32, 4d
|
LI64 r32, 1d
|
||||||
LI64 r33, 1d
|
|
||||||
LI64 r34, 2d
|
|
||||||
LI64 r35, 3d
|
|
||||||
LI64 r36, 1d
|
|
||||||
LI64 r37, 0d
|
|
||||||
ADDI64 r2, r254, 0d
|
ADDI64 r2, r254, 0d
|
||||||
ADDI64 r38, r254, 24d
|
ST r32, r254, 0a, 8h
|
||||||
ST r37, r254, 24a, 1h
|
LI64 r33, 2d
|
||||||
ST r37, r254, 25a, 1h
|
ST r33, r254, 8a, 8h
|
||||||
ST r35, r254, 26a, 1h
|
LI64 r34, 4d
|
||||||
ST r33, r254, 27a, 1h
|
ST r34, r254, 16a, 8h
|
||||||
ST r36, r254, 0a, 8h
|
|
||||||
ST r34, r254, 8a, 8h
|
|
||||||
ST r32, r254, 16a, 8h
|
|
||||||
JAL r31, r0, :pass
|
JAL r31, r0, :pass
|
||||||
LD r39, r254, 27a, 1h
|
ADD64 r1, r1, r32
|
||||||
ANDI r40, r39, 255d
|
LD r31, r254, 24a, 32h
|
||||||
ADD64 r1, r1, r40
|
ADDI64 r254, r254, 56d
|
||||||
LD r31, r254, 28a, 80h
|
|
||||||
ADDI64 r254, r254, 108d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
pass:
|
pass:
|
||||||
LD r3, r2, 8a, 8h
|
LD r4, r2, 8a, 8h
|
||||||
MULI64 r8, r3, 8d
|
MULI64 r7, r4, 8d
|
||||||
ADD64 r10, r8, r2
|
LD r5, r2, 0a, 8h
|
||||||
LD r8, r10, 0a, 8h
|
ADD64 r10, r7, r2
|
||||||
LD r9, r2, 0a, 8h
|
ADD64 r9, r4, r5
|
||||||
ADD64 r11, r3, r9
|
LD r1, r10, 0a, 8h
|
||||||
ADD64 r1, r8, r11
|
ADD64 r1, r1, r9
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 348
|
code size: 231
|
||||||
ret: 8
|
ret: 8
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
7
lang/tests/son_tests_big_array_crash.txt
Normal file
7
lang/tests/son_tests_big_array_crash.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
main:
|
||||||
|
LRA r1, r0, :SIN_TABLE
|
||||||
|
LD r1, r1, 80a, 8h
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 767
|
||||||
|
ret: 1736
|
||||||
|
status: Ok(())
|
|
@ -11,7 +11,7 @@ main:
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
str_len:
|
str_len:
|
||||||
LI64 r6, 0d
|
LI8 r6, 0b
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
2: LD r8, r2, 0a, 1h
|
2: LD r8, r2, 0a, 1h
|
||||||
ANDI r8, r8, 255d
|
ANDI r8, r8, 255d
|
||||||
|
@ -22,6 +22,6 @@ str_len:
|
||||||
ADDI64 r1, r1, 1d
|
ADDI64 r1, r1, 1d
|
||||||
JMP :2
|
JMP :2
|
||||||
1: JALA r0, r31, 0a
|
1: JALA r0, r31, 0a
|
||||||
code size: 223
|
code size: 216
|
||||||
ret: 16
|
ret: 16
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -2,8 +2,8 @@ cond:
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -32d
|
ADDI64 r254, r254, -24d
|
||||||
ST r31, r254, 8a, 24h
|
ST r31, r254, 0a, 24h
|
||||||
JAL r31, r0, :cond
|
JAL r31, r0, :cond
|
||||||
LI64 r32, 0d
|
LI64 r32, 0d
|
||||||
CP r33, r32
|
CP r33, r32
|
||||||
|
@ -12,11 +12,9 @@ main:
|
||||||
CP r1, r32
|
CP r1, r32
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r1, 2d
|
0: LI64 r1, 2d
|
||||||
1: ADDI64 r33, r254, 0d
|
1: LD r31, r254, 0a, 24h
|
||||||
ST r1, r254, 0a, 8h
|
ADDI64 r254, r254, 24d
|
||||||
LD r31, r254, 8a, 24h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 158
|
code size: 134
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
6
lang/tests/son_tests_dead_code_in_loop.txt
Normal file
6
lang/tests/son_tests_dead_code_in_loop.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
main:
|
||||||
|
LI64 r1, 0d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 29
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
5
lang/tests/son_tests_die.txt
Normal file
5
lang/tests/son_tests_die.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
main:
|
||||||
|
UN
|
||||||
|
code size: 9
|
||||||
|
ret: 0
|
||||||
|
status: Err(Unreachable)
|
|
@ -1,54 +1,30 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -24d
|
ADDI64 r254, r254, -12d
|
||||||
LI64 r9, 2d
|
LI8 r1, 255b
|
||||||
LI64 r8, 0d
|
ST r1, r254, 0a, 1h
|
||||||
LI64 r6, 0d
|
LI8 r4, 0b
|
||||||
LI64 r7, 255d
|
ST r4, r254, 1a, 1h
|
||||||
ADDI64 r10, r254, 0d
|
ST r4, r254, 2a, 1h
|
||||||
ADDI64 r10, r254, 8d
|
ST r1, r254, 3a, 1h
|
||||||
ST r7, r254, 8a, 1h
|
LI32 r9, 0w
|
||||||
ST r6, r254, 9a, 1h
|
|
||||||
ST r6, r254, 10a, 1h
|
|
||||||
ST r7, r254, 11a, 1h
|
|
||||||
LD r3, r254, 8a, 4h
|
|
||||||
ADDI64 r12, r254, 12d
|
|
||||||
ST r3, r254, 12a, 4h
|
|
||||||
ST r8, r254, 0a, 4h
|
|
||||||
ST r9, r254, 4a, 4h
|
ST r9, r254, 4a, 4h
|
||||||
LD r1, r254, 0a, 8h
|
LI32 r12, 2w
|
||||||
ST r1, r254, 16a, 8h
|
ST r12, r254, 8a, 4h
|
||||||
LD r3, r254, 20a, 4h
|
LD r3, r254, 8a, 4h
|
||||||
ANDI r3, r3, 4294967295d
|
ANDI r3, r3, 4294967295d
|
||||||
ANDI r9, r9, 4294967295d
|
ANDI r12, r12, 4294967295d
|
||||||
JEQ r3, r9, :0
|
JEQ r3, r12, :0
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r10, r12, 8d
|
0: LD r10, r254, 4a, 4h
|
||||||
ADDI64 r10, r10, -4d
|
ANDI r10, r10, 4294967295d
|
||||||
LD r1, r10, 0a, 4h
|
ANDI r9, r9, 4294967295d
|
||||||
ANDI r1, r1, 4294967295d
|
JEQ r10, r9, :2
|
||||||
ANDI r8, r8, 4294967295d
|
|
||||||
JEQ r1, r8, :2
|
|
||||||
LI64 r1, 64d
|
LI64 r1, 64d
|
||||||
JMP :1
|
JMP :1
|
||||||
2: LD r7, r254, 15a, 1h
|
2: LI64 r1, 512d
|
||||||
ANDI r9, r7, 255d
|
1: ADDI64 r254, r254, 12d
|
||||||
LD r6, r254, 14a, 1h
|
|
||||||
ANDI r8, r6, 255d
|
|
||||||
LD r5, r254, 13a, 1h
|
|
||||||
ANDI r7, r5, 255d
|
|
||||||
LD r3, r254, 12a, 1h
|
|
||||||
ANDI r6, r3, 255d
|
|
||||||
LD r4, r254, 20a, 4h
|
|
||||||
LD r5, r254, 16a, 4h
|
|
||||||
ADD32 r10, r4, r5
|
|
||||||
ADD32 r11, r10, r6
|
|
||||||
ADD32 r3, r11, r7
|
|
||||||
ADD32 r7, r3, r8
|
|
||||||
ADD32 r11, r7, r9
|
|
||||||
ANDI r1, r11, 4294967295d
|
|
||||||
1: ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 529
|
code size: 257
|
||||||
ret: 512
|
ret: 512
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
20
lang/tests/son_tests_directives.txt
Normal file
20
lang/tests/son_tests_directives.txt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -16d
|
||||||
|
LI64 r1, 10d
|
||||||
|
ADDI64 r4, r254, 0d
|
||||||
|
ST r1, r254, 0a, 8h
|
||||||
|
LI64 r7, 20d
|
||||||
|
ST r7, r254, 8a, 8h
|
||||||
|
LI64 r6, 6d
|
||||||
|
LI64 r5, 5d
|
||||||
|
LI64 r2, 1d
|
||||||
|
CP r3, r4
|
||||||
|
LD r3, r3, 0a, 16h
|
||||||
|
ECA
|
||||||
|
LI64 r1, 0d
|
||||||
|
ADDI64 r254, r254, 16d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
ev: Ecall
|
||||||
|
code size: 155
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -15,55 +15,65 @@ continue_and_state_change:
|
||||||
4: ADDI64 r2, r2, 1d
|
4: ADDI64 r2, r2, 1d
|
||||||
3: JMP :6
|
3: JMP :6
|
||||||
5: JALA r0, r31, 0a
|
5: JALA r0, r31, 0a
|
||||||
|
infinite_loop:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ST r31, r254, 0a, 24h
|
||||||
|
LI64 r32, 1d
|
||||||
|
LI64 r33, 0d
|
||||||
|
CP r1, r33
|
||||||
|
1: JNE r1, r32, :0
|
||||||
|
JMP :0
|
||||||
|
0: CP r2, r33
|
||||||
|
JAL r31, r0, :continue_and_state_change
|
||||||
|
JMP :1
|
||||||
|
LD r31, r254, 0a, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -80d
|
ADDI64 r254, r254, -64d
|
||||||
ST r31, r254, 0a, 80h
|
ST r31, r254, 0a, 64h
|
||||||
LI64 r32, 0d
|
LI64 r32, 0d
|
||||||
CP r2, r32
|
CP r2, r32
|
||||||
JAL r31, r0, :multiple_breaks
|
JAL r31, r0, :multiple_breaks
|
||||||
CP r33, r32
|
CP r33, r1
|
||||||
CP r34, r1
|
|
||||||
LI64 r1, 3d
|
LI64 r1, 3d
|
||||||
JEQ r34, r1, :0
|
JEQ r33, r1, :0
|
||||||
LI64 r1, 1d
|
LI64 r1, 1d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: CP r35, r1
|
0: CP r34, r1
|
||||||
LI64 r36, 4d
|
LI64 r35, 4d
|
||||||
CP r2, r36
|
CP r2, r35
|
||||||
JAL r31, r0, :multiple_breaks
|
JAL r31, r0, :multiple_breaks
|
||||||
CP r37, r36
|
CP r36, r35
|
||||||
LI64 r38, 10d
|
LI64 r37, 10d
|
||||||
JEQ r1, r38, :2
|
JEQ r1, r37, :2
|
||||||
LI64 r1, 2d
|
LI64 r1, 2d
|
||||||
JMP :1
|
JMP :1
|
||||||
2: CP r2, r33
|
2: CP r2, r32
|
||||||
JAL r31, r0, :state_change_in_break
|
JAL r31, r0, :state_change_in_break
|
||||||
CP r39, r1
|
JEQ r1, r32, :3
|
||||||
CP r1, r33
|
CP r1, r34
|
||||||
JEQ r39, r1, :3
|
|
||||||
CP r1, r35
|
|
||||||
JMP :1
|
JMP :1
|
||||||
3: CP r33, r1
|
3: CP r2, r36
|
||||||
CP r2, r37
|
|
||||||
JAL r31, r0, :state_change_in_break
|
JAL r31, r0, :state_change_in_break
|
||||||
JEQ r1, r38, :4
|
JEQ r1, r37, :4
|
||||||
CP r1, r37
|
CP r1, r36
|
||||||
JMP :1
|
JMP :1
|
||||||
4: CP r2, r38
|
4: CP r2, r37
|
||||||
JAL r31, r0, :continue_and_state_change
|
JAL r31, r0, :continue_and_state_change
|
||||||
JEQ r1, r38, :5
|
JEQ r1, r37, :5
|
||||||
LI64 r1, 5d
|
LI64 r1, 5d
|
||||||
JMP :1
|
JMP :1
|
||||||
5: CP r2, r35
|
5: CP r2, r34
|
||||||
JAL r31, r0, :continue_and_state_change
|
JAL r31, r0, :continue_and_state_change
|
||||||
CP r40, r1
|
JEQ r1, r32, :6
|
||||||
CP r1, r33
|
|
||||||
JEQ r40, r1, :6
|
|
||||||
LI64 r1, 6d
|
LI64 r1, 6d
|
||||||
JMP :1
|
JMP :1
|
||||||
6: CP r1, r33
|
6: CP r38, r32
|
||||||
1: LD r31, r254, 0a, 80h
|
JAL r31, r0, :infinite_loop
|
||||||
ADDI64 r254, r254, 80d
|
CP r1, r38
|
||||||
|
1: LD r31, r254, 0a, 64h
|
||||||
|
ADDI64 r254, r254, 64d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
multiple_breaks:
|
multiple_breaks:
|
||||||
LI64 r6, 3d
|
LI64 r6, 3d
|
||||||
|
@ -89,6 +99,7 @@ state_change_in_break:
|
||||||
2: ADDI64 r2, r2, 1d
|
2: ADDI64 r2, r2, 1d
|
||||||
JMP :4
|
JMP :4
|
||||||
3: JALA r0, r31, 0a
|
3: JALA r0, r31, 0a
|
||||||
code size: 569
|
timed out
|
||||||
ret: 0
|
code size: 668
|
||||||
|
ret: 10
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
6
lang/tests/son_tests_floating_point_arithmetic.txt
Normal file
6
lang/tests/son_tests_floating_point_arithmetic.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
main:
|
||||||
|
LI32 r1, 3212836864w
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 25
|
||||||
|
ret: 3212836864
|
||||||
|
status: Ok(())
|
24
lang/tests/son_tests_generic_functions.txt
Normal file
24
lang/tests/son_tests_generic_functions.txt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
add:
|
||||||
|
ADD64 r1, r2, r3
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
add:
|
||||||
|
ADD32 r1, r2, r3
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ST r31, r254, 0a, 24h
|
||||||
|
LI32 r3, 2w
|
||||||
|
CP r2, r3
|
||||||
|
JAL r31, r0, :add
|
||||||
|
CP r32, r1
|
||||||
|
LI64 r3, 3d
|
||||||
|
LI64 r2, 1d
|
||||||
|
JAL r31, r0, :add
|
||||||
|
ANDI r33, r32, 4294967295d
|
||||||
|
SUB64 r1, r33, r1
|
||||||
|
LD r31, r254, 0a, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 158
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
127
lang/tests/son_tests_generic_types.txt
Normal file
127
lang/tests/son_tests_generic_types.txt
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
deinit:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 0a, 32h
|
||||||
|
CP r32, r2
|
||||||
|
LD r33, r2, 16a, 8h
|
||||||
|
LI64 r4, 8d
|
||||||
|
MUL64 r3, r33, r4
|
||||||
|
CP r34, r32
|
||||||
|
LD r2, r34, 0a, 8h
|
||||||
|
JAL r31, r0, :free
|
||||||
|
CP r1, r32
|
||||||
|
JAL r31, r0, :new
|
||||||
|
LD r31, r254, 0a, 32h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
free:
|
||||||
|
CP r10, r2
|
||||||
|
LRA r7, r0, :FREE_SYS_CALL
|
||||||
|
LD r2, r7, 0a, 8h
|
||||||
|
CP r5, r4
|
||||||
|
CP r4, r3
|
||||||
|
CP r3, r10
|
||||||
|
ECA
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -56d
|
||||||
|
ST r31, r254, 24a, 32h
|
||||||
|
ADDI64 r32, r254, 0d
|
||||||
|
CP r1, r32
|
||||||
|
JAL r31, r0, :new
|
||||||
|
LI64 r3, 69d
|
||||||
|
CP r2, r32
|
||||||
|
JAL r31, r0, :push
|
||||||
|
LD r33, r254, 0a, 8h
|
||||||
|
LD r34, r33, 0a, 8h
|
||||||
|
CP r2, r32
|
||||||
|
JAL r31, r0, :deinit
|
||||||
|
CP r1, r34
|
||||||
|
LD r31, r254, 24a, 32h
|
||||||
|
ADDI64 r254, r254, 56d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
malloc:
|
||||||
|
CP r9, r2
|
||||||
|
LRA r5, r0, :MALLOC_SYS_CALL
|
||||||
|
LD r2, r5, 0a, 8h
|
||||||
|
CP r4, r3
|
||||||
|
CP r3, r9
|
||||||
|
ECA
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
new:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
LI64 r4, 0d
|
||||||
|
ADDI64 r5, r254, 0d
|
||||||
|
ST r4, r254, 0a, 8h
|
||||||
|
ST r4, r254, 8a, 8h
|
||||||
|
ST r4, r254, 16a, 8h
|
||||||
|
BMC r5, r1, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
push:
|
||||||
|
ADDI64 r254, r254, -192d
|
||||||
|
ST r31, r254, 0a, 192h
|
||||||
|
CP r32, r3
|
||||||
|
LI64 r33, 1d
|
||||||
|
LD r34, r2, 8a, 8h
|
||||||
|
LD r35, r2, 16a, 8h
|
||||||
|
CP r36, r2
|
||||||
|
JNE r35, r34, :0
|
||||||
|
LI64 r37, 0d
|
||||||
|
JNE r35, r37, :1
|
||||||
|
CP r38, r33
|
||||||
|
JMP :2
|
||||||
|
1: MULI64 r38, r35, 2d
|
||||||
|
2: LI64 r39, 8d
|
||||||
|
MUL64 r2, r38, r39
|
||||||
|
CP r3, r39
|
||||||
|
JAL r31, r0, :malloc
|
||||||
|
CP r40, r1
|
||||||
|
CP r41, r36
|
||||||
|
ST r38, r41, 16a, 8h
|
||||||
|
LI64 r1, 0d
|
||||||
|
CP r42, r40
|
||||||
|
JNE r42, r1, :3
|
||||||
|
JMP :4
|
||||||
|
3: CP r40, r42
|
||||||
|
LD r36, r41, 8a, 8h
|
||||||
|
MULI64 r43, r36, 8d
|
||||||
|
LD r44, r41, 0a, 8h
|
||||||
|
ADD64 r45, r44, r43
|
||||||
|
CP r46, r40
|
||||||
|
9: LD r2, r41, 0a, 8h
|
||||||
|
LD r47, r41, 8a, 8h
|
||||||
|
JNE r45, r44, :5
|
||||||
|
JEQ r47, r37, :6
|
||||||
|
CP r4, r39
|
||||||
|
MUL64 r3, r47, r4
|
||||||
|
JAL r31, r0, :free
|
||||||
|
CP r1, r40
|
||||||
|
JMP :7
|
||||||
|
6: CP r1, r40
|
||||||
|
7: ST r1, r41, 0a, 8h
|
||||||
|
JMP :8
|
||||||
|
5: CP r1, r40
|
||||||
|
CP r4, r39
|
||||||
|
ADDI64 r48, r46, 8d
|
||||||
|
ADDI64 r42, r44, 8d
|
||||||
|
LD r49, r44, 0a, 8h
|
||||||
|
ST r49, r46, 0a, 8h
|
||||||
|
CP r44, r42
|
||||||
|
CP r46, r48
|
||||||
|
JMP :9
|
||||||
|
0: CP r41, r36
|
||||||
|
8: LD r50, r41, 8a, 8h
|
||||||
|
MULI64 r51, r50, 8d
|
||||||
|
LD r52, r41, 0a, 8h
|
||||||
|
ADD64 r1, r52, r51
|
||||||
|
CP r3, r32
|
||||||
|
ST r3, r1, 0a, 8h
|
||||||
|
LD r53, r41, 8a, 8h
|
||||||
|
ADD64 r54, r53, r33
|
||||||
|
ST r54, r41, 8a, 8h
|
||||||
|
4: LD r31, r254, 0a, 192h
|
||||||
|
ADDI64 r254, r254, 192d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 955
|
||||||
|
ret: 69
|
||||||
|
status: Ok(())
|
19
lang/tests/son_tests_global_aliasing_overptimization.txt
Normal file
19
lang/tests/son_tests_global_aliasing_overptimization.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
clobber:
|
||||||
|
LRA r1, r0, :var
|
||||||
|
LI64 r3, 0d
|
||||||
|
ST r3, r1, 0a, 8h
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ST r31, r254, 0a, 24h
|
||||||
|
LRA r32, r0, :var
|
||||||
|
LI64 r33, 2d
|
||||||
|
ST r33, r32, 0a, 8h
|
||||||
|
JAL r31, r0, :clobber
|
||||||
|
LD r1, r32, 0a, 8h
|
||||||
|
LD r31, r254, 0a, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 166
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -1,20 +1,20 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -128d
|
ADDI64 r254, r254, -128d
|
||||||
LI64 r6, 69d
|
LI8 r5, 69b
|
||||||
LI64 r5, 128d
|
LI64 r6, 128d
|
||||||
LI64 r7, 0d
|
LI64 r7, 0d
|
||||||
ADDI64 r4, r254, 0d
|
ADDI64 r4, r254, 0d
|
||||||
2: JLTU r7, r5, :0
|
2: LD r12, r254, 42a, 1h
|
||||||
LD r2, r254, 42a, 1h
|
JLTU r7, r6, :0
|
||||||
ANDI r1, r2, 255d
|
ANDI r1, r12, 255d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r8, r7, 1d
|
0: ADDI64 r3, r7, 1d
|
||||||
ADD64 r3, r7, r4
|
ADD64 r7, r4, r7
|
||||||
ST r6, r3, 0a, 1h
|
ST r5, r7, 0a, 1h
|
||||||
CP r7, r8
|
CP r7, r3
|
||||||
JMP :2
|
JMP :2
|
||||||
1: ADDI64 r254, r254, 128d
|
1: ADDI64 r254, r254, 128d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 152
|
code size: 145
|
||||||
ret: 69
|
ret: 69
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
9
lang/tests/son_tests_infinite_loop_after_peephole.txt
Normal file
9
lang/tests/son_tests_infinite_loop_after_peephole.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
main:
|
||||||
|
LI64 r2, 0d
|
||||||
|
0: ADDI64 r2, r2, 1d
|
||||||
|
JMP :0
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
timed out
|
||||||
|
code size: 45
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
18
lang/tests/son_tests_inline.txt
Normal file
18
lang/tests/son_tests_inline.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
main:
|
||||||
|
LI64 r7, 6d
|
||||||
|
LRA r3, r0, :gb
|
||||||
|
LI64 r6, 0d
|
||||||
|
LD r8, r3, 0a, 8h
|
||||||
|
CMPU r9, r8, r6
|
||||||
|
CMPUI r9, r9, 0d
|
||||||
|
ORI r11, r9, 0d
|
||||||
|
ANDI r11, r11, 255d
|
||||||
|
JNE r11, r0, :0
|
||||||
|
CP r4, r7
|
||||||
|
JMP :1
|
||||||
|
0: LI64 r4, 1d
|
||||||
|
1: SUB64 r1, r4, r7
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 131
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
39
lang/tests/son_tests_inline_test.txt
Normal file
39
lang/tests/son_tests_inline_test.txt
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 0a, 32h
|
||||||
|
JAL r31, r0, :scalar_values
|
||||||
|
LI64 r32, 0d
|
||||||
|
CP r33, r32
|
||||||
|
JEQ r1, r33, :0
|
||||||
|
LI64 r1, 1d
|
||||||
|
JMP :1
|
||||||
|
0: JAL r31, r0, :structs
|
||||||
|
CP r34, r33
|
||||||
|
JEQ r1, r34, :2
|
||||||
|
JAL r31, r0, :structs
|
||||||
|
JMP :1
|
||||||
|
2: CP r1, r34
|
||||||
|
CP r33, r34
|
||||||
|
1: LD r31, r254, 0a, 32h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
scalar_values:
|
||||||
|
LI64 r1, 0d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
structs:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
LI64 r1, 5d
|
||||||
|
ST r1, r254, 16a, 8h
|
||||||
|
ST r1, r254, 24a, 8h
|
||||||
|
LD r5, r254, 16a, 8h
|
||||||
|
ADDI64 r7, r5, 15d
|
||||||
|
ST r7, r254, 0a, 8h
|
||||||
|
LI64 r10, 20d
|
||||||
|
ST r10, r254, 8a, 8h
|
||||||
|
LD r1, r254, 0a, 8h
|
||||||
|
SUB64 r1, r1, r10
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 307
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
6
lang/tests/son_tests_inlined_generic_functions.txt
Normal file
6
lang/tests/son_tests_inlined_generic_functions.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
main:
|
||||||
|
LI64 r1, 10d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 29
|
||||||
|
ret: 10
|
||||||
|
status: Ok(())
|
109
lang/tests/son_tests_inlining_issues.txt
Normal file
109
lang/tests/son_tests_inlining_issues.txt
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -106d
|
||||||
|
ST r31, r254, 58a, 48h
|
||||||
|
ADDI64 r32, r254, 33d
|
||||||
|
ADDI64 r2, r254, 34d
|
||||||
|
ADDI64 r6, r254, 1d
|
||||||
|
LI64 r33, 0d
|
||||||
|
ADDI64 r4, r254, 17d
|
||||||
|
ST r32, r254, 34a, 8h
|
||||||
|
LI64 r34, 100d
|
||||||
|
ADDI64 r7, r254, 0d
|
||||||
|
LI8 r35, 1b
|
||||||
|
ST r33, r254, 1a, 8h
|
||||||
|
ST r33, r254, 17a, 8h
|
||||||
|
ST r34, r254, 42a, 8h
|
||||||
|
LI8 r36, 0b
|
||||||
|
ST r35, r254, 0a, 1h
|
||||||
|
ST r33, r254, 9a, 8h
|
||||||
|
ST r33, r254, 25a, 8h
|
||||||
|
ST r34, r254, 50a, 8h
|
||||||
|
ST r36, r254, 33a, 1h
|
||||||
|
CP r3, r4
|
||||||
|
CP r5, r6
|
||||||
|
LD r3, r3, 0a, 16h
|
||||||
|
LD r5, r5, 0a, 16h
|
||||||
|
LD r7, r7, 0a, 1h
|
||||||
|
JAL r31, r0, :put_filled_rect
|
||||||
|
LD r31, r254, 58a, 48h
|
||||||
|
ADDI64 r254, r254, 106d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
put_filled_rect:
|
||||||
|
ADDI64 r254, r254, -212d
|
||||||
|
ST r32, r254, 108a, 104h
|
||||||
|
ST r3, r254, 92a, 16h
|
||||||
|
ADDI64 r3, r254, 92d
|
||||||
|
ST r5, r254, 76a, 16h
|
||||||
|
ADDI64 r5, r254, 76d
|
||||||
|
ST r7, r254, 75a, 1h
|
||||||
|
ADDI64 r7, r254, 75d
|
||||||
|
LI64 r8, 25d
|
||||||
|
LI64 r32, 2d
|
||||||
|
LI64 r6, 8d
|
||||||
|
ADDI64 r33, r254, 25d
|
||||||
|
ADDI64 r34, r254, 50d
|
||||||
|
LI8 r35, 5b
|
||||||
|
ST r35, r254, 25a, 1h
|
||||||
|
LD r36, r5, 0a, 8h
|
||||||
|
ST r36, r254, 26a, 4h
|
||||||
|
LI64 r37, 1d
|
||||||
|
ST r37, r254, 30a, 4h
|
||||||
|
ST r7, r254, 34a, 8h
|
||||||
|
ST r35, r254, 50a, 1h
|
||||||
|
ST r36, r254, 51a, 4h
|
||||||
|
ST r37, r254, 55a, 4h
|
||||||
|
ST r7, r254, 59a, 8h
|
||||||
|
CP r38, r7
|
||||||
|
LD r7, r3, 8a, 8h
|
||||||
|
LD r39, r5, 8a, 8h
|
||||||
|
ADD64 r11, r39, r7
|
||||||
|
SUB64 r4, r11, r37
|
||||||
|
LD r40, r2, 8a, 8h
|
||||||
|
MUL64 r5, r40, r4
|
||||||
|
LD r9, r2, 0a, 8h
|
||||||
|
ADD64 r10, r9, r5
|
||||||
|
LD r2, r3, 0a, 8h
|
||||||
|
ADD64 r41, r2, r10
|
||||||
|
MUL64 r3, r40, r7
|
||||||
|
ADD64 r4, r9, r3
|
||||||
|
ADD64 r42, r2, r4
|
||||||
|
3: JGTU r39, r37, :0
|
||||||
|
JNE r39, r37, :1
|
||||||
|
ADDI64 r4, r254, 0d
|
||||||
|
ST r35, r254, 0a, 1h
|
||||||
|
ST r36, r254, 1a, 4h
|
||||||
|
ST r37, r254, 5a, 4h
|
||||||
|
ST r38, r254, 9a, 8h
|
||||||
|
ST r42, r254, 17a, 8h
|
||||||
|
CP r2, r6
|
||||||
|
CP r3, r32
|
||||||
|
CP r5, r8
|
||||||
|
ECA
|
||||||
|
JMP :1
|
||||||
|
1: JMP :2
|
||||||
|
0: CP r3, r32
|
||||||
|
CP r43, r6
|
||||||
|
CP r44, r8
|
||||||
|
ST r42, r254, 67a, 8h
|
||||||
|
CP r2, r43
|
||||||
|
CP r4, r34
|
||||||
|
CP r5, r44
|
||||||
|
ECA
|
||||||
|
ST r41, r254, 42a, 8h
|
||||||
|
CP r2, r43
|
||||||
|
CP r3, r32
|
||||||
|
CP r4, r33
|
||||||
|
CP r5, r44
|
||||||
|
ECA
|
||||||
|
ADD64 r42, r40, r42
|
||||||
|
SUB64 r41, r41, r40
|
||||||
|
SUB64 r39, r39, r32
|
||||||
|
CP r6, r43
|
||||||
|
CP r8, r44
|
||||||
|
JMP :3
|
||||||
|
2: LD r32, r254, 108a, 104h
|
||||||
|
ADDI64 r254, r254, 212d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 917
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
20
lang/tests/son_tests_intcast_store.txt
Normal file
20
lang/tests/son_tests_intcast_store.txt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 16a, 16h
|
||||||
|
ADDI64 r3, r254, 0d
|
||||||
|
ADDI64 r2, r254, 8d
|
||||||
|
LI64 r32, 0d
|
||||||
|
ST r32, r254, 0a, 8h
|
||||||
|
ST r32, r254, 8a, 8h
|
||||||
|
LI64 r4, 1024d
|
||||||
|
JAL r31, r0, :set
|
||||||
|
ANDI r1, r1, 4294967295d
|
||||||
|
LD r31, r254, 16a, 16h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
set:
|
||||||
|
CP r1, r4
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 167
|
||||||
|
ret: 1024
|
||||||
|
status: Ok(())
|
29
lang/tests/son_tests_integer_inference_issues.txt
Normal file
29
lang/tests/son_tests_integer_inference_issues.txt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
integer_range:
|
||||||
|
ADDI64 r254, r254, -16d
|
||||||
|
ST r32, r254, 0a, 16h
|
||||||
|
CP r32, r2
|
||||||
|
CP r33, r3
|
||||||
|
LI64 r3, 4d
|
||||||
|
LI64 r2, 3d
|
||||||
|
ECA
|
||||||
|
CP r2, r32
|
||||||
|
CP r3, r33
|
||||||
|
SUB64 r11, r3, r2
|
||||||
|
ADDI64 r3, r11, 1d
|
||||||
|
DIRU64 r0, r3, r1, r3
|
||||||
|
ADD64 r1, r3, r2
|
||||||
|
LD r32, r254, 0a, 16h
|
||||||
|
ADDI64 r254, r254, 16d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ST r31, r254, 0a, 8h
|
||||||
|
LI64 r3, 1000d
|
||||||
|
LI64 r2, 0d
|
||||||
|
JAL r31, r0, :integer_range
|
||||||
|
LD r31, r254, 0a, 8h
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 210
|
||||||
|
ret: 42
|
||||||
|
status: Ok(())
|
|
@ -1,17 +1,16 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -8d
|
ADDI64 r254, r254, -8d
|
||||||
LI64 r4, 0d
|
LI64 r3, 0d
|
||||||
LI64 r2, 10d
|
LI64 r2, 10d
|
||||||
ADDI64 r5, r254, 0d
|
|
||||||
ST r2, r254, 0a, 8h
|
ST r2, r254, 0a, 8h
|
||||||
2: LD r1, r254, 0a, 8h
|
2: LD r1, r254, 0a, 8h
|
||||||
JNE r1, r4, :0
|
JNE r1, r3, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r1, r1, -1d
|
0: ADDI64 r11, r1, -1d
|
||||||
ST r1, r254, 0a, 8h
|
ST r11, r254, 0a, 8h
|
||||||
JMP :2
|
JMP :2
|
||||||
1: ADDI64 r254, r254, 8d
|
1: ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 137
|
code size: 126
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -5,8 +5,9 @@ fib:
|
||||||
CP r10, r4
|
CP r10, r4
|
||||||
2: JNE r2, r5, :0
|
2: JNE r2, r5, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADD64 r3, r10, r1
|
0: ADD64 r1, r10, r1
|
||||||
SUB64 r2, r2, r4
|
SUB64 r2, r2, r4
|
||||||
|
CP r3, r1
|
||||||
CP r1, r10
|
CP r1, r10
|
||||||
CP r10, r3
|
CP r10, r3
|
||||||
JMP :2
|
JMP :2
|
||||||
|
@ -19,6 +20,6 @@ main:
|
||||||
LD r31, r254, 0a, 8h
|
LD r31, r254, 0a, 8h
|
||||||
ADDI64 r254, r254, 8d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 150
|
code size: 153
|
||||||
ret: 55
|
ret: 55
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
27
lang/tests/son_tests_more_if_opts.txt
Normal file
27
lang/tests/son_tests_more_if_opts.txt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 0a, 32h
|
||||||
|
JAL r31, r0, :opaque
|
||||||
|
CP r32, r1
|
||||||
|
JAL r31, r0, :opaque
|
||||||
|
LI64 r33, 0d
|
||||||
|
CP r1, r32
|
||||||
|
JNE r1, r33, :0
|
||||||
|
CP r32, r1
|
||||||
|
LI64 r1, 0d
|
||||||
|
CP r34, r32
|
||||||
|
JMP :1
|
||||||
|
0: CP r34, r1
|
||||||
|
LD r1, r34, 0a, 8h
|
||||||
|
1: JEQ r34, r33, :2
|
||||||
|
LD r1, r34, 0a, 8h
|
||||||
|
JMP :2
|
||||||
|
2: LD r31, r254, 0a, 32h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
opaque:
|
||||||
|
LI64 r1, 0d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 183
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
6
lang/tests/son_tests_needless_unwrap.txt
Normal file
6
lang/tests/son_tests_needless_unwrap.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
test.hb:4:17: unwrap is not needed since the value is (provably) never null, remove it, or replace with '@as(<expr_ty>, <opt_expr>)'
|
||||||
|
ptr := @unwrap(always_nn)
|
||||||
|
^
|
||||||
|
test.hb:6:16: unwrap is incorrect since the value is (provably) always null, make sure your logic is correct
|
||||||
|
ptr = @unwrap(always_n)
|
||||||
|
^
|
7
lang/tests/son_tests_nonexistent_ident_import.txt
Normal file
7
lang/tests/son_tests_nonexistent_ident_import.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
foo.hb:4:1: redeclaration of identifier: foo
|
||||||
|
foo := fn(): void {
|
||||||
|
^
|
||||||
|
|
||||||
|
foo.hb:7:23: undefined indentifier: mian
|
||||||
|
main := @use("bar.hb").mian
|
||||||
|
^
|
26
lang/tests/son_tests_null_check_test.txt
Normal file
26
lang/tests/son_tests_null_check_test.txt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
get_ptr:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ADDI64 r1, r254, 0d
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -40d
|
||||||
|
ST r31, r254, 0a, 40h
|
||||||
|
JAL r31, r0, :get_ptr
|
||||||
|
LI64 r32, 0d
|
||||||
|
JNE r1, r32, :0
|
||||||
|
LI64 r1, 0d
|
||||||
|
JMP :1
|
||||||
|
0: LI64 r33, 10d
|
||||||
|
CP r34, r1
|
||||||
|
2: LD r1, r34, 0a, 8h
|
||||||
|
JEQ r1, r33, :1
|
||||||
|
ADDI64 r35, r1, 1d
|
||||||
|
ST r35, r34, 0a, 8h
|
||||||
|
JMP :2
|
||||||
|
1: LD r31, r254, 0a, 40h
|
||||||
|
ADDI64 r254, r254, 40d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 208
|
||||||
|
ret: 10
|
||||||
|
status: Ok(())
|
130
lang/tests/son_tests_nullable_types.txt
Normal file
130
lang/tests/son_tests_nullable_types.txt
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
decide:
|
||||||
|
LI8 r1, 1b
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -224d
|
||||||
|
ST r31, r254, 80a, 144h
|
||||||
|
JAL r31, r0, :decide
|
||||||
|
LI64 r32, 0d
|
||||||
|
ADDI64 r2, r254, 72d
|
||||||
|
CP r33, r2
|
||||||
|
ANDI r1, r1, 255d
|
||||||
|
JNE r1, r0, :0
|
||||||
|
CP r34, r32
|
||||||
|
JMP :1
|
||||||
|
0: CP r34, r33
|
||||||
|
1: JNE r34, r32, :2
|
||||||
|
LI64 r1, 9001d
|
||||||
|
JMP :3
|
||||||
|
2: JAL r31, r0, :decide
|
||||||
|
LI8 r35, 0b
|
||||||
|
ANDI r1, r1, 255d
|
||||||
|
JNE r1, r0, :4
|
||||||
|
LI8 r36, 1b
|
||||||
|
ST r36, r254, 56a, 1h
|
||||||
|
LD r36, r34, 0a, 8h
|
||||||
|
ST r36, r254, 64a, 8h
|
||||||
|
JMP :5
|
||||||
|
4: ST r35, r254, 56a, 1h
|
||||||
|
5: LD r37, r254, 56a, 1h
|
||||||
|
ANDI r37, r37, 255d
|
||||||
|
ANDI r35, r35, 255d
|
||||||
|
JEQ r37, r35, :6
|
||||||
|
LI64 r1, 42d
|
||||||
|
JMP :3
|
||||||
|
6: JAL r31, r0, :decide
|
||||||
|
LI32 r38, 0w
|
||||||
|
ANDI r1, r1, 255d
|
||||||
|
JNE r1, r0, :7
|
||||||
|
CP r39, r38
|
||||||
|
JMP :8
|
||||||
|
7: LI32 r39, 8388609w
|
||||||
|
8: ANDI r39, r39, 4294967295d
|
||||||
|
ANDI r38, r38, 4294967295d
|
||||||
|
JNE r39, r38, :9
|
||||||
|
LI64 r1, 69d
|
||||||
|
JMP :3
|
||||||
|
9: ADDI64 r3, r254, 40d
|
||||||
|
CP r40, r3
|
||||||
|
JAL r31, r0, :new_foo
|
||||||
|
ST r1, r254, 40a, 16h
|
||||||
|
LI64 r32, 0d
|
||||||
|
LD r41, r254, 40a, 8h
|
||||||
|
JNE r41, r32, :10
|
||||||
|
LI64 r1, 999d
|
||||||
|
JMP :3
|
||||||
|
10: LRA r4, r0, :"foo\0"
|
||||||
|
CP r3, r40
|
||||||
|
CP r2, r3
|
||||||
|
LD r2, r2, 0a, 16h
|
||||||
|
JAL r31, r0, :use_foo
|
||||||
|
ADDI64 r42, r254, 0d
|
||||||
|
JAL r31, r0, :no_foo
|
||||||
|
ST r1, r254, 0a, 16h
|
||||||
|
JAL r31, r0, :decide
|
||||||
|
ANDI r1, r1, 255d
|
||||||
|
JNE r1, r0, :11
|
||||||
|
CP r2, r33
|
||||||
|
JMP :12
|
||||||
|
11: CP r2, r33
|
||||||
|
ST r2, r254, 0a, 8h
|
||||||
|
LI64 r43, 1d
|
||||||
|
ST r43, r254, 8a, 8h
|
||||||
|
ST r43, r254, 72a, 8h
|
||||||
|
12: LD r44, r254, 0a, 8h
|
||||||
|
JNE r44, r32, :13
|
||||||
|
LI64 r1, 34d
|
||||||
|
JMP :3
|
||||||
|
13: ADDI64 r1, r254, 16d
|
||||||
|
JAL r31, r0, :new_bar
|
||||||
|
JAL r31, r0, :decide
|
||||||
|
ANDI r1, r1, 255d
|
||||||
|
JNE r1, r0, :14
|
||||||
|
JMP :15
|
||||||
|
14: ST r35, r254, 16a, 1h
|
||||||
|
15: LD r45, r254, 16a, 1h
|
||||||
|
ANDI r45, r45, 255d
|
||||||
|
ANDI r35, r35, 255d
|
||||||
|
JEQ r45, r35, :16
|
||||||
|
LI64 r1, 420d
|
||||||
|
JMP :3
|
||||||
|
16: LD r46, r254, 0a, 8h
|
||||||
|
LD r47, r46, 0a, 8h
|
||||||
|
ANDI r48, r39, 65535d
|
||||||
|
SUB64 r1, r48, r47
|
||||||
|
3: LD r31, r254, 80a, 144h
|
||||||
|
ADDI64 r254, r254, 224d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
new_bar:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ADDI64 r5, r254, 0d
|
||||||
|
BMC r1, r1, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
new_foo:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ADDI64 r3, r254, 0d
|
||||||
|
ADDI64 r2, r254, 8d
|
||||||
|
ST r3, r254, 8a, 8h
|
||||||
|
LI64 r5, 0d
|
||||||
|
ST r5, r254, 16a, 8h
|
||||||
|
LD r1, r2, 0a, 16h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
no_foo:
|
||||||
|
ADDI64 r254, r254, -16d
|
||||||
|
ADDI64 r1, r254, 0d
|
||||||
|
LI64 r3, 0d
|
||||||
|
ST r3, r254, 0a, 8h
|
||||||
|
LD r1, r1, 0a, 16h
|
||||||
|
ADDI64 r254, r254, 16d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
use_foo:
|
||||||
|
ADDI64 r254, r254, -16d
|
||||||
|
ST r2, r254, 0a, 16h
|
||||||
|
ADDI64 r2, r254, 0d
|
||||||
|
ADDI64 r254, r254, 16d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 1091
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
30
lang/tests/son_tests_only_break_loop.txt
Normal file
30
lang/tests/son_tests_only_break_loop.txt
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
inb:
|
||||||
|
CP r1, r2
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 0a, 32h
|
||||||
|
LI64 r32, 0d
|
||||||
|
LI64 r33, 100d
|
||||||
|
4: CP r2, r33
|
||||||
|
JAL r31, r0, :inb
|
||||||
|
ANDI r34, r1, 2d
|
||||||
|
JNE r34, r32, :0
|
||||||
|
LI64 r2, 96d
|
||||||
|
CP r3, r32
|
||||||
|
JAL r31, r0, :outb
|
||||||
|
3: CP r2, r33
|
||||||
|
JAL r31, r0, :inb
|
||||||
|
JEQ r1, r32, :1
|
||||||
|
LI64 r1, 1d
|
||||||
|
JMP :2
|
||||||
|
1: JMP :3
|
||||||
|
0: JMP :4
|
||||||
|
2: LD r31, r254, 0a, 32h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
outb:
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 198
|
||||||
|
ret: 1
|
||||||
|
status: Ok(())
|
34
lang/tests/son_tests_overwrite_aliasing_overoptimization.txt
Normal file
34
lang/tests/son_tests_overwrite_aliasing_overoptimization.txt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -104d
|
||||||
|
ST r31, r254, 40a, 64h
|
||||||
|
LI64 r32, 4d
|
||||||
|
ADDI64 r33, r254, 24d
|
||||||
|
ADDI64 r34, r254, 0d
|
||||||
|
ST r32, r254, 24a, 8h
|
||||||
|
LI64 r35, 1d
|
||||||
|
ST r35, r254, 32a, 8h
|
||||||
|
ST r35, r254, 16a, 8h
|
||||||
|
BMC r33, r34, 16h
|
||||||
|
JAL r31, r0, :opaque
|
||||||
|
ST r1, r254, 0a, 16h
|
||||||
|
LD r36, r254, 8a, 8h
|
||||||
|
LD r37, r254, 16a, 8h
|
||||||
|
ADD64 r38, r37, r36
|
||||||
|
LD r37, r254, 0a, 8h
|
||||||
|
SUB64 r1, r37, r38
|
||||||
|
LD r31, r254, 40a, 64h
|
||||||
|
ADDI64 r254, r254, 104d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
opaque:
|
||||||
|
ADDI64 r254, r254, -16d
|
||||||
|
LI64 r3, 3d
|
||||||
|
ADDI64 r2, r254, 0d
|
||||||
|
ST r3, r254, 0a, 8h
|
||||||
|
LI64 r6, 2d
|
||||||
|
ST r6, r254, 8a, 8h
|
||||||
|
LD r1, r2, 0a, 16h
|
||||||
|
ADDI64 r254, r254, 16d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 323
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -3,17 +3,18 @@ clobber:
|
||||||
ST r3, r2, 0a, 8h
|
ST r3, r2, 0a, 8h
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -32d
|
ADDI64 r254, r254, -40d
|
||||||
ST r31, r254, 8a, 24h
|
ST r31, r254, 8a, 32h
|
||||||
LI64 r32, 2d
|
|
||||||
ADDI64 r2, r254, 0d
|
ADDI64 r2, r254, 0d
|
||||||
|
LI64 r32, 2d
|
||||||
ST r32, r254, 0a, 8h
|
ST r32, r254, 0a, 8h
|
||||||
JAL r31, r0, :clobber
|
JAL r31, r0, :clobber
|
||||||
LD r33, r254, 0a, 8h
|
LD r33, r254, 0a, 8h
|
||||||
ADDI64 r1, r33, -4d
|
LI64 r34, 4d
|
||||||
LD r31, r254, 8a, 24h
|
SUB64 r1, r34, r33
|
||||||
ADDI64 r254, r254, 32d
|
LD r31, r254, 8a, 32h
|
||||||
|
ADDI64 r254, r254, 40d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 166
|
code size: 169
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,26 +1,23 @@
|
||||||
drop:
|
drop:
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -48d
|
ADDI64 r254, r254, -32d
|
||||||
ST r31, r254, 8a, 40h
|
ST r31, r254, 8a, 24h
|
||||||
|
ADDI64 r2, r254, 0d
|
||||||
LI64 r32, 1d
|
LI64 r32, 1d
|
||||||
ADDI64 r33, r254, 0d
|
|
||||||
ADDI64 r34, r33, 8000d
|
|
||||||
ADDI64 r34, r34, -8000d
|
|
||||||
ST r32, r254, 0a, 8h
|
ST r32, r254, 0a, 8h
|
||||||
CP r2, r34
|
|
||||||
JAL r31, r0, :modify
|
JAL r31, r0, :modify
|
||||||
CP r2, r32
|
CP r2, r32
|
||||||
JAL r31, r0, :drop
|
JAL r31, r0, :drop
|
||||||
LD r35, r34, 0a, 8h
|
LD r33, r254, 0a, 8h
|
||||||
ADDI64 r1, r35, -2d
|
ADDI64 r1, r33, -2d
|
||||||
LD r31, r254, 8a, 40h
|
LD r31, r254, 8a, 24h
|
||||||
ADDI64 r254, r254, 48d
|
ADDI64 r254, r254, 32d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
modify:
|
modify:
|
||||||
LI64 r3, 2d
|
LI64 r3, 2d
|
||||||
ST r3, r2, 0a, 8h
|
ST r3, r2, 0a, 8h
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 212
|
code size: 187
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
6
lang/tests/son_tests_reading_idk.txt
Normal file
6
lang/tests/son_tests_reading_idk.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
main:
|
||||||
|
LI64 r1, 0d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 29
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
48
lang/tests/son_tests_request_page.txt
Normal file
48
lang/tests/son_tests_request_page.txt
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
create_back_buffer:
|
||||||
|
ADDI64 r254, r254, -56d
|
||||||
|
ST r31, r254, 0a, 56h
|
||||||
|
LI64 r32, 255d
|
||||||
|
JGTS r2, r32, :0
|
||||||
|
JAL r31, r0, :request_page
|
||||||
|
JMP :1
|
||||||
|
0: CP r33, r2
|
||||||
|
LI8 r34, 255b
|
||||||
|
CP r2, r34
|
||||||
|
JAL r31, r0, :request_page
|
||||||
|
LI64 r35, 0d
|
||||||
|
CP r2, r33
|
||||||
|
SUB64 r36, r2, r32
|
||||||
|
5: JGTS r36, r35, :2
|
||||||
|
JMP :1
|
||||||
|
2: CP r37, r1
|
||||||
|
JLTS r36, r32, :3
|
||||||
|
CP r2, r34
|
||||||
|
JAL r31, r0, :request_page
|
||||||
|
JMP :4
|
||||||
|
3: CP r2, r36
|
||||||
|
JAL r31, r0, :request_page
|
||||||
|
4: SUB64 r36, r36, r32
|
||||||
|
CP r1, r37
|
||||||
|
JMP :5
|
||||||
|
1: LD r31, r254, 0a, 56h
|
||||||
|
ADDI64 r254, r254, 56d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ST r31, r254, 0a, 8h
|
||||||
|
LI64 r2, 400d
|
||||||
|
JAL r31, r0, :create_back_buffer
|
||||||
|
LD r31, r254, 0a, 8h
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
request_page:
|
||||||
|
LRA r4, r0, :"\0\u{1}xxxxxxxx\0"
|
||||||
|
ST r2, r4, 1a, 1h
|
||||||
|
LI64 r5, 12d
|
||||||
|
LI64 r3, 2d
|
||||||
|
LI64 r2, 3d
|
||||||
|
ECA
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 331
|
||||||
|
ret: 42
|
||||||
|
status: Ok(())
|
27
lang/tests/son_tests_returning_global_struct.txt
Normal file
27
lang/tests/son_tests_returning_global_struct.txt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -100d
|
||||||
|
ST r31, r254, 4a, 96h
|
||||||
|
ADDI64 r32, r254, 0d
|
||||||
|
JAL r31, r0, :random_color
|
||||||
|
ST r1, r254, 0a, 4h
|
||||||
|
LD r33, r254, 0a, 1h
|
||||||
|
LD r34, r254, 1a, 1h
|
||||||
|
LD r35, r254, 2a, 1h
|
||||||
|
ANDI r36, r33, 255d
|
||||||
|
ANDI r37, r34, 255d
|
||||||
|
LD r38, r254, 3a, 1h
|
||||||
|
ANDI r39, r35, 255d
|
||||||
|
ADD64 r40, r37, r36
|
||||||
|
ANDI r41, r38, 255d
|
||||||
|
ADD64 r42, r40, r39
|
||||||
|
ADD64 r1, r42, r41
|
||||||
|
LD r31, r254, 4a, 96h
|
||||||
|
ADDI64 r254, r254, 100d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
random_color:
|
||||||
|
LRA r1, r0, :white
|
||||||
|
LD r1, r1, 0a, 4h
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 241
|
||||||
|
ret: 1020
|
||||||
|
status: Ok(())
|
6
lang/tests/son_tests_signed_to_unsigned_upcast.txt
Normal file
6
lang/tests/son_tests_signed_to_unsigned_upcast.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
main:
|
||||||
|
LI64 r1, 1d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 29
|
||||||
|
ret: 1
|
||||||
|
status: Ok(())
|
12
lang/tests/son_tests_small_struct_assignment.txt
Normal file
12
lang/tests/son_tests_small_struct_assignment.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -4d
|
||||||
|
LRA r2, r0, :white
|
||||||
|
ADDI64 r3, r254, 0d
|
||||||
|
BMC r2, r3, 4h
|
||||||
|
LD r6, r254, 3a, 1h
|
||||||
|
ANDI r1, r6, 255d
|
||||||
|
ADDI64 r254, r254, 4d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 92
|
||||||
|
ret: 255
|
||||||
|
status: Ok(())
|
29
lang/tests/son_tests_small_struct_bitcast.txt
Normal file
29
lang/tests/son_tests_small_struct_bitcast.txt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -36d
|
||||||
|
ST r31, r254, 4a, 32h
|
||||||
|
LRA r32, r0, :white
|
||||||
|
ADDI64 r33, r254, 0d
|
||||||
|
LD r2, r32, 0a, 4h
|
||||||
|
JAL r31, r0, :u32_to_color
|
||||||
|
ST r1, r254, 0a, 4h
|
||||||
|
LD r34, r254, 0a, 1h
|
||||||
|
ANDI r1, r34, 255d
|
||||||
|
LD r31, r254, 4a, 32h
|
||||||
|
ADDI64 r254, r254, 36d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
u32_to_color:
|
||||||
|
ADDI64 r254, r254, -20d
|
||||||
|
ST r31, r254, 4a, 16h
|
||||||
|
JAL r31, r0, :u32_to_u32
|
||||||
|
ADDI64 r32, r254, 0d
|
||||||
|
ST r1, r254, 0a, 4h
|
||||||
|
LD r1, r32, 0a, 4h
|
||||||
|
LD r31, r254, 4a, 16h
|
||||||
|
ADDI64 r254, r254, 20d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
u32_to_u32:
|
||||||
|
CP r1, r2
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 263
|
||||||
|
ret: 255
|
||||||
|
status: Ok(())
|
|
@ -6,11 +6,7 @@ main:
|
||||||
ADDI64 r254, r254, 8d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
some_func:
|
some_func:
|
||||||
ADDI64 r254, r254, -8d
|
|
||||||
ST r31, r254, 0a, 8h
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 133
|
code size: 85
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue