diff --git a/Cargo.toml b/Cargo.toml index e0dad45..637d3aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [package] +#![recursion_limit = "256"] name = "game" version = "0.1.0" edition = "2024" @@ -18,6 +19,7 @@ log = "0.4" wgpu = "29.0.3" pollster = "0.4.0" console_error_panic_hook = "0.1.7" +parse = { path = "./parse" } [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.6" diff --git a/src/lang.rs b/src/lang.rs index e69de29..851709d 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -0,0 +1,299 @@ +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 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 { + $($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)*) 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)*} + }; +} + +macro_rules! implement { + {@begin $n:ident $i:ident $($t:tt)*} => { + implement!{@build ($i $n) {} {} $($t)*} + }; + {@build $m:tt $f:tt {$($f2:tt)*} $s:literal $($t:tt)*} => { + implement!{@build $m $f { + $($f2)* + state = state.trim_start(); + if state.starts_with($s) { + state = &state[$s.len()..] + } else { + return Err("error".into()) + } + } $($t)*} + }; + {@build $m:tt {$($f:tt)*} {$($f2:tt)*} $i:ident $($t:tt)*} => { + implement!{@build $m {$($f)*{$($f2)*}} { + let mut result; + match $i::take(state) { + Ok((r,s)) => { + state = s; + result = r; + } + Err(error) => { + return Err(error); + } + } + } $($t)*} + }; + {@build ($($m:tt)*) {$($f:tt)*} {$($f2:tt)*} {$($r:tt)*} $($t:tt)*} => { + implement!{@build (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)*} + }; + {@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; + $($f)* + Ok(($({$($r)*result}),*)) + }; + result = taker(state).ok(); + } $($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; + $($f)* + Ok(($({$($r)*result}),*)) + }; + loop { + match taker(state) { + Ok((r,s)) => { + state = s; + result.push(r); + } + Err(error) => { + break; + } + }; + } + } $($t)*} + }; + {@build $m:tt {$($r:tt)*} $r2:tt} => { + implement!{@finish $m {$($r)*$r2}} + }; + {@finish (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; + $($f)* + Ok(($n($({$($r)*result.into()}),*),state)) + } + } + }; +} + +macro_rules! class { + ($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 ()} + } +} +macro_rules! parser { + () => {}; + ($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> + where Self: Sized; +} +impl Parse for String { + fn take(state: &str) -> Result<(Self, &str), Error> + where + Self: Sized + { + todo!() + } +} + +fn g() -> Result { + Ok(Chunk( + { + if 1 == 2 { + Box::new(Block(Vec::new(),None)) + } else { + return Err(()) + } + } + )) +} + +parser! { + Chunk3 ( "Pookie" Block "Dookie" ); +} + +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 ("~") + }; +} diff --git a/src/lib.rs b/src/lib.rs index 8f29b2a..8618666 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,22 @@ +#![recursion_limit = "256"] mod lang; +mod neural; // Credit of most code to https://sotrh.github.io/learn-wgpu/ since I come from OpenGl not wgpu use std::sync::Arc; -use winit::{ - application::ApplicationHandler, event::*, event_loop::{ActiveEventLoop, EventLoop}, keyboard::{KeyCode, PhysicalKey}, window::Window -}; -use winit::dpi::{PhysicalPosition}; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; +use winit::dpi::PhysicalPosition; #[cfg(target_arch = "wasm32")] use winit::platform::web::EventLoopExtWebSys; +use winit::{ + application::ApplicationHandler, + event::*, + event_loop::{ActiveEventLoop, EventLoop}, + keyboard::{KeyCode, PhysicalKey}, + window::Window, +}; // This will store the state of our game pub struct State { @@ -76,7 +82,9 @@ impl State { // Shader code in this tutorial assumes an sRGB surface texture. Using a different // one will result in all the colors coming out darker. If you want to support non // sRGB surfaces, you'll need to account for that when drawing to the frame. - let surface_format = surface_caps.formats.iter() + let surface_format = surface_caps + .formats + .iter() .find(|f| f.is_srgb()) .copied() .unwrap_or(surface_caps.formats[0]); @@ -106,13 +114,15 @@ impl State { vertex: wgpu::VertexState { module: &shader1, entry_point: Some("vs_main"), // 1. - buffers: &[], // 2. + buffers: &[], // 2. compilation_options: wgpu::PipelineCompilationOptions::default(), }, - fragment: Some(wgpu::FragmentState { // 3. + fragment: Some(wgpu::FragmentState { + // 3. module: &shader1, entry_point: Some("fs_main"), - targets: &[Some(wgpu::ColorTargetState { // 4. + targets: &[Some(wgpu::ColorTargetState { + // 4. format: config.format, blend: Some(wgpu::BlendState::REPLACE), write_mask: wgpu::ColorWrites::ALL, @@ -133,12 +143,12 @@ impl State { }, depth_stencil: None, // 1. multisample: wgpu::MultisampleState { - count: 1, // 2. - mask: !0, // 3. + count: 1, // 2. + mask: !0, // 3. alpha_to_coverage_enabled: false, // 4. }, multiview_mask: None, // 5. - cache: None, // 6. + cache: None, // 6. }); let shader2 = device.create_shader_module(wgpu::include_wgsl!("shader2.wgsl")); @@ -156,13 +166,15 @@ impl State { vertex: wgpu::VertexState { module: &shader2, entry_point: Some("vs_main"), // 1. - buffers: &[], // 2. + buffers: &[], // 2. compilation_options: wgpu::PipelineCompilationOptions::default(), }, - fragment: Some(wgpu::FragmentState { // 3. + fragment: Some(wgpu::FragmentState { + // 3. module: &shader2, entry_point: Some("fs_main"), - targets: &[Some(wgpu::ColorTargetState { // 4. + targets: &[Some(wgpu::ColorTargetState { + // 4. format: config.format, blend: Some(wgpu::BlendState::REPLACE), write_mask: wgpu::ColorWrites::ALL, @@ -183,12 +195,12 @@ impl State { }, depth_stencil: None, // 1. multisample: wgpu::MultisampleState { - count: 1, // 2. - mask: !0, // 3. + count: 1, // 2. + mask: !0, // 3. alpha_to_coverage_enabled: false, // 4. }, multiview_mask: None, // 5. - cache: None, // 6. + cache: None, // 6. }); Ok(Self { @@ -206,7 +218,7 @@ impl State { g: 0.2, b: 0.3, a: 1.0, - } + }, }) } @@ -254,10 +266,14 @@ impl State { anyhow::bail!("Lost device"); } }; - let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default()); - let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { - label: Some("Render Encoder"), - }); + let view = output + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + let mut encoder = self + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("Render Encoder"), + }); { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"), @@ -304,8 +320,8 @@ impl State { fn handle_mouse_moved(&mut self, position: PhysicalPosition) { self.sky = wgpu::Color { r: 0.3, - g: position.x/1000.0, - b: position.y/1000.0, + g: position.x / 1000.0, + b: position.y / 1000.0, a: 1.0, } } @@ -363,13 +379,15 @@ impl ApplicationHandler for App { // proxy to send the results to the event loop if let Some(proxy) = self.proxy.take() { wasm_bindgen_futures::spawn_local(async move { - assert!(proxy - .send_event( - State::new(window) - .await - .expect("Unable to create canvas!!!") - ) - .is_ok()) + assert!( + proxy + .send_event( + State::new(window) + .await + .expect("Unable to create canvas!!!") + ) + .is_ok() + ) }); } } @@ -414,16 +432,14 @@ impl ApplicationHandler for App { } } } - WindowEvent::CursorMoved { - position: pos, .. - } => state.handle_mouse_moved(pos), + WindowEvent::CursorMoved { position: pos, .. } => state.handle_mouse_moved(pos), WindowEvent::KeyboardInput { event: - KeyEvent { - physical_key: PhysicalKey::Code(code), - state: key_state, - .. - }, + KeyEvent { + physical_key: PhysicalKey::Code(code), + state: key_state, + .. + }, .. } => state.handle_key(event_loop, code, key_state.is_pressed()), _ => {} @@ -463,4 +479,4 @@ pub fn run_web() -> Result<(), wasm_bindgen::JsValue> { run().unwrap_throw(); Ok(()) -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index e8b1c3d..fc66e18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ +#![recursion_limit = "256"] + use game::run; fn main() { run().unwrap(); -} \ No newline at end of file +}