Compare commits

...

2 Commits

3 changed files with 294 additions and 229 deletions
-1
View File
@@ -19,7 +19,6 @@ log = "0.4"
wgpu = "29.0.3" wgpu = "29.0.3"
pollster = "0.4.0" pollster = "0.4.0"
console_error_panic_hook = "0.1.7" console_error_panic_hook = "0.1.7"
parse = { path = "./parse" }
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6" console_error_panic_hook = "0.1.6"
+294 -228
View File
@@ -1,81 +1,84 @@
macro_rules! definition { macro_rules! definition {
{@build ($n:ident structure) ($($t:tt)*) null () } => { {@build ($n:ident structure) ($($t:tt)*) null () } => {
struct $n ($($t)*); struct $n ($($t)*);
}; };
{@build ($n:ident enumeration new ($($f:tt)*) ($m:ident($($mt:tt)*)$($r:tt)*)) () null ()} => { {@build ($n:ident enumeration new ($($f:tt)*) ($m:ident($($mt:tt)*)$($r:tt)*)) () null ()} => {
definition!{@build ($n enumeration ($($f)*) ($m($($mt)*)$($r)*)) () null () $($mt)*} 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 ()} => { {@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 () } definition!{@build ($n enumeration new ($($f)*$m($($t)*)) ($($r)*)) () null () }
}; };
{@build ($n:ident enumeration new ($($m:ident($($mt:tt)*))*) ()) () null () } => { {@build ($n:ident enumeration new ($($m:ident($($mt:tt)*))*) ()) () null () } => {
definition!{@build ($n enumeration filter () ($($m($($mt)*))*))} definition!{@build ($n enumeration filter () ($($m($($mt)*))*))}
}; };
{@build ($n:ident enumeration filter ($($e:tt)*) ($m:ident($($mt:tt)+)$($t:tt)*))} => { {@build ($n:ident enumeration filter ($($e:tt)*) ($m:ident($($mt:tt)+)$($t:tt)*))} => {
definition!{@build ($n enumeration filter ($($e)*$m($($mt)*),) ($($t)*))} definition!{@build ($n enumeration filter ($($e)*$m($($mt)*),) ($($t)*))}
}; };
{@build ($n:ident enumeration filter ($($e:tt)*) ($m:ident()$($t:tt)*))} => { {@build ($n:ident enumeration filter ($($e:tt)*) ($m:ident()$($t:tt)*))} => {
definition!{@build ($n enumeration filter ($($e)*$m,) ($($t)*))} definition!{@build ($n enumeration filter ($($e)*$m,) ($($t)*))}
}; };
{@build ($n:ident enumeration filter ($($e:tt)*) ())} => { {@build ($n:ident enumeration filter ($($e:tt)*) ())} => {
enum $n { enum $n {
$($e)* $($e)*
} }
}; };
{@build $m:tt ($($t:tt)*) null () $l:literal $($r:tt)*} => { {@build $m:tt ($($t:tt)*) null () $l:literal $($r:tt)*} => {
definition!{@build $m ($($t)*) null () $($r)*} definition!{@build $m ($($t)*) null () $($r)*}
}; };
{@build $m:tt ($($t:tt)*) null () $i:ident $($r:tt)*} => { {@build $m:tt ($($t:tt)*) null () $i:ident $($r:tt)*} => {
definition!{@build $m ($($t)*Box<$i>,) null () $($r)*} definition!{@build $m ($($t)*Box<$i>,) null () $($r)*}
}; };
{@build $m:tt ($($t:tt)*) option ($a:tt) () $($r:tt)*} => { {@build $m:tt ($($t:tt)*) option ($a:tt) () $($r:tt)*} => {
definition!{@build $m ($($t)*Option<$a>,) null () $($r)*} definition!{@build $m ($($t)*Option<$a>,) null () $($r)*}
}; };
{@build $m:tt ($($t:tt)*) vector ($a:tt) () $($r:tt)*} => { {@build $m:tt ($($t:tt)*) vector ($a:tt) () $($r:tt)*} => {
definition!{@build $m ($($t)*Vec<$a>,) null () $($r)*} definition!{@build $m ($($t)*Vec<$a>,) null () $($r)*}
}; };
{@build $m:tt ($($t:tt)*) option ($($a:tt)*) () $($r:tt)*} => { {@build $m:tt ($($t:tt)*) option ($($a:tt)*) () $($r:tt)*} => {
definition!{@build $m ($($t)*Option<($($a),*)>,) null () $($r)*} definition!{@build $m ($($t)*Option<($($a),*)>,) null () $($r)*}
}; };
{@build $m:tt ($($t:tt)*) vector ($($a:tt)*) () $($r:tt)*} => { {@build $m:tt ($($t:tt)*) vector ($($a:tt)*) () $($r:tt)*} => {
definition!{@build $m ($($t)*Vec<($($a),*)>,) null () $($r)*} definition!{@build $m ($($t)*Vec<($($a),*)>,) null () $($r)*}
}; };
{@build $m:tt ($($t:tt)*) null () [$($b:tt)*] $($r:tt)*} => { {@build $m:tt ($($t:tt)*) null () [$($b:tt)*] $($r:tt)*} => {
definition!{@build $m ($($t)*) option () ($($b)*) $($r)*} definition!{@build $m ($($t)*) option () ($($b)*) $($r)*}
}; };
{@build $m:tt ($($t:tt)*) null () {$($b:tt)*} $($r:tt)*} => { {@build $m:tt ($($t:tt)*) null () {$($b:tt)*} $($r:tt)*} => {
definition!{@build $m ($($t)*) vector () ($($b)*) $($r)*} definition!{@build $m ($($t)*) vector () ($($b)*) $($r)*}
}; };
{@build $m:tt ($($t:tt)*) $i:ident ($($a:tt)*) ($l:literal $($b:tt)*) $($r:tt)*} => { {@build $m:tt ($($t:tt)*) $i:ident ($($a:tt)*) ($l:literal $($b:tt)*) $($r:tt)*} => {
definition!{@build $m ($($t)*) $i ($($a)*) ($($b)*) $($r)*} definition!{@build $m ($($t)*) $i ($($a)*) ($($b)*) $($r)*}
}; };
{@build $m:tt ($($t:tt)*) $i:ident ($($a:tt)*) ($n:ident $($b:tt)*) $($r:tt)*} => { {@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)*) $i ($($a)*$n) ($($b)*) $($r)*}
}; };
} }
macro_rules! implement { macro_rules! implement {
{@begin $n:ident $i:ident $($t:tt)*} => { {@begin $n:ident structure $($t:tt)*} => {
implement!{@build ($i $n) {} {} $($t)*} implement!{@build (state result) (structure $n) {} {} $($t)*}
}; };
{@build $m:tt $f:tt {$($f2:tt)*} $s:literal $($t:tt)*} => { {@begin $n:ident enumeration ($m:ident ($($t2:tt)*)$($t:tt)*)} => {
implement!{@build $m $f { 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)* $($f2)*
state = state.trim_start(); $st = $st.trim_start();
if state.starts_with($s) { if $st.starts_with($s) {
state = &state[$s.len()..] $st = &$st[$s.len()..]
} else { } else {
return Err("error".into()) return Err("error".to_string())
} }
} $($t)*} } $($t)*}
}; };
{@build $m:tt {$($f:tt)*} {$($f2:tt)*} $i:ident $($t:tt)*} => { {@build ($s:ident $r:ident) $m:tt {$($f:tt)*} {$($f2:tt)*} $i:ident $($t:tt)*} => {
implement!{@build $m {$($f)*{$($f2)*}} { implement!{@build ($s $r) $m {$($f)*{$($f2)*}} {
let mut result; let $r;
match $i::take(state) { match $i::consume($s) {
Ok((r,s)) => { Ok((r,s)) => {
state = s; $s = s;
result = r; $r = r;
} }
Err(error) => { Err(error) => {
return Err(error); return Err(error);
@@ -83,36 +86,48 @@ macro_rules! implement {
} }
} $($t)*} } $($t)*}
}; };
{@build ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} {$($r:tt)*} $($t:tt)*} => { {@build $va:tt ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} {$($r:tt)*} $($t:tt)*} => {
implement!{@build (vector {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*} implement!{@build $va (vector {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*}
}; };
{@build ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} [$($r:tt)*] $($t:tt)*} => { {@build $va:tt ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} [$($r:tt)*] $($t:tt)*} => {
implement!{@build (option {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*} implement!{@build $va (option {$($f)*{$($f2)*}} ($($t)*) $($m)*) {} {} $($r)*}
}; };
{@finish (option {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => { {@finish ($s:ident $re:ident) (option {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => {
implement!{@build ($($m)*) {$($l)*} { implement!{@build ($s $re) ($($m)*) {$($l)*} {
let mut result; let mut $re;
let taker = |_state: &str| { let taker = move |_state| {
let mut state: &str = _state; let mut $s: &str = _state;
$($f)* $($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)*} } $($t)*}
}; };
{@finish (vector {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => { {@finish ($s:ident $re:ident) (vector {$($l:tt)*} ($($t:tt)*) $($m:tt)*) {{$($f:tt)*}$({$($r:tt)*})*} } => {
implement!{@build ($($m)*) {$($l)*} { implement!{@build ($s $re) ($($m)*) {$($l)*} {
let mut result = Vec::new(); let mut $re = Vec::new();
let taker = |_state: &str| { let taker = move |_state| {
let mut state: &str = _state; let mut $s: &str = _state;
$($f)* $($f)*
Ok(($({$($r)*result}),*)) Ok(((
$({$($r)*$re}),*
),$s))
}; };
loop { loop {
match taker(state) { match taker($s) {
Ok((r,s)) => { Ok((r,s)) => {
state = s; $s = s;
result.push(r); $re.push(r);
} }
Err(error) => { Err(error) => {
break; break;
@@ -121,45 +136,103 @@ macro_rules! implement {
} }
} $($t)*} } $($t)*}
}; };
{@build $m:tt {$($r:tt)*} $r2:tt} => { {@build $va:tt $m:tt {$($r:tt)*} $r2:tt} => {
implement!{@finish $m {$($r)*$r2}} 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 { impl Parse for $n {
fn take(_state: &str) -> Result<(Self, &str), Error> where Self: Sized { fn consume(_state: &str) -> Result<(Self, &str), Error> where Self: Sized {
let mut state: &str = _state; let mut $s: &str = _state;
$($f)* $($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 { macro_rules! class {
($i:ident($($t:tt)*)) => { ($i:ident($($t:tt)*)) => {
definition!{@build ($i structure) () null () $($t)*} definition!{@build ($i structure) () null () $($t)*}
implement!{@begin $i structure $($t)*} implement!{@begin $i structure $($t)*}
}; };
($i:ident{$($n:ident($($t:tt)*)),*}) => { ($i:ident{$($n:ident($($t:tt)*)),*}) => {
definition!{@build ($i enumeration new () ($($n($($t)*))*)) () null ()} definition!{@build ($i enumeration new () ($($n($($t)*))*)) () null ()}
} implement!{@begin $i enumeration ($($n($($t)*))*)}
}
} }
macro_rules! parser { macro_rules! parser {
() => {}; () => {};
($i:ident$t:tt;$($tail:tt)*) => { ($i:ident$t:tt;$($tail:tt)*) => {
class!($i$t); class!($i$t);
parser!($($tail)*); parser!($($tail)*);
}; };
} }
struct Number(String); struct Number(String);
struct Name(String); struct Name(String);
type Error = String; type Error = String;
trait Parse { trait Parse {
fn take(state: &str) -> Result<(Self, &str), Error> fn consume(state: &str) -> Result<(Self, &str), Error>
where Self: Sized; where Self: Sized;
} }
impl Parse for Name {
fn consume(state: &str) -> Result<(Self, &str), Error>
where
Self: Sized
{
todo!()
}
}
impl Parse for String { impl Parse for String {
fn take(state: &str) -> Result<(Self, &str), Error> fn consume(state: &str) -> Result<(Self, &str), Error>
where where
Self: Sized Self: Sized
{ {
@@ -167,133 +240,126 @@ impl Parse for String {
} }
} }
fn g() -> Result<Chunk,()> { impl Parse for Number {
Ok(Chunk( fn consume(state: &str) -> Result<(Self, &str), Error>
{ where
if 1 == 2 { Self: Sized
Box::new(Block(Vec::new(),None)) {
} else { todo!()
return Err(()) }
}
}
))
} }
parser! { parser!(
Chunk3 ( "Pookie" Block "Dookie" ); Block2 ( {Statement} [Return] );
} );
parser! { parser! {
Block2 ( {Statement} [Return] ); // LiteralString -> "..."
} // LiteralNumber -> 0x... 123.456
Chunk ( Block );
parser! { Block ( {Statement} [Return Name] );
// LiteralString -> "..." Statement {
// LiteralNumber -> 0x... 123.456 Semicolon (";"),
Chunk ( Block ); Assignment (Variables "=" Expressions),
Block ( {Statement} [Return] ); Call (FunctionCall),
Statement { Label (Label),
Semicolon (";"), Break ("break"),
Assignment (Variables "=" Expressions), Goto ("goto" Name),
Call (FunctionCall), Do ("do" Block "end"),
Label (Label), While ("while" Expression "do" Block "end"),
Break ("break"), Repeat ("repeat" Block "until" Expression),
Goto ("goto" Name), If ("if" Expression "then" Block {"elseif" Expression "then" Block} ["else" Block] "end"),
Do ("do" Block "end"), ForRange ("for" Name "=" Expression "," Expression ["," Expression] "do" Block "end"),
While ("while" Expression "do" Block "end"), ForIn ("for" Names "in" Expressions "do" Block "end"),
Repeat ("repeat" Block "until" Expression), Function ("function" FunctionName FunctionBody),
If ("if" Expression "then" Block {"elseif" Expression "then" Block} ["else" Block] "end"), LocalFunction ("local" "function" Name FunctionBody),
ForRange ("for" Name "=" Expression "," Expression ["," Expression] "do" Block "end"), GlobalFunction ("global" "function" Name FunctionBody),
ForIn ("for" Names "in" Expressions "do" Block "end"), Declaration ("local" Names ["=" Expressions]),
Function ("function" FunctionName FunctionBody), Global ("global" Names)
LocalFunction ("local" "function" Name FunctionBody), };
GlobalFunction ("global" "function" Name FunctionBody), Return( "return" [Expressions] [";"] );
Declaration ("local" Names ["=" Expressions]), Label( "::" Name "::" );
Global ("global" Names) FunctionName( Name {"." Name} [":" Name] );
}; Variables( Variable {"," Variable} );
Return( "return" [Expressions] [";"] ); Variable {
Label( "::" Name "::" ); Name (Name),
FunctionName( Name {"." Name} [":" Name] ); Index (PrefixExpression "[" Expression "]"),
Variables( Variable {"," Variable} ); DotIndex (PrefixExpression "." Name)
Variable { };
Name (Name), Names( Name {"," Name} );
Index (PrefixExpression "[" Expression "]"), Expressions( Expression {"," Expression} );
DotIndex (PrefixExpression "." Name) Expression {
}; Nil ("nil"),
Names( Name {"," Name} ); False ("false"),
Expressions( Expression {"," Expression} ); True ("true"),
Expression { Number (Number),
Nil ("nil"), String (String),
False ("false"), VarArg ("..."),
True ("true"), FunctionDef (FunctionDef),
Number (Number), PrefixExpression (PrefixExpression),
String (String), Table (Table),
VarArg ("..."), Binary (Expression BinaryOp Expression),
FunctionDef (FunctionDef), Unary (UnaryOp Expression)
PrefixExpression (PrefixExpression), };
Table (Table), PrefixExpression {
Binary (Expression BinaryOp Expression), Variable (Variable),
Unary (UnaryOp Expression) Call (FunctionCall),
}; Expression ("(" Expression ")")
PrefixExpression { };
Variable (Variable), FunctionCall {
Call (FunctionCall), Normal (PrefixExpression Arguments),
Expression ("(" Expression ")") Instanced (PrefixExpression ":" Name Arguments)
}; };
FunctionCall { Arguments {
Normal (PrefixExpression Arguments), Expressions ("(" [Expressions] ")"),
Instanced (PrefixExpression ":" Name Arguments) Table (Table),
}; String (String)
Arguments { };
Expressions ("(" [Expressions] ")"), FunctionDef( "function" FunctionBody );
Table (Table), FunctionBody( "(" [Parameters] ")" Block "end" );
String (String) Parameters {
}; Names (Names ["," VarArg]),
FunctionDef( "function" FunctionBody ); VarArg (VarArg)
FunctionBody( "(" [Parameters] ")" Block "end" ); };
Parameters { VarArg( "..." [Name] );
Names (Names ["," VarArg]), Table( "{" [Fields] "}" );
VarArg (VarArg) Fields( Field {FieldSep Field} [FieldSep] );
}; Field {
VarArg( "..." [Name] ); ExpressionIndex ("[" Expression "]" "=" Expression),
Table( "{" [Fields] "}" ); Name (Name "=" Expression),
Fields( Field {FieldSep Field} [FieldSep] ); Expression (Expression)
Field { };
ExpressionIndex ("[" Expression "]" "=" Expression), FieldSep {
Name (Name "=" Expression), Comma (","),
Expression (Expression) Semicolon (";")
}; };
FieldSep { BinaryOp {
Comma (","), Plus ("+"),
Semicolon (";") Minus ("-"),
}; Mul ("*"),
BinaryOp { Divide ("/"),
Plus ("+"), DivFloor ("//"),
Minus ("-"), Caret ("^"),
Mul ("*"), Modulo ("%"),
Divide ("/"), Ampersand ("&"),
DivFloor ("//"), Tilde ("~"),
Caret ("^"), Pipe ("|"),
Modulo ("%"), ShiftRight (">>"),
Ampersand ("&"), ShiftLeft ("<<"),
Tilde ("~"), Concat (".."),
Pipe ("|"), Less ("<"),
ShiftRight (">>"), LessEqual ("<="),
ShiftLeft ("<<"), Greater (">"),
Concat (".."), GreatEqual (">="),
Less ("<"), Equivalent ("=="),
LessEqual ("<="), NotEqual ("~="),
Greater (">"), And ("and"),
GreatEqual (">="), Or ("or")
Equivalent ("=="), };
NotEqual ("~="), UnaryOp {
And ("and"), Negate ("-"),
Or ("or") Not ("!"),
}; Ampersand ("#"),
UnaryOp { Tilde ("~")
Negate ("-"), };
Not ("!"), }
Ampersand ("#"),
Tilde ("~")
};
}
Regular → Executable
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

After

Width:  |  Height:  |  Size: 254 KiB