diff --git a/.mise.toml b/.mise.toml index 4087423..2fec96e 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,2 +1,2 @@ [tools] -rust = "nightly-2024-09-09" +rust = "nightly-2024-02-13" diff --git a/Cargo.lock b/Cargo.lock index 4a5d9ab..c5585eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anstream" version = "0.6.15" @@ -66,6 +75,15 @@ dependencies = [ "spin", ] +[[package]] +name = "cc" +version = "1.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +dependencies = [ + "shlex", +] + [[package]] name = "clap" version = "4.5.17" @@ -150,6 +168,12 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + [[package]] name = "proc-macro2" version = "1.0.86" @@ -168,6 +192,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "rust-gb" version = "0.1.0" @@ -181,6 +234,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "spin" version = "0.9.8" @@ -207,6 +266,34 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tree-sitter" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20f4cd3642c47a85052a887d86704f4eac272969f61b686bdd3f772122aabaff" +dependencies = [ + "cc", + "regex", + "regex-syntax", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-c" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e795ad541f7ae6a80d22975296340a75a12a29afd3a7089f4368021613728e17" +dependencies = [ + "cc", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-language" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2545046bd1473dac6c626659cc2567c6c0ff302fc8b84a56c4243378276f7f57" + [[package]] name = "unicode-ident" version = "1.0.13" @@ -362,6 +449,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" name = "xtask-build-rom" version = "0.1.0" dependencies = [ + "cc", "clap", "colored", + "tree-sitter", + "tree-sitter-c", ] diff --git a/source/src/gbdk.rs b/source/src/gbdk/gb.rs similarity index 83% rename from source/src/gbdk.rs rename to source/src/gbdk/gb.rs index 2be439f..0f09907 100644 --- a/source/src/gbdk.rs +++ b/source/src/gbdk/gb.rs @@ -1,12 +1,15 @@ pub mod gb { extern "C" { pub fn delay(delay: u16); + #[link_name="waitpad __preserves_regs(b, c, h, l)"] + pub fn waitpad(mask: u8) -> u8; + #[link_name="waitpad __preserves_regs(a, b, c, d, e, h, l)"] + pub fn waitpadup(); } } pub mod drawing { use core::ffi::c_char; - pub const GRAPHICS_WIDTH: u8 = 160; pub const GRAPHICS_HEIGHT: u8 = 144; @@ -27,7 +30,7 @@ pub mod drawing { pub const AND: u8 = 0x03; extern "C" { - #[link_name="circle __sdcccall(0)"] + #[link_name="circle __sdcccall(0) __preserve_regs(a, b, c)"] pub fn circle(x: u8, y: u8, radius: u8, style: u8); #[link_name="color __sdcccall(0)"] pub fn color(forecolor: u8, backcolor: u8, mode: u8); diff --git a/source/src/gbdk/mod.rs b/source/src/gbdk/mod.rs new file mode 100644 index 0000000..b3679eb --- /dev/null +++ b/source/src/gbdk/mod.rs @@ -0,0 +1 @@ +pub mod gb; diff --git a/source/src/main.rs b/source/src/main.rs index a2d6182..49beae7 100644 --- a/source/src/main.rs +++ b/source/src/main.rs @@ -6,7 +6,7 @@ use core::ffi::c_char; mod gbdk; -use gbdk::drawing::{r#box, circle, color, getpix, gotogxy, gprint, line, plot_point, BLACK, DKGREY, LTGREY, M_FILL, M_NOFILL, SOLID, WHITE, XOR}; +use gbdk::gb::drawing::{r#box, circle, color, getpix, gotogxy, gprint, line, plot_point, BLACK, DKGREY, LTGREY, M_FILL, M_NOFILL, SOLID, WHITE, XOR}; fn linetest(x: u8, y: u8, w: u8) { let w = w as i8; diff --git a/xtask/build-rom/Cargo.toml b/xtask/build-rom/Cargo.toml index 5069af8..4b0cb0b 100644 --- a/xtask/build-rom/Cargo.toml +++ b/xtask/build-rom/Cargo.toml @@ -6,3 +6,8 @@ edition = "2021" [dependencies] clap = { version = "4.5.17", features = ["derive"] } colored = "2.1.0" +tree-sitter = "0.23.0" +tree-sitter-c = "0.23.0" + +[build-dependencies] +cc="*" diff --git a/xtask/build-rom/src/main.rs b/xtask/build-rom/src/main.rs index c3b1bfc..e434591 100644 --- a/xtask/build-rom/src/main.rs +++ b/xtask/build-rom/src/main.rs @@ -1,8 +1,9 @@ use core::str; -use std::{fs, io::{ErrorKind, Write}, process::{self, Command}, str::FromStr}; +use std::{fs::{self, File, OpenOptions}, io::{ErrorKind, Write}, process::{self, Command}, str::FromStr}; use clap::Parser; use colored::Colorize; +use tree_sitter::{self, Query, QueryCursor}; ///Build GB ROM from Rust #[derive(Parser, Debug)] @@ -125,18 +126,6 @@ fn main() { else { println!("{}", "[rustc] Rust -> LLVM-IR compile succeeded".green()); } - - fs::copy("./out/out.ll", "./out/pre.ll").unwrap(); - let postprocess_status = llvm_post_process(); - - - if postprocess_status.is_err() { - println!("{}", "[sed] LLVM-IR postprocess for LLVM-CBE failed".red()); - process::exit(1); - } - else { - println!("{}", "[sed] LLVM-IR postprocess for LLVM-CBE succeeded".green()); - } } if build_from <= BuildChain::LLVM { @@ -162,7 +151,7 @@ fn main() { //Command::new("sed 's/uint8_t\\* memset(uint8_t\\*, uint32_t, uint16_t);/inline uint8_t\\* memset(uint8_t\\* dst, uint8_t c, uint16_t sz) {uint8_t \\*p = dst; while (sz--) *p++ = c; return dst; }/g' -i ./out/main.c").status().unwrap(); //Command::new("sed '/__noreturn void rust_begin_unwind(struct l_struct_core_KD__KD_panic_KD__KD_PanicInfo\\* llvm_cbe_info)/{:a;N;/__builtin_unreachable/{N;N;d};/ }/b;ba}' -i ./out/main.c").status().unwrap(); fs::copy("./out/out.c", "./out/pre.c").unwrap(); - let postprocess_status = c_post_process(); + let postprocess_status = treesitter_process(); if postprocess_status.is_err() { println!("{}", "[sed] C postprocess for SDCC failed".red()); @@ -229,19 +218,47 @@ fn main() { } } -fn llvm_post_process() -> Result<(), std::io::Error> { - //`or disjoint` -> `or` - let s = Command::new("sed") - .args([ - "s/or disjoint/or/g", - "-i", "./out/out.ll", - ]) - .status()?; +fn treesitter_process() -> Result<(), std::io::Error> { + let mut code = fs::read_to_string("./out/out.c")?; + let code_bytes = code.clone(); + let code_bytes = code_bytes.as_bytes(); + let mut parser = tree_sitter::Parser::new(); + parser.set_language(&tree_sitter_c::LANGUAGE.into()).unwrap(); - if !s.success() { - return Err(std::io::Error::new(ErrorKind::NotFound, "sed failed")) + let tree = parser.parse(code_bytes, None).unwrap(); + let query = Query::new(&tree_sitter_c::LANGUAGE.into(), "(function_declarator(identifier)@iden)@decl").unwrap(); + let mut cursor = QueryCursor::new(); + + let mut diff: i32 = 0; + + for qm in cursor.matches(&query, tree.root_node(), code_bytes) { + let node = qm.captures[1].node; + let identifier = node.utf8_text(&code_bytes).unwrap(); + let attributes: Vec<_> = identifier.split("_AC___").collect(); //` __` + + if attributes.len() < 2 { + continue; + } + + match &attributes[..] { + [] | [_] => {}, + [name, attrib @ ..] => { + code.replace_range(((node.start_byte() as i32) + diff) as usize..((node.end_byte() as i32) + diff) as usize, name); + diff += name.len() as i32 - node.byte_range().len() as i32; + let attrib = format!("__{}", attrib.join(" __")); + let attrib = attrib + .replace("_AC_", " ") + .replace("_IC_", "(") + .replace("_JC_", ")") + .replace("_MC_", ","); + println!("{:?}", attrib); + } + } } + let mut file = File::create("./out/out.c")?; + file.write_all(&code.as_bytes())?; + Ok(()) }