diff --git a/src/lang.rs b/src/lang.rs index 851709d..783eacf 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -1,81 +1,84 @@ macro_rules! definition { - {@build ($n:ident structure) ($($t:tt)*) null () } => { - struct $n ($($t)*); - }; - {@build ($n:ident enumeration new ($($f:tt)*) ($m:ident($($mt:tt)*)$($r:tt)*)) () null ()} => { - definition!{@build ($n enumeration ($($f)*) ($m($($mt)*)$($r)*)) () null () $($mt)*} - }; - {@build ($n:ident enumeration ($($f:tt)*) ($m:ident($($mt:tt)*)$($r:tt)*)) ($($t:tt)*) null ()} => { - definition!{@build ($n enumeration new ($($f)*$m($($t)*)) ($($r)*)) () null () } - }; - {@build ($n:ident enumeration new ($($m:ident($($mt:tt)*))*) ()) () null () } => { - definition!{@build ($n enumeration filter () ($($m($($mt)*))*))} - }; + {@build ($n:ident structure) ($($t:tt)*) null () } => { + struct $n ($($t)*); + }; + {@build ($n:ident enumeration new ($($f:tt)*) ($m:ident($($mt:tt)*)$($r:tt)*)) () null ()} => { + definition!{@build ($n enumeration ($($f)*) ($m($($mt)*)$($r)*)) () null () $($mt)*} + }; + {@build ($n:ident enumeration ($($f:tt)*) ($m:ident($($mt:tt)*)$($r:tt)*)) ($($t:tt)*) null ()} => { + definition!{@build ($n enumeration new ($($f)*$m($($t)*)) ($($r)*)) () null () } + }; + {@build ($n:ident enumeration new ($($m:ident($($mt:tt)*))*) ()) () null () } => { + definition!{@build ($n enumeration filter () ($($m($($mt)*))*))} + }; {@build ($n:ident enumeration filter ($($e:tt)*) ($m:ident($($mt:tt)+)$($t:tt)*))} => { - definition!{@build ($n enumeration filter ($($e)*$m($($mt)*),) ($($t)*))} - }; - {@build ($n:ident enumeration filter ($($e:tt)*) ($m:ident()$($t:tt)*))} => { - definition!{@build ($n enumeration filter ($($e)*$m,) ($($t)*))} - }; - {@build ($n:ident enumeration filter ($($e:tt)*) ())} => { - enum $n { + definition!{@build ($n enumeration filter ($($e)*$m($($mt)*),) ($($t)*))} + }; + {@build ($n:ident enumeration filter ($($e:tt)*) ($m:ident()$($t:tt)*))} => { + definition!{@build ($n enumeration filter ($($e)*$m,) ($($t)*))} + }; + {@build ($n:ident enumeration filter ($($e:tt)*) ())} => { + enum $n { $($e)* } - }; - {@build $m:tt ($($t:tt)*) null () $l:literal $($r:tt)*} => { - definition!{@build $m ($($t)*) null () $($r)*} - }; - {@build $m:tt ($($t:tt)*) null () $i:ident $($r:tt)*} => { - definition!{@build $m ($($t)*Box<$i>,) null () $($r)*} - }; + }; + {@build $m:tt ($($t:tt)*) null () $l:literal $($r:tt)*} => { + definition!{@build $m ($($t)*) null () $($r)*} + }; + {@build $m:tt ($($t:tt)*) null () $i:ident $($r:tt)*} => { + definition!{@build $m ($($t)*Box<$i>,) null () $($r)*} + }; {@build $m:tt ($($t:tt)*) option ($a:tt) () $($r:tt)*} => { - definition!{@build $m ($($t)*Option<$a>,) null () $($r)*} - }; - {@build $m:tt ($($t:tt)*) vector ($a:tt) () $($r:tt)*} => { - definition!{@build $m ($($t)*Vec<$a>,) null () $($r)*} - }; - {@build $m:tt ($($t:tt)*) option ($($a:tt)*) () $($r:tt)*} => { - definition!{@build $m ($($t)*Option<($($a),*)>,) null () $($r)*} - }; - {@build $m:tt ($($t:tt)*) vector ($($a:tt)*) () $($r:tt)*} => { - definition!{@build $m ($($t)*Vec<($($a),*)>,) null () $($r)*} - }; - {@build $m:tt ($($t:tt)*) null () [$($b:tt)*] $($r:tt)*} => { - definition!{@build $m ($($t)*) option () ($($b)*) $($r)*} - }; - {@build $m:tt ($($t:tt)*) null () {$($b:tt)*} $($r:tt)*} => { - definition!{@build $m ($($t)*) vector () ($($b)*) $($r)*} - }; - {@build $m:tt ($($t:tt)*) $i:ident ($($a:tt)*) ($l:literal $($b:tt)*) $($r:tt)*} => { - definition!{@build $m ($($t)*) $i ($($a)*) ($($b)*) $($r)*} - }; - {@build $m:tt ($($t:tt)*) $i:ident ($($a:tt)*) ($n:ident $($b:tt)*) $($r:tt)*} => { - definition!{@build $m ($($t)*) $i ($($a)*$n) ($($b)*) $($r)*} - }; + definition!{@build $m ($($t)*Option<$a>,) null () $($r)*} + }; + {@build $m:tt ($($t:tt)*) vector ($a:tt) () $($r:tt)*} => { + definition!{@build $m ($($t)*Vec<$a>,) null () $($r)*} + }; + {@build $m:tt ($($t:tt)*) option ($($a:tt)*) () $($r:tt)*} => { + definition!{@build $m ($($t)*Option<($($a),*)>,) null () $($r)*} + }; + {@build $m:tt ($($t:tt)*) vector ($($a:tt)*) () $($r:tt)*} => { + definition!{@build $m ($($t)*Vec<($($a),*)>,) null () $($r)*} + }; + {@build $m:tt ($($t:tt)*) null () [$($b:tt)*] $($r:tt)*} => { + definition!{@build $m ($($t)*) option () ($($b)*) $($r)*} + }; + {@build $m:tt ($($t:tt)*) null () {$($b:tt)*} $($r:tt)*} => { + definition!{@build $m ($($t)*) vector () ($($b)*) $($r)*} + }; + {@build $m:tt ($($t:tt)*) $i:ident ($($a:tt)*) ($l:literal $($b:tt)*) $($r:tt)*} => { + definition!{@build $m ($($t)*) $i ($($a)*) ($($b)*) $($r)*} + }; + {@build $m:tt ($($t:tt)*) $i:ident ($($a:tt)*) ($n:ident $($b:tt)*) $($r:tt)*} => { + definition!{@build $m ($($t)*) $i ($($a)*$n) ($($b)*) $($r)*} + }; } macro_rules! implement { - {@begin $n:ident $i:ident $($t:tt)*} => { - implement!{@build ($i $n) {} {} $($t)*} + {@begin $n:ident structure $($t:tt)*} => { + implement!{@build (state result) (structure $n) {} {} $($t)*} }; - {@build $m:tt $f:tt {$($f2:tt)*} $s:literal $($t:tt)*} => { - implement!{@build $m $f { + {@begin $n:ident enumeration ($m:ident ($($t2:tt)*)$($t:tt)*)} => { + implement!{@build (state result) (enumeration $m {} ($($t)*) $n) {} {} $($t2)*} + }; + {@build ($st:ident $r:ident) $m:tt $f:tt {$($f2:tt)*} $s:literal $($t:tt)*} => { + implement!{@build ($st $r) $m $f { $($f2)* - state = state.trim_start(); - if state.starts_with($s) { - state = &state[$s.len()..] + $st = $st.trim_start(); + if $st.starts_with($s) { + $st = &$st[$s.len()..] } else { - return Err("error".into()) + return Err("error".to_string()) } } $($t)*} }; - {@build $m:tt {$($f:tt)*} {$($f2:tt)*} $i:ident $($t:tt)*} => { - implement!{@build $m {$($f)*{$($f2)*}} { - let mut result; - match $i::take(state) { + {@build ($s:ident $r:ident) $m:tt {$($f:tt)*} {$($f2:tt)*} $i:ident $($t:tt)*} => { + implement!{@build ($s $r) $m {$($f)*{$($f2)*}} { + let $r; + match $i::consume($s) { Ok((r,s)) => { - state = s; - result = r; + $s = s; + $r = r; } Err(error) => { return Err(error); @@ -83,36 +86,48 @@ macro_rules! implement { } } $($t)*} }; - {@build ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} {$($r:tt)*} $($t:tt)*} => { - implement!{@build (vector {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*} + {@build $va:tt ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} {$($r:tt)*} $($t:tt)*} => { + implement!{@build $va (vector {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*} }; - {@build ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} [$($r:tt)*] $($t:tt)*} => { - implement!{@build (option {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*} + {@build $va:tt ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} [$($r:tt)*] $($t:tt)*} => { + implement!{@build $va (option {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*} }; - {@finish (option {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => { - implement!{@build ($($m)*) {$($l)*} { - let mut result; - let taker = |_state: &str| { - let mut state: &str = _state; + {@finish ($s:ident $re:ident) (option {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => { + implement!{@build ($s $re) ($($m)*) {$($l)*} { + let mut $re; + let taker = move |_state| { + let mut $s: &str = _state; $($f)* - Ok(($({$($r)*result}),*)) + Ok((( + $({$($r)*$re}),* + ),$s)) }; - result = taker(state).ok(); + match taker($s) { + Ok((r,s)) => { + $s = s; + $re = Some(r); + } + Err(error) => { + $re = None; + } + } } $($t)*} }; - {@finish (vector {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => { - implement!{@build ($($m)*) {$($l)*} { - let mut result = Vec::new(); - let taker = |_state: &str| { - let mut state: &str = _state; + {@finish ($s:ident $re:ident) (vector {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => { + implement!{@build ($s $re) ($($m)*) {$($l)*} { + let mut $re = Vec::new(); + let taker = move |_state| { + let mut $s: &str = _state; $($f)* - Ok(($({$($r)*result}),*)) + Ok((( + $({$($r)*$re}),* + ),$s)) }; loop { - match taker(state) { + match taker($s) { Ok((r,s)) => { - state = s; - result.push(r); + $s = s; + $re.push(r); } Err(error) => { break; @@ -121,45 +136,103 @@ macro_rules! implement { } } $($t)*} }; - {@build $m:tt {$($r:tt)*} $r2:tt} => { - implement!{@finish $m {$($r)*$r2}} + {@build $va:tt $m:tt {$($r:tt)*} $r2:tt} => { + implement!{@finish $va $m {$($r)*$r2}} }; - {@finish (structure $n:ident) {{$($f:tt)*}$({$($r:tt)*})*} } => { + {@finish ($s:ident $re:ident) (structure $n:ident) {{$($f:tt)*}$({$($r:tt)*})*} } => { impl Parse for $n { - fn take(_state: &str) -> Result<(Self, &str), Error> where Self: Sized { - let mut state: &str = _state; + fn consume(_state: &str) -> Result<(Self, &str), Error> where Self: Sized { + let mut $s: &str = _state; $($f)* - Ok(($n($({$($r)*result.into()}),*),state)) + Ok(( + $n($({$($r)*$re.into()}),*),$s + )) + } + } + }; + {@finish ($s:ident $re:ident) (enumeration $m2:ident {$($l:tt)*} ($m:ident ($($t2:tt)*)$($t:tt)*) $n:ident) {$f:tt$({$($r:tt)*})+} } => { + implement!{@build ($s $re) (enumeration $m {$($l)*{ + $f + Ok(( + $n::$m2($({$($r)*$re.into()}),+),$s + )) + }} ($($t)*) $n) {} {} $($t2)*} + }; + {@finish ($s:ident $re:ident) (enumeration $m3:ident {$($l:tt)*} ($m:ident ($($t2:tt)*)$($t:tt)*) $n:ident) {$f:tt} } => { + implement!{@build ($s $re) (enumeration $m {$($l)*{ + $f + Ok(( + $n::$m3,$s + )) + }} ($($t)*) $n) {} {} $($t2)*} + }; + {@finish ($s:ident $re:ident) (enumeration $m2:ident {$($l:tt)*} () $n:ident) {$f:tt$({$($r:tt)*})+}} => { + implement!{@finish ($s $re) (enumeration {$($l)*{ + $f + Ok(( + $n::$m2($({$($r)*$re.into()}),+),$s + )) + }} () $n)} // straight to below + }; + {@finish ($s:ident $re:ident) (enumeration $m2:ident {$($l:tt)*} () $n:ident) {$f:tt}} => { + implement!{@finish ($s $re) (enumeration {$($l)*{ + $f + Ok(( + $n::$m2,$s + )) + }} () $n)} // straight to below + }; + {@finish ($s:ident $re:ident) (enumeration {$($f:tt)*} () $n:ident)} => { + impl Parse for $n { + fn consume(_state: &str) -> Result<(Self, &str), Error> where Self: Sized { + let mut $s: &str = _state; + $( + let case = $f; + if case.is_ok() { + return case; + } + )* + Err("error".into()) } } }; } macro_rules! class { - ($i:ident($($t:tt)*)) => { - definition!{@build ($i structure) () null () $($t)*} + ($i:ident($($t:tt)*)) => { + definition!{@build ($i structure) () null () $($t)*} implement!{@begin $i structure $($t)*} - }; - ($i:ident{$($n:ident($($t:tt)*)),*}) => { - definition!{@build ($i enumeration new () ($($n($($t)*))*)) () null ()} - } + }; + ($i:ident{$($n:ident($($t:tt)*)),*}) => { + definition!{@build ($i enumeration new () ($($n($($t)*))*)) () null ()} + implement!{@begin $i enumeration ($($n($($t)*))*)} + } } macro_rules! parser { - () => {}; - ($i:ident$t:tt;$($tail:tt)*) => { - class!($i$t); - parser!($($tail)*); - }; + () => {}; + ($i:ident$t:tt;$($tail:tt)*) => { + class!($i$t); + parser!($($tail)*); + }; } struct Number(String); struct Name(String); type Error = String; trait Parse { - fn take(state: &str) -> Result<(Self, &str), Error> + fn consume(state: &str) -> Result<(Self, &str), Error> where Self: Sized; } + +impl Parse for Name { + fn consume(state: &str) -> Result<(Self, &str), Error> + where + Self: Sized + { + todo!() + } +} impl Parse for String { - fn take(state: &str) -> Result<(Self, &str), Error> + fn consume(state: &str) -> Result<(Self, &str), Error> where Self: Sized { @@ -167,133 +240,126 @@ impl Parse for String { } } -fn g() -> Result { - Ok(Chunk( - { - if 1 == 2 { - Box::new(Block(Vec::new(),None)) - } else { - return Err(()) - } - } - )) +impl Parse for Number { + fn consume(state: &str) -> Result<(Self, &str), Error> + where + Self: Sized + { + todo!() + } } -parser! { - Chunk3 ( "Pookie" Block "Dookie" ); -} +parser!( + Block2 ( {Statement} [Return] ); +); parser! { - Block2 ( {Statement} [Return] ); -} - -parser! { - // LiteralString -> "..." - // LiteralNumber -> 0x... 123.456 - Chunk ( Block ); - Block ( {Statement} [Return] ); - Statement { - Semicolon (";"), - Assignment (Variables "=" Expressions), - Call (FunctionCall), - Label (Label), - Break ("break"), - Goto ("goto" Name), - Do ("do" Block "end"), - While ("while" Expression "do" Block "end"), - Repeat ("repeat" Block "until" Expression), - If ("if" Expression "then" Block {"elseif" Expression "then" Block} ["else" Block] "end"), - ForRange ("for" Name "=" Expression "," Expression ["," Expression] "do" Block "end"), - ForIn ("for" Names "in" Expressions "do" Block "end"), - Function ("function" FunctionName FunctionBody), - LocalFunction ("local" "function" Name FunctionBody), - GlobalFunction ("global" "function" Name FunctionBody), - Declaration ("local" Names ["=" Expressions]), - Global ("global" Names) - }; - Return( "return" [Expressions] [";"] ); - Label( "::" Name "::" ); - FunctionName( Name {"." Name} [":" Name] ); - Variables( Variable {"," Variable} ); - Variable { - Name (Name), - Index (PrefixExpression "[" Expression "]"), - DotIndex (PrefixExpression "." Name) - }; - Names( Name {"," Name} ); - Expressions( Expression {"," Expression} ); - Expression { - Nil ("nil"), - False ("false"), - True ("true"), - Number (Number), - String (String), - VarArg ("..."), - FunctionDef (FunctionDef), - PrefixExpression (PrefixExpression), - Table (Table), - Binary (Expression BinaryOp Expression), - Unary (UnaryOp Expression) - }; - PrefixExpression { - Variable (Variable), - Call (FunctionCall), - Expression ("(" Expression ")") - }; - FunctionCall { - Normal (PrefixExpression Arguments), - Instanced (PrefixExpression ":" Name Arguments) - }; - Arguments { - Expressions ("(" [Expressions] ")"), - Table (Table), - String (String) - }; - FunctionDef( "function" FunctionBody ); - FunctionBody( "(" [Parameters] ")" Block "end" ); - Parameters { - Names (Names ["," VarArg]), - VarArg (VarArg) - }; - VarArg( "..." [Name] ); - Table( "{" [Fields] "}" ); - Fields( Field {FieldSep Field} [FieldSep] ); - Field { - ExpressionIndex ("[" Expression "]" "=" Expression), - Name (Name "=" Expression), - Expression (Expression) - }; - FieldSep { - Comma (","), - Semicolon (";") - }; - BinaryOp { - Plus ("+"), - Minus ("-"), - Mul ("*"), - Divide ("/"), - DivFloor ("//"), - Caret ("^"), - Modulo ("%"), - Ampersand ("&"), - Tilde ("~"), - Pipe ("|"), - ShiftRight (">>"), - ShiftLeft ("<<"), - Concat (".."), - Less ("<"), - LessEqual ("<="), - Greater (">"), - GreatEqual (">="), - Equivalent ("=="), - NotEqual ("~="), - And ("and"), - Or ("or") - }; - UnaryOp { - Negate ("-"), - Not ("!"), - Ampersand ("#"), - Tilde ("~") - }; -} + // LiteralString -> "..." + // LiteralNumber -> 0x... 123.456 + Chunk ( Block ); + Block ( {Statement} [Return Name] ); + Statement { + Semicolon (";"), + Assignment (Variables "=" Expressions), + Call (FunctionCall), + Label (Label), + Break ("break"), + Goto ("goto" Name), + Do ("do" Block "end"), + While ("while" Expression "do" Block "end"), + Repeat ("repeat" Block "until" Expression), + If ("if" Expression "then" Block {"elseif" Expression "then" Block} ["else" Block] "end"), + ForRange ("for" Name "=" Expression "," Expression ["," Expression] "do" Block "end"), + ForIn ("for" Names "in" Expressions "do" Block "end"), + Function ("function" FunctionName FunctionBody), + LocalFunction ("local" "function" Name FunctionBody), + GlobalFunction ("global" "function" Name FunctionBody), + Declaration ("local" Names ["=" Expressions]), + Global ("global" Names) + }; + Return( "return" [Expressions] [";"] ); + Label( "::" Name "::" ); + FunctionName( Name {"." Name} [":" Name] ); + Variables( Variable {"," Variable} ); + Variable { + Name (Name), + Index (PrefixExpression "[" Expression "]"), + DotIndex (PrefixExpression "." Name) + }; + Names( Name {"," Name} ); + Expressions( Expression {"," Expression} ); + Expression { + Nil ("nil"), + False ("false"), + True ("true"), + Number (Number), + String (String), + VarArg ("..."), + FunctionDef (FunctionDef), + PrefixExpression (PrefixExpression), + Table (Table), + Binary (Expression BinaryOp Expression), + Unary (UnaryOp Expression) + }; + PrefixExpression { + Variable (Variable), + Call (FunctionCall), + Expression ("(" Expression ")") + }; + FunctionCall { + Normal (PrefixExpression Arguments), + Instanced (PrefixExpression ":" Name Arguments) + }; + Arguments { + Expressions ("(" [Expressions] ")"), + Table (Table), + String (String) + }; + FunctionDef( "function" FunctionBody ); + FunctionBody( "(" [Parameters] ")" Block "end" ); + Parameters { + Names (Names ["," VarArg]), + VarArg (VarArg) + }; + VarArg( "..." [Name] ); + Table( "{" [Fields] "}" ); + Fields( Field {FieldSep Field} [FieldSep] ); + Field { + ExpressionIndex ("[" Expression "]" "=" Expression), + Name (Name "=" Expression), + Expression (Expression) + }; + FieldSep { + Comma (","), + Semicolon (";") + }; + BinaryOp { + Plus ("+"), + Minus ("-"), + Mul ("*"), + Divide ("/"), + DivFloor ("//"), + Caret ("^"), + Modulo ("%"), + Ampersand ("&"), + Tilde ("~"), + Pipe ("|"), + ShiftRight (">>"), + ShiftLeft ("<<"), + Concat (".."), + Less ("<"), + LessEqual ("<="), + Greater (">"), + GreatEqual (">="), + Equivalent ("=="), + NotEqual ("~="), + And ("and"), + Or ("or") + }; + UnaryOp { + Negate ("-"), + Not ("!"), + Ampersand ("#"), + Tilde ("~") + }; +} \ No newline at end of file diff --git a/src/test.png b/src/test.png old mode 100644 new mode 100755 index 240be72..9de6980 Binary files a/src/test.png and b/src/test.png differ