Add examples with cargo run --example support
- Move .mrs files into misses-compiler/examples/ alongside .rs runners - Add lib.rs exposing parse/codegen for use by example binaries and main.rs - Fix parser: #[attr] vs #[a => b] disambiguation (look for => before ]) - Fix parser: `for` keyword in `impl Foo for Bar` no longer triggers spread (is_spread_for lookahead: must match `for <ident> in $<ident> =>`) - Add derive_getters.mrs: getter methods via spread iteration - Add make_id_type.mrs: newtype u64 wrapper with From impls, derive attrs Run with: cargo run --example hello|derive_builder|declare_table|derive_getters|make_id_type https://claude.ai/code/session_01Tppkab4eLsL21asHGjQJoF
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
// declare_table.mrs — DSL-to-struct mapping
|
||||
// Demonstrates: $body:tt raw token capture, escape block calling misses_rt,
|
||||
// expression injection of a &str
|
||||
macro declare_table! {
|
||||
$name:ident { $body:tt } => {
|
||||
@{
|
||||
let table_str = misses_rt::to_table_name(&name);
|
||||
}
|
||||
T~{
|
||||
pub struct $name {
|
||||
pub id: u64,
|
||||
}
|
||||
impl $name {
|
||||
pub const TABLE: &'static str = ${ table_str.as_str() };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fn main() {
|
||||
let src = include_str!("declare_table.mrs");
|
||||
let bar = "=".repeat(60);
|
||||
println!("{bar}");
|
||||
println!("SOURCE declare_table.mrs");
|
||||
println!("{bar}");
|
||||
println!("{}", src.trim());
|
||||
println!();
|
||||
|
||||
match misses::parse(src) {
|
||||
Err(e) => eprintln!("parse error: {e}"),
|
||||
Ok(ast) => {
|
||||
let generated = misses::codegen(&ast);
|
||||
println!("{bar}");
|
||||
println!("GENERATED");
|
||||
println!("{bar}");
|
||||
println!("{}", generated.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// derive_builder.mrs — builder pattern generator
|
||||
// Demonstrates: struct pattern, variadic field binding, escape block,
|
||||
// expression injection, spread iteration in struct and impl bodies
|
||||
macro derive_builder! {
|
||||
struct $name:ident { $($field:ident : $ty:ty),* } => {
|
||||
@{
|
||||
let builder_name = format_ident!("{}_Builder", name.to_string());
|
||||
}
|
||||
T~{
|
||||
pub struct ${ builder_name } {
|
||||
for field in $fields =>
|
||||
pub $field.name: Option<$field.ty>,
|
||||
}
|
||||
impl ${ builder_name } {
|
||||
pub fn build(self) -> $name {
|
||||
$name {
|
||||
for field in $fields =>
|
||||
$field.name: self.$field.name.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fn main() {
|
||||
let src = include_str!("derive_builder.mrs");
|
||||
let bar = "=".repeat(60);
|
||||
println!("{bar}");
|
||||
println!("SOURCE derive_builder.mrs");
|
||||
println!("{bar}");
|
||||
println!("{}", src.trim());
|
||||
println!();
|
||||
|
||||
match misses::parse(src) {
|
||||
Err(e) => eprintln!("parse error: {e}"),
|
||||
Ok(ast) => {
|
||||
let generated = misses::codegen(&ast);
|
||||
println!("{bar}");
|
||||
println!("GENERATED");
|
||||
println!("{bar}");
|
||||
println!("{}", generated.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// derive_getters.mrs — auto-generate getter methods
|
||||
// Demonstrates: struct pattern, variadic binding, spread iteration generating
|
||||
// impl methods with reference return types
|
||||
macro derive_getters! {
|
||||
struct $name:ident { $($field:ident : $ty:ty),* } => {
|
||||
T~{
|
||||
impl $name {
|
||||
for field in $fields =>
|
||||
pub fn $field.name(&self) -> &$field.ty { &self.$field.name }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fn main() {
|
||||
let src = include_str!("derive_getters.mrs");
|
||||
let bar = "=".repeat(60);
|
||||
println!("{bar}");
|
||||
println!("SOURCE derive_getters.mrs");
|
||||
println!("{bar}");
|
||||
println!("{}", src.trim());
|
||||
println!();
|
||||
|
||||
match misses::parse(src) {
|
||||
Err(e) => eprintln!("parse error: {e}"),
|
||||
Ok(ast) => {
|
||||
let generated = misses::codegen(&ast);
|
||||
println!("{bar}");
|
||||
println!("GENERATED");
|
||||
println!("{bar}");
|
||||
println!("{}", generated.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// hello.mrs — smoke test
|
||||
// Demonstrates: single ident binding, ident construction with #[a => b]
|
||||
macro hello! {
|
||||
$name:ident => {
|
||||
T~{
|
||||
pub fn #[say => $name]() -> &'static str {
|
||||
"hello from the macro!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
fn main() {
|
||||
let src = include_str!("hello.mrs");
|
||||
show("hello.mrs", src);
|
||||
}
|
||||
|
||||
fn show(name: &str, src: &str) {
|
||||
let bar = "=".repeat(60);
|
||||
println!("{bar}");
|
||||
println!("SOURCE {name}");
|
||||
println!("{bar}");
|
||||
println!("{}", src.trim());
|
||||
println!();
|
||||
|
||||
match misses::parse(src) {
|
||||
Err(e) => eprintln!("parse error: {e}"),
|
||||
Ok(ast) => {
|
||||
let generated = misses::codegen(&ast);
|
||||
println!("{bar}");
|
||||
println!("GENERATED");
|
||||
println!("{bar}");
|
||||
println!("{}", generated.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// make_id_type.mrs — newtype ID wrapper generator
|
||||
// Demonstrates: single ident binding, multi-line template output,
|
||||
// derive attributes, impl blocks, no escape block needed
|
||||
macro make_id_type! {
|
||||
$name:ident => {
|
||||
T~{
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct $name(pub u64);
|
||||
|
||||
impl $name {
|
||||
pub fn new(val: u64) -> Self { Self(val) }
|
||||
pub fn value(self) -> u64 { self.0 }
|
||||
}
|
||||
|
||||
impl From<u64> for $name {
|
||||
fn from(val: u64) -> Self { Self(val) }
|
||||
}
|
||||
|
||||
impl From<$name> for u64 {
|
||||
fn from(id: $name) -> Self { id.0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
fn main() {
|
||||
let src = include_str!("make_id_type.mrs");
|
||||
let bar = "=".repeat(60);
|
||||
println!("{bar}");
|
||||
println!("SOURCE make_id_type.mrs");
|
||||
println!("{bar}");
|
||||
println!("{}", src.trim());
|
||||
println!();
|
||||
|
||||
match misses::parse(src) {
|
||||
Err(e) => eprintln!("parse error: {e}"),
|
||||
Ok(ast) => {
|
||||
let generated = misses::codegen(&ast);
|
||||
println!("{bar}");
|
||||
println!("GENERATED");
|
||||
println!("{bar}");
|
||||
println!("{}", generated.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user