Parser production ready

- TODO: T-Dark block
- cargo fmt
- Obeyed our clippy overlord
This commit is contained in:
Erin 2021-05-02 16:48:33 +02:00 committed by ondra05
parent c90d242b0f
commit 5a8dd5051f
5 changed files with 38 additions and 4 deletions

View file

@ -1,4 +1,4 @@
# Ablescript
# AbleScript
![Lines of code](https://img.shields.io/tokei/lines/github/abletheabove/able-script)
Bravely going where some languages have gone before.

View file

@ -174,6 +174,15 @@ pub enum Token {
#[token("!=")]
OpNeq,
#[token("&")]
LogAnd,
#[token("|")]
LogOr,
#[token("!")]
LogNot,
/// Base52 based character ('a')
#[token("'.*'")]
Char,

View file

@ -27,6 +27,13 @@ pub enum Expr {
Subtract { left: Box<Expr>, right: Box<Expr> },
Multiply { left: Box<Expr>, right: Box<Expr> },
Divide { left: Box<Expr>, right: Box<Expr> },
Lt { left: Box<Expr>, right: Box<Expr> },
Gt { left: Box<Expr>, right: Box<Expr> },
Eq { left: Box<Expr>, right: Box<Expr> },
Neq { left: Box<Expr>, right: Box<Expr> },
And { left: Box<Expr>, right: Box<Expr> },
Or { left: Box<Expr>, right: Box<Expr> },
Not(Box<Expr>),
Literal(Value),
Identifier(Iden),
}

View file

@ -59,7 +59,9 @@ impl<'a> Parser<'a> {
| Token::Aboolean(_)
| Token::Boolean(_)
| Token::Integer(_)
| Token::String(_) => self.parse_ops(token),
| Token::String(_)
| Token::LogNot => self.parse_ops(token),
// Control flow
Token::If => self.if_cond(),

View file

@ -32,6 +32,12 @@ impl<'a> Parser<'a> {
Some(Token::Subtract) => self.subtract(buf)?,
Some(Token::Multiply) => self.multiply(buf)?,
Some(Token::Divide) => self.divide(buf)?,
Some(Token::OpLt) => self.cmplt(buf)?,
Some(Token::OpGt) => self.cmpgt(buf)?,
Some(Token::OpEq) => self.cmpeq(buf)?,
Some(Token::OpNeq) => self.cmpneq(buf)?,
Some(Token::LogAnd) => self.logand(buf)?,
Some(Token::LogOr) => self.logor(buf)?,
Some(Token::Print) => {
self.lexer.next();
self.require(Token::Semicolon)?;
@ -48,10 +54,16 @@ impl<'a> Parser<'a> {
subtract => Subtract;
multiply => Multiply;
divide => Divide;
cmplt => Lt;
cmpgt => Gt;
cmpeq => Eq;
cmpneq => Neq;
logand => And;
logor => Or;
}
/// Ensure that input token is an expression
fn parse_expr(&mut self, token: Option<Token>) -> ExprResult {
pub(super) fn parse_expr(&mut self, token: Option<Token>) -> ExprResult {
let token = token.ok_or(Error {
kind: ErrorKind::EndOfTokenStream,
position: self.lexer.span(),
@ -63,6 +75,10 @@ impl<'a> Parser<'a> {
Token::String(s) => Ok(Expr::Literal(Value::Str(s))),
Token::Aboolean(a) => Ok(Expr::Literal(Value::Abool(a))),
Token::Identifier(i) => Ok(Expr::Identifier(Iden(i))),
Token::LogNot => {
let next = self.lexer.next();
Ok(Expr::Not(Box::new(self.parse_expr(next)?)))
}
Token::LeftParenthesis => self.parse_paren(),
t => Err(self.unexpected_token(Some(t))),
}
@ -95,7 +111,7 @@ impl<'a> Parser<'a> {
self.lexer.next();
return Ok(buf);
}
_ => return Ok(buf.into()),
_ => return Ok(buf),
};
}
}