Compare commits

...

5 Commits

Author SHA1 Message Date
SimonFJ20
5f508eee12 fix quit event to exit game loop 2023-01-23 01:01:58 +01:00
SimonFJ20
f223e2401e parsing is *doom music start plaing* inducing 2023-01-23 01:00:13 +01:00
SimonFJ20
ba8f867bd9 parser is hard 2023-01-22 03:40:01 +01:00
SimonFJ20
8852ca6fe2 moar parsing 2023-01-21 03:40:08 +01:00
df49e28f78 made some rectangles 2023-01-20 17:02:03 +01:00
5 changed files with 258 additions and 72 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
target/ target/
SDL2*.dll

View File

@ -11,8 +11,7 @@ element_fields -> (_ element_field (__linebreak__ element_field):*):? __linebrea
element_field -> element_field ->
| element | element
| Id | specifier_chain
| Class
| element_property | element_property
| value | value
@ -20,22 +19,20 @@ element_property -> Name _ ("=" | ":") _ value
single_line_fields -> single_line_fields ->
(first_single_line_field (first_single_line_field
(__singleline__ single_line_field):*):? _singleline_ (__sl__ single_line_field):*):? _sl_
first_single_line_field -> first_single_line_field ->
| Id | specifier_chain
| Class | __sl__ single_line_element_property
| __singleline__ single_line_element_property | __sl__ single_line_value
| __singleline__ single_line_value
single_line_field -> single_line_field ->
| Id | specifier_chain
| Class
| single_line_element_property | single_line_element_property
| single_line_value | single_line_value
single_line_element_property -> single_line_element_property ->
Name _singleline_ ("=" | ":") _singleline_ value Name _sl_ ("=" | ":") _sl_ value
single_line_value -> single_line_value ->
| array | array
@ -45,6 +42,12 @@ single_line_value ->
| bool | bool
| Null | Null
specifier_chain -> specifier:+
specifier ->
| Id
| Class
value -> value ->
| object | object
| array | array
@ -56,7 +59,8 @@ value ->
object -> "{" object_properties "}" object -> "{" object_properties "}"
object_properties -> (_ object_property (_ "," _ object_property):* _ ",":?):? _ object_properties ->
(_ object_property (_ "," _ object_property):* _ ",":?):? _
object_property -> (Name | String) _ ("=" | ":") _ value object_property -> (Name | String) _ ("=" | ":") _ value
@ -66,28 +70,27 @@ array_values -> (_ value (_ "," _ value):* _ ",":?):? _
bool -> True | False bool -> True | False
__singleline__ -> mandatory_same_line_whitespace
_singleline_ -> optional_same_line_whitespace
__linebreak__ -> mandatory_linebreak __linebreak__ -> mandatory_linebreak
__ -> mandatory_whitespace __sl__ -> mandatory_single_line_whitespace
_sl_ -> optional_single_line_whitespace
__ml__ -> mandatory_whitespace
_ -> optional_whitespace _ -> optional_whitespace
mandatory_same_line_whitespace -> single_line_whitespace:+
optional_same_line_whitespace -> single_line_whitespace:*
mandatory_linebreak -> mandatory_linebreak ->
single_line_whitespace:* single_line_whitespace:*
line_breaker line_breaker
whitespace_and_line_break:* whitespace_and_line_break:*
single_line_whitespace -> SingleLineWhitespace | MultiLineComment
line_breaker -> MultiLineComment | MultiLineWhitespace | ";" line_breaker -> MultiLineComment | MultiLineWhitespace | ";"
whitespace_and_line_break -> singular_whitespace | ";" whitespace_and_line_break -> singular_whitespace | ";"
optional_whitespace -> singular_whitespace:* mandatory_single_line_whitespace -> single_line_whitespace:+
optional_single_line_whitespace -> single_line_whitespace:*
single_line_whitespace -> SingleLineWhitespace | MultiLineComment
optional_whitespace -> singular_whitespace:*
mandatory_whitespace -> singular_whitespace:+ mandatory_whitespace -> singular_whitespace:+
singular_whitespace -> singular_whitespace ->

View File

@ -1,17 +1,17 @@
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq)]
pub enum ErrorType { pub enum ErrorType {
UnexpectedToken(char), UnexpectedToken(char),
InvalidConstructor, InvalidConstructor,
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq)]
pub struct Error { pub struct Error {
error: ErrorType, error: ErrorType,
line: isize, line: isize,
col: isize, col: isize,
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq)]
pub enum Token { pub enum Token {
Name(String), Name(String),
Id(String), Id(String),
@ -30,10 +30,10 @@ pub enum Token {
RBrace(String), RBrace(String),
LBracket(String), LBracket(String),
RBracket(String), RBracket(String),
Equal(String), Equal(String), // not implemented
Colon(String), Colon(String), // not implemented
SemiColon(String), SemiColon(String), // not implemented
Comma(String), Comma(String), // not implemented
} }
#[derive(PartialEq)] #[derive(PartialEq)]

View File

@ -27,6 +27,13 @@ pub struct Parser {
type ParserError = String; type ParserError = String;
enum ElementField {
Id(String),
Class(String),
Property(Box<Node>),
Value(Node),
}
impl Parser { impl Parser {
pub fn new(tokens: Vec<Token>) -> Self { pub fn new(tokens: Vec<Token>) -> Self {
Self { tokens, index: 0 } Self { tokens, index: 0 }
@ -41,23 +48,63 @@ impl Parser {
} }
fn parse_element(&mut self) -> Result<Node, ParserError> { fn parse_element(&mut self) -> Result<Node, ParserError> {
let name = match self.current() {
Some(Token::Name(value)) => value.clone(),
_ => panic!("checked by previous predicate"),
};
self.step();
todo!() todo!()
} }
fn parse_singe_line_fields(&mut self) -> Result<Vec<ElementField>, ParserError> {
let mut fields = Vec::<ElementField>::new();
match self.current() {
Some(Token::Id(value)) => {
fields.push(ElementField::Id(value.clone()));
self.step();
todo!()
}
Some(Token::Class(value)) => {
fields.push(ElementField::Class(value.clone()));
self.step();
todo!()
}
Some(_) => todo!(),
_ => Ok(fields),
}
}
fn parse_value(&mut self) -> Result<Node, ParserError> { fn parse_value(&mut self) -> Result<Node, ParserError> {
match self.current() { match self.current() {
Some(Token::LBrace(_)) => self.parse_object(), Some(Token::LBrace(_)) => self.parse_object(),
Some(Token::LBracket(_)) => self.parse_object(), Some(Token::LBracket(_)) => self.parse_object(),
Some(Token::Int(value)) => Ok(Node::Int( Some(Token::Int(value)) => {
value.parse().map_err(|_| "malformed int".to_string())?, let value = value.parse().map_err(|_| "malformed int".to_string())?;
)), self.step();
Some(Token::Float(value)) => Ok(Node::Int( Ok(Node::Int(value))
value.parse().map_err(|_| "malformed float".to_string())?, }
)), Some(Token::Float(value)) => {
Some(Token::String(value)) => Ok(Node::String(value[1..value.len() - 1].to_string())), let value = value.parse().map_err(|_| "malformed float".to_string())?;
Some(Token::False(_)) => Ok(Node::Bool(false)), self.step();
Some(Token::True(_)) => Ok(Node::Bool(false)), Ok(Node::Float(value))
Some(Token::Null(_)) => Ok(Node::Null), }
Some(Token::String(value)) => {
let value = value[1..value.len() - 1].to_string();
self.step();
Ok(Node::String(value))
}
Some(Token::False(_)) => {
self.step();
Ok(Node::Bool(false))
}
Some(Token::True(_)) => {
self.step();
Ok(Node::Bool(false))
}
Some(Token::Null(_)) => {
self.step();
Ok(Node::Null)
}
Some(_) => Err("unexpected token, expected value".to_owned()), Some(_) => Err("unexpected token, expected value".to_owned()),
None => Err("expected value".to_owned()), None => Err("expected value".to_owned()),
} }
@ -65,6 +112,8 @@ impl Parser {
fn parse_object(&mut self) -> Result<Node, ParserError> { fn parse_object(&mut self) -> Result<Node, ParserError> {
self.step(); self.step();
// object_properties -> (_ (...)):? _ <=> object_properties -> _ | _ (...) _
self.parse_optional_whitespace()?;
let mut values = HashMap::<String, Box<Node>>::new(); let mut values = HashMap::<String, Box<Node>>::new();
match self.current() { match self.current() {
Some(Token::RBrace(_)) => { Some(Token::RBrace(_)) => {
@ -72,27 +121,32 @@ impl Parser {
Ok(Node::Object(values)) Ok(Node::Object(values))
} }
Some(t @ (Token::Name(_) | Token::String(_))) => { Some(t @ (Token::Name(_) | Token::String(_))) => {
// let key = match t { let key = match t {
// Token::Name(v) => v, Token::Name(v) => v.clone(),
// Token::String(v) => &v[1..v.len() - 1].to_string(), Token::String(v) => v[1..v.len() - 1].to_string(),
// _ => panic!("checked by previous predicate"), _ => panic!("checked by previous predicate"),
// }; };
// self.step(); self.step();
// match self.current() { self.parse_optional_whitespace()?;
// Some(Token::Equal(_) | Token::Colon(_)) => {} match self.current() {
// _ => return Err("expected ':' or '='".to_string()), Some(Token::Equal(_) | Token::Colon(_)) => {}
// } _ => return Err("expected ':' or '='".to_string()),
// self.step(); }
// values[key] = Box::new(self.parse_value()?); self.step();
// self.parse_object_tail(values) self.parse_optional_whitespace()?;
todo!() values.insert(key, Box::new(self.parse_value()?));
self.parse_object_tail(values)
} }
_ => Err("expected Name, String or '}'".to_string()), _ => Err("expected Name, String or '}'".to_string()),
} }
} }
fn parse_object_tail(&mut self, values: HashMap<String, Box<Node>>) -> Result<Node, String> { fn parse_object_tail(
&mut self,
mut values: HashMap<String, Box<Node>>,
) -> Result<Node, String> {
loop { loop {
self.parse_optional_whitespace()?;
match self.current() { match self.current() {
Some(Token::RBrace(_)) => { Some(Token::RBrace(_)) => {
self.step(); self.step();
@ -100,25 +154,28 @@ impl Parser {
} }
Some(Token::Comma(_)) => { Some(Token::Comma(_)) => {
self.step(); self.step();
self.parse_optional_whitespace()?;
match self.current() { match self.current() {
Some(Token::RBrace(_)) => { Some(Token::RBrace(_)) => {
self.step(); self.step();
break Ok(Node::Object(values)); break Ok(Node::Object(values));
} }
Some(t @ (Token::Name(_) | Token::String(_))) => { Some(t @ (Token::Name(_) | Token::String(_))) => {
// let key = match t { let key = match t {
// Token::Name(v) => v, Token::Name(v) => v.clone(),
// Token::String(v) => &v[1..v.len() - 1].to_string(), Token::String(v) => v[1..v.len() - 1].to_string(),
// _ => panic!("unterminated object, checked by previous predicate"), _ => panic!("unterminated object, checked by previous predicate"),
// }; };
// self.step(); self.step();
// match self.current() { self.parse_optional_whitespace()?;
// Some(Token::Equal(_) | Token::Colon(_)) => {} match self.current() {
// _ => return Err("expected ':' or '='".to_string()), Some(Token::Equal(_) | Token::Colon(_)) => {}
// } _ => return Err("expected ':' or '='".to_string()),
// self.step(); }
// values[key] = Box::new(self.parse_value()?); self.step();
todo!() self.parse_optional_whitespace()?;
values.insert(key, Box::new(self.parse_value()?));
self.parse_optional_whitespace()?;
} }
_ => { _ => {
break Err( break Err(
@ -134,6 +191,7 @@ impl Parser {
fn parse_array(&mut self) -> Result<Node, ParserError> { fn parse_array(&mut self) -> Result<Node, ParserError> {
self.step(); self.step();
self.parse_optional_whitespace()?;
let mut values = Vec::<Node>::new(); let mut values = Vec::<Node>::new();
match self.current() { match self.current() {
Some(Token::RBracket(_)) => { Some(Token::RBracket(_)) => {
@ -142,12 +200,112 @@ impl Parser {
} }
Some(_) => { Some(_) => {
values.push(self.parse_value()?); values.push(self.parse_value()?);
todo!() loop {
match self.current() {
Some(Token::RBracket(_)) => {
self.step();
break Ok(Node::Array(values));
}
Some(Token::Comma(_)) => {
self.step();
self.parse_optional_whitespace()?;
match self.current() {
Some(Token::RBracket(_)) => {
self.step();
self.parse_optional_whitespace()?;
break Ok(Node::Array(values));
}
_ => {
self.step();
self.parse_optional_whitespace()?;
values.push(self.parse_value()?)
}
}
}
_ => break Err("unterminated array, expected Value or ']'".to_string()),
}
}
} }
_ => Err("unterminated array, expected Value or ']'".to_string()), _ => Err("unterminated array, expected Value or ']'".to_string()),
} }
} }
fn parse_mandatory_linebreak(&mut self) -> Result<(), ParserError> {
self.parse_single_line_optional_whitespace()?;
match self.current() {
Some(Token::MlWhitespace(_) | Token::MlComment(_) | Token::SemiColon(_)) => {
self.step();
loop {
match self.current() {
Some(
Token::MlWhitespace(_)
| Token::SlWhitespace(_)
| Token::MlComment(_)
| Token::SlComment(_)
| Token::SemiColon(_),
) => {
self.step();
}
_ => break Ok(()),
}
}
}
_ => Err("expected linebreak".to_string()),
}
}
fn parse_single_line_mandatory_whitespace(&mut self) -> Result<(), ParserError> {
match self.current() {
Some(Token::SlWhitespace(_) | Token::SlComment(_)) => {
self.step();
self.parse_single_line_optional_whitespace()
}
_ => Err("expected whitespace".to_string()),
}
}
fn parse_single_line_optional_whitespace(&mut self) -> Result<(), ParserError> {
loop {
match self.current() {
Some(Token::SlWhitespace(_) | Token::SlComment(_)) => {
self.step();
}
_ => break Ok(()),
}
}
}
fn parse_mandatory_whitespace(&mut self) -> Result<(), ParserError> {
match self.current() {
Some(
Token::MlWhitespace(_)
| Token::SlWhitespace(_)
| Token::MlComment(_)
| Token::SlComment(_),
) => {
self.step();
self.parse_optional_whitespace()
}
_ => Err("expected whitespace".to_string()),
}
}
fn parse_optional_whitespace(&mut self) -> Result<(), ParserError> {
loop {
match self.current() {
Some(
Token::MlWhitespace(_)
| Token::SlWhitespace(_)
| Token::MlComment(_)
| Token::SlComment(_),
) => {
self.step();
}
_ => break Ok(()),
}
}
}
fn step(&mut self) { fn step(&mut self) {
self.index += 1 self.index += 1
} }

View File

@ -1,9 +1,28 @@
use std::time::Duration; use std::time::Duration;
use sdl2::{event::Event, keyboard::Keycode, pixels::Color}; use sdl2::{
event::Event, keyboard::Keycode, pixels::Color, rect::Rect, render::Canvas, video::Window,
};
mod bong; mod bong;
enum Element {
Div(Vec<Element>),
Rectangle(Color),
}
impl Element {
fn render(&self, canvas: &mut Canvas<Window>, x: i32, y: i32) {
match self {
Element::Div(_) => todo!(),
Element::Rectangle(color) => {
canvas.set_draw_color(*color);
let _ = canvas.fill_rect(Rect::new(x, y, 50, 50));
}
}
}
}
fn main() { fn main() {
let sdl_context = sdl2::init().unwrap(); let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap(); let video_subsystem = sdl_context.video().unwrap();
@ -20,10 +39,8 @@ fn main() {
canvas.clear(); canvas.clear();
canvas.present(); canvas.present();
let mut event_pump = sdl_context.event_pump().unwrap(); let mut event_pump = sdl_context.event_pump().unwrap();
let mut i = 0; 'game_loop: loop {
'running: loop { canvas.set_draw_color(Color::RGB(170, 200, 255));
i = (i + 1) % 255;
canvas.set_draw_color(Color::RGB(i, 64, 255 - i));
canvas.clear(); canvas.clear();
for event in event_pump.poll_iter() { for event in event_pump.poll_iter() {
match event { match event {
@ -31,11 +48,18 @@ fn main() {
| Event::KeyDown { | Event::KeyDown {
keycode: Some(Keycode::Escape), keycode: Some(Keycode::Escape),
.. ..
} => break 'running, } => break 'game_loop,
_ => {} _ => {}
} }
} }
// The rest of the game loop goes here... // The rest of the game loop goes here...
let dom = Element::Div(vec![
Element::Rectangle(Color::RGB(1, 238, 34)),
Element::Rectangle(Color::RGB(123, 123, 123)),
]);
canvas.set_draw_color(Color::RGB(255, 0, 0));
let _ = canvas.fill_rect(Rect::new(0, 0, 50, 50));
canvas.present(); canvas.present();
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));