Added T-Dark block

- obeyed clippy
This commit is contained in:
Erin 2021-05-02 17:38:12 +02:00 committed by ondra05
parent ecd972e55d
commit f8db60bc7c
4 changed files with 60 additions and 14 deletions

View file

@ -18,6 +18,7 @@ pub type ParseResult = Result<Item, Error>;
pub struct Parser<'a> { pub struct Parser<'a> {
lexer: PeekableLexer<'a>, lexer: PeekableLexer<'a>,
ast: Vec<Item>, ast: Vec<Item>,
tdark: bool,
} }
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
@ -26,22 +27,28 @@ impl<'a> Parser<'a> {
Self { Self {
lexer: PeekableLexer::lexer(source), lexer: PeekableLexer::lexer(source),
ast: Vec::new(), ast: Vec::new(),
tdark: false,
} }
} }
pub fn init(&mut self) -> Result<Vec<Item>, Error> { pub fn init(&mut self) -> Result<Vec<Item>, Error> {
loop { loop {
let token = self.lexer.next(); let token = self.lexer.next();
if token.is_none() {
return Ok(self.ast.clone()); match token {
}; Some(Token::Comment) => continue,
if matches!(token, Some(Token::Comment)) { Some(Token::TDark) => {
continue; let mut block = self.tdark_block()?;
self.ast.append(&mut block);
} }
None => return Ok(self.ast.clone()),
_ => {
let item = self.parse_item(token)?; let item = self.parse_item(token)?;
self.ast.push(item); self.ast.push(item);
} }
} }
}
}
fn parse_item(&mut self, token: Option<Token>) -> ParseResult { fn parse_item(&mut self, token: Option<Token>) -> ParseResult {
if matches!(token, None) { if matches!(token, None) {
@ -169,7 +176,7 @@ impl<'a> Parser<'a> {
Ok(Stmt::BfFDeclaration { iden, body }.into()) Ok(Stmt::BfFDeclaration { iden, body }.into())
} }
/// Parse If-expression /// Parse If-stmt
pub fn if_cond(&mut self) -> ParseResult { pub fn if_cond(&mut self) -> ParseResult {
self.require(Token::LeftParenthesis)?; self.require(Token::LeftParenthesis)?;
let cond = self.lexer.next(); let cond = self.lexer.next();
@ -186,4 +193,31 @@ impl<'a> Parser<'a> {
} }
.into()) .into())
} }
/// T-Dark block parsing
pub fn tdark_block(&mut self) -> Result<Vec<Item>, Error> {
self.require(Token::LeftBrace)?;
self.tdark = true;
let mut body = Vec::new();
loop {
let token = {
match self.lexer.next() {
Some(t) => t,
None => {
return Err(Error {
kind: ErrorKind::EndOfTokenStream,
position: self.lexer.span(),
})
}
}
};
if token == Token::RightBrace {
break;
}
body.push(self.parse_item(Some(token))?);
}
self.tdark = false;
Ok(body)
}
} }

View file

@ -72,9 +72,17 @@ impl<'a> Parser<'a> {
match token { match token {
Token::Boolean(b) => Ok(Expr::Literal(Value::Bool(b))), Token::Boolean(b) => Ok(Expr::Literal(Value::Bool(b))),
Token::Integer(i) => Ok(Expr::Literal(Value::Int(i))), Token::Integer(i) => Ok(Expr::Literal(Value::Int(i))),
Token::String(s) => Ok(Expr::Literal(Value::Str(s))), Token::String(s) => Ok(Expr::Literal(Value::Str(if self.tdark {
s.replace("lang", "script")
} else {
s
}))),
Token::Aboolean(a) => Ok(Expr::Literal(Value::Abool(a))), Token::Aboolean(a) => Ok(Expr::Literal(Value::Abool(a))),
Token::Identifier(i) => Ok(Expr::Identifier(Iden(i))), Token::Identifier(i) => Ok(Expr::Identifier(Iden(if self.tdark {
i.replace("lang", "script")
} else {
i
}))),
Token::LogNot => { Token::LogNot => {
let next = self.lexer.next(); let next = self.lexer.next();
Ok(Expr::Not(Box::new(self.parse_expr(next)?))) Ok(Expr::Not(Box::new(self.parse_expr(next)?)))

View file

@ -36,7 +36,11 @@ impl<'a> Parser<'a> {
/// Require an identifier on next and return it /// Require an identifier on next and return it
pub(super) fn require_iden(&mut self) -> Result<Iden, Error> { pub(super) fn require_iden(&mut self) -> Result<Iden, Error> {
if let Some(Token::Identifier(id)) = self.lexer.next() { if let Some(Token::Identifier(id)) = self.lexer.next() {
if self.tdark {
Ok(Iden(id.replace("lang", "script")))
} else {
Ok(Iden(id)) Ok(Iden(id))
}
} else { } else {
Err(Error { Err(Error {
kind: ErrorKind::InvalidIdentifier, kind: ErrorKind::InvalidIdentifier,

View file

@ -7,9 +7,9 @@ pub enum Abool {
Always = 1, Always = 1,
} }
impl Into<bool> for Abool { impl From<Abool> for bool {
fn into(self) -> bool { fn from(val: Abool) -> Self {
match self { match val {
Abool::Never => false, Abool::Never => false,
Abool::Always => true, Abool::Always => true,
Abool::Sometimes => rand::thread_rng().gen(), Abool::Sometimes => rand::thread_rng().gen(),