Playing with proc macros

This commit is contained in:
2025-05-23 22:12:24 -07:00
parent 856f817dbe
commit 59392ccad2
8 changed files with 64 additions and 0 deletions
Generated
+8
View File
@@ -16,6 +16,7 @@ dependencies = [
"codepage-437", "codepage-437",
"insta", "insta",
"nom", "nom",
"peg_macro",
"pest", "pest",
] ]
@@ -126,6 +127,13 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "peg_macro"
version = "0.1.0"
dependencies = [
"quote",
]
[[package]] [[package]]
name = "pest" name = "pest"
version = "2.8.0" version = "2.8.0"
+4
View File
@@ -8,6 +8,7 @@ edition = "2024"
[dependencies] [dependencies]
anyhow = "1.0.86" anyhow = "1.0.86"
codepage-437 = "0.1.0" codepage-437 = "0.1.0"
peg_macro = { path = "./peg_macro"}
insta = "1.39.0" insta = "1.39.0"
nom = "7.1.3" nom = "7.1.3"
pest = "2.7.15" pest = "2.7.15"
@@ -22,3 +23,6 @@ similar.opt-level = 3
[[bin]] [[bin]]
name = "zasm" name = "zasm"
path = "src/main.rs" path = "src/main.rs"
[workspace]
members = [".", "peg_macro"]
+1
View File
@@ -0,0 +1 @@
/target
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "peg_macro"
version = "0.1.0"
edition = "2024"
[lib]
proc-macro = true
[dependencies]
quote = "1.0.40"
+27
View File
@@ -0,0 +1,27 @@
use proc_macro::TokenStream;
use quote::quote;
#[proc_macro]
pub fn grammar(ts: TokenStream) -> TokenStream {
let token = ts.into_iter().next().expect("must have at least one token");
let result = match token {
proc_macro::TokenTree::Literal(literal) => {
let s = literal.to_string();
let c = s.chars().next().unwrap_or('\0');
match c {
'0'..'9' => {
let val: usize = s.parse().unwrap();
quote! { Some(crate::peg::Foo::Bar(#val)) }
}
'"' => {
let inner = &s[1..s.len() - 1];
quote! { Some(crate::peg::Foo::Baz(#inner.into())) }
}
_ => quote! { None },
}
}
_ => quote! { None },
};
quote! { println!("Hello, world! {:?}", #result); }.into()
}
+5
View File
@@ -1,15 +1,20 @@
mod encoding; mod encoding;
mod labels; mod labels;
mod peg;
mod preprocess; mod preprocess;
mod world; mod world;
use anyhow::anyhow; use anyhow::anyhow;
use labels::labels::print_labels; use labels::labels::print_labels;
use peg_macro::grammar;
use preprocess::eval::Context; use preprocess::eval::Context;
use std::{env, error::Error, fs, path::PathBuf, process::exit}; use std::{env, error::Error, fs, path::PathBuf, process::exit};
use world::World; use world::World;
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
grammar!(123);
grammar!("abc");
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if args.len() != 2 { if args.len() != 2 {
eprintln!("Usage: {} WORLD_FILE", args[0]); eprintln!("Usage: {} WORLD_FILE", args[0]);
+3
View File
@@ -0,0 +1,3 @@
pub mod peg;
pub use peg::*;
+6
View File
@@ -0,0 +1,6 @@
#[derive(Debug)]
#[allow(dead_code)]
pub enum Foo {
Bar(usize),
Baz(String),
}