Compare commits

..

No commits in common. "5f508eee121fc8ba74a37480ccbc803b51496d7f" and "086fcf6dd9662cc4d74c0be7fe8c3f7ddd069766" have entirely different histories.

5 changed files with 72 additions and 258 deletions

1
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

@ -1,28 +1,9 @@
use std::time::Duration;
use sdl2::{
event::Event, keyboard::Keycode, pixels::Color, rect::Rect, render::Canvas, video::Window,
};
use sdl2::{event::Event, keyboard::Keycode, pixels::Color};
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() {
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
@ -39,8 +20,10 @@ fn main() {
canvas.clear();
canvas.present();
let mut event_pump = sdl_context.event_pump().unwrap();
'game_loop: loop {
canvas.set_draw_color(Color::RGB(170, 200, 255));
let mut i = 0;
'running: loop {
i = (i + 1) % 255;
canvas.set_draw_color(Color::RGB(i, 64, 255 - i));
canvas.clear();
for event in event_pump.poll_iter() {
match event {
@ -48,18 +31,11 @@ fn main() {
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'game_loop,
} => break 'running,
_ => {}
}
}
// 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();
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));