forked from AbleScript/ablescript
Added T-Dark block
- obeyed clippy
This commit is contained in:
parent
ecd972e55d
commit
f8db60bc7c
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)?)))
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
Loading…
Reference in a new issue