forked from AbleScript/ablescript
Merge pull request #15 from erindesu/master
Fixed some incompatible old code
This commit is contained in:
commit
143ae613d8
|
@ -88,9 +88,6 @@ pub enum Token {
|
||||||
#[token("if")]
|
#[token("if")]
|
||||||
If,
|
If,
|
||||||
|
|
||||||
#[token("else")]
|
|
||||||
Else,
|
|
||||||
|
|
||||||
#[token("loop")]
|
#[token("loop")]
|
||||||
Loop,
|
Loop,
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ impl From<Iden> for Expr {
|
||||||
pub enum Stmt {
|
pub enum Stmt {
|
||||||
VariableDeclaration {
|
VariableDeclaration {
|
||||||
iden: Iden,
|
iden: Iden,
|
||||||
init: Option<Box<Item>>,
|
init: Option<Expr>,
|
||||||
},
|
},
|
||||||
FunctionDeclaration {
|
FunctionDeclaration {
|
||||||
iden: Iden,
|
iden: Iden,
|
||||||
|
@ -65,7 +65,7 @@ pub enum Stmt {
|
||||||
body: String,
|
body: String,
|
||||||
},
|
},
|
||||||
If {
|
If {
|
||||||
cond: Box<Item>,
|
cond: Expr,
|
||||||
body: Vec<Item>,
|
body: Vec<Item>,
|
||||||
},
|
},
|
||||||
FunctionCall {
|
FunctionCall {
|
||||||
|
@ -75,6 +75,11 @@ pub enum Stmt {
|
||||||
Loop {
|
Loop {
|
||||||
body: Vec<Item>,
|
body: Vec<Item>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
VarAssignment {
|
||||||
|
iden: Iden,
|
||||||
|
value: Expr,
|
||||||
|
},
|
||||||
Break,
|
Break,
|
||||||
HopBack,
|
HopBack,
|
||||||
Print(Expr),
|
Print(Expr),
|
||||||
|
|
|
@ -69,6 +69,7 @@ impl<'a> Parser<'a> {
|
||||||
| Token::String(_)
|
| Token::String(_)
|
||||||
| Token::Nul
|
| Token::Nul
|
||||||
| Token::LeftParenthesis
|
| Token::LeftParenthesis
|
||||||
|
| Token::Assignment
|
||||||
| Token::LogNot => self.parse_ops(token),
|
| Token::LogNot => self.parse_ops(token),
|
||||||
|
|
||||||
// Control flow
|
// Control flow
|
||||||
|
@ -98,7 +99,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(Error {
|
_ => Err(Error {
|
||||||
kind: ErrorKind::SyntaxError("Unexpected identifier".to_owned()),
|
kind: ErrorKind::SyntaxError("Unexpected token".to_owned()),
|
||||||
position: start..self.lexer.span().end,
|
position: start..self.lexer.span().end,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -110,13 +111,31 @@ impl<'a> Parser<'a> {
|
||||||
fn variable_declaration(&mut self) -> ParseResult {
|
fn variable_declaration(&mut self) -> ParseResult {
|
||||||
let iden = self.require_iden()?;
|
let iden = self.require_iden()?;
|
||||||
|
|
||||||
let init = match self.lexer.next() {
|
let peek = self.lexer.peek().clone();
|
||||||
Some(Token::Semicolon) => None,
|
let init = match peek {
|
||||||
|
Some(Token::Semicolon) => {
|
||||||
|
self.lexer.next();
|
||||||
|
None
|
||||||
|
}
|
||||||
Some(Token::Assignment) => {
|
Some(Token::Assignment) => {
|
||||||
let value = self.lexer.next();
|
self.lexer.next();
|
||||||
let value = self.parse_item(value)?;
|
let next = self.lexer.next();
|
||||||
self.require(Token::Semicolon)?;
|
let mut value = self.parse_expr(next)?;
|
||||||
Some(Box::new(value))
|
loop {
|
||||||
|
let peek = self.lexer.peek().clone();
|
||||||
|
value = match peek {
|
||||||
|
Some(Token::Semicolon) => break,
|
||||||
|
None => {
|
||||||
|
return Err(Error {
|
||||||
|
kind: ErrorKind::EndOfTokenStream,
|
||||||
|
position: self.lexer.span(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(t) => self.parse_operation(Some(t), value)?,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
self.lexer.next();
|
||||||
|
Some(value)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error {
|
return Err(Error {
|
||||||
|
@ -134,6 +153,7 @@ impl<'a> Parser<'a> {
|
||||||
/// `functio [iden] ([expr], [expr]) { ... }
|
/// `functio [iden] ([expr], [expr]) { ... }
|
||||||
fn function_declaration(&mut self) -> ParseResult {
|
fn function_declaration(&mut self) -> ParseResult {
|
||||||
let iden = self.require_iden()?;
|
let iden = self.require_iden()?;
|
||||||
|
|
||||||
self.require(Token::LeftParenthesis)?;
|
self.require(Token::LeftParenthesis)?;
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
loop {
|
loop {
|
||||||
|
@ -144,7 +164,9 @@ impl<'a> Parser<'a> {
|
||||||
_ => return Err(self.unexpected_token(None)),
|
_ => return Err(self.unexpected_token(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.require(Token::LeftBrace)?;
|
self.require(Token::LeftBrace)?;
|
||||||
|
|
||||||
// Parse function body
|
// Parse function body
|
||||||
let body = self.parse_body()?;
|
let body = self.parse_body()?;
|
||||||
|
|
||||||
|
@ -191,19 +213,12 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse If-stmt
|
/// 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.parse_paren()?;
|
||||||
let cond = self.parse_item(cond)?;
|
|
||||||
self.require(Token::RightParenthesis)?;
|
|
||||||
|
|
||||||
self.require(Token::LeftBrace)?;
|
self.require(Token::LeftBrace)?;
|
||||||
|
|
||||||
let body = self.parse_body()?;
|
let body = self.parse_body()?;
|
||||||
|
|
||||||
Ok(Stmt::If {
|
Ok(Stmt::If { cond, body }.into())
|
||||||
cond: Box::new(cond),
|
|
||||||
body,
|
|
||||||
}
|
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse loop
|
/// Parse loop
|
||||||
|
@ -256,23 +271,17 @@ mod tests {
|
||||||
body: vec![
|
body: vec![
|
||||||
VariableDeclaration {
|
VariableDeclaration {
|
||||||
iden: Iden("a".to_owned()),
|
iden: Iden("a".to_owned()),
|
||||||
init: Some(Box::new(
|
init: Some(Add {
|
||||||
Add {
|
left: Box::new(Literal(Value::Int(3))),
|
||||||
left: Box::new(Literal(Value::Int(3))),
|
right: Box::new(Literal(Value::Int(2))),
|
||||||
right: Box::new(Literal(Value::Int(2))),
|
}),
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
If {
|
If {
|
||||||
cond: Box::new(
|
cond: Eq {
|
||||||
Eq {
|
left: Box::new(Iden("a".to_owned()).into()),
|
||||||
left: Box::new(Iden("a".to_owned()).into()),
|
right: Box::new(Literal(Value::Int(5)).into()),
|
||||||
right: Box::new(Literal(Value::Int(5)).into()),
|
},
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
body: vec![Break.into()],
|
body: vec![Break.into()],
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -289,7 +298,7 @@ mod tests {
|
||||||
let expected: &[Item] = &[
|
let expected: &[Item] = &[
|
||||||
VariableDeclaration {
|
VariableDeclaration {
|
||||||
iden: Iden("script".to_owned()),
|
iden: Iden("script".to_owned()),
|
||||||
init: Some(Box::new(Literal(Value::Nul).into())),
|
init: Some(Literal(Value::Nul)),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
Print(Iden("script".to_owned()).into()).into(),
|
Print(Iden("script".to_owned()).into()).into(),
|
||||||
|
|
|
@ -20,34 +20,87 @@ macro_rules! gen_infix {
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
pub(super) fn parse_ops(&mut self, token: Token) -> ParseResult {
|
pub(super) fn parse_ops(&mut self, token: Token) -> ParseResult {
|
||||||
if matches!(self.lexer.peek(), Some(Token::LeftParenthesis)) {
|
// Statements
|
||||||
return self.fn_call(token);
|
match self.lexer.peek() {
|
||||||
|
Some(Token::LeftParenthesis) => return self.fn_call(token),
|
||||||
|
Some(Token::Assignment) => return self.parse_assignment(token),
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut buf: Expr = self.parse_expr(Some(token))?;
|
let mut buf: Expr = self.parse_expr(Some(token))?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
buf = match self.lexer.peek() {
|
let peek = self.lexer.peek().clone();
|
||||||
Some(Token::Addition) => self.addition(buf)?,
|
buf = match peek {
|
||||||
Some(Token::Subtract) => self.subtract(buf)?,
|
// Print statement
|
||||||
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) => {
|
Some(Token::Print) => {
|
||||||
self.lexer.next();
|
self.lexer.next();
|
||||||
self.require(Token::Semicolon)?;
|
self.require(Token::Semicolon)?;
|
||||||
return Ok(Stmt::Print(buf).into());
|
return Ok(Stmt::Print(buf).into());
|
||||||
}
|
}
|
||||||
_ => return Ok(buf.into()),
|
None => return Ok(buf.into()),
|
||||||
|
|
||||||
|
// An expression
|
||||||
|
_ => self.parse_operation(peek, buf)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Match and perform
|
||||||
|
pub(super) fn parse_operation(&mut self, token: Option<Token>, buf: Expr) -> ExprResult {
|
||||||
|
match token {
|
||||||
|
Some(Token::Addition) => self.addition(buf),
|
||||||
|
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::LeftParenthesis) => Err(Error {
|
||||||
|
kind: ErrorKind::SyntaxError("Function call isn't an expression!".to_owned()),
|
||||||
|
position: self.lexer.span(),
|
||||||
|
}),
|
||||||
|
Some(_) | None => Err(self.unexpected_token(None)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_assignment(&mut self, token: Token) -> ParseResult {
|
||||||
|
self.lexer.next();
|
||||||
|
|
||||||
|
// Extract identifier
|
||||||
|
let iden = if let Token::Identifier(i) = token {
|
||||||
|
Iden(i)
|
||||||
|
} else {
|
||||||
|
return Err(Error {
|
||||||
|
kind: ErrorKind::InvalidIdentifier,
|
||||||
|
position: self.lexer.span(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let next = self.lexer.next();
|
||||||
|
let mut value = self.parse_expr(next)?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let peek = self.lexer.peek().clone();
|
||||||
|
value = match peek {
|
||||||
|
Some(Token::Semicolon) => break,
|
||||||
|
None => {
|
||||||
|
return Err(Error {
|
||||||
|
kind: ErrorKind::EndOfTokenStream,
|
||||||
|
position: self.lexer.span(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(t) => self.parse_operation(Some(t), value)?,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
self.lexer.next();
|
||||||
|
|
||||||
|
Ok(Stmt::VarAssignment { iden, value }.into())
|
||||||
|
}
|
||||||
// Generate infix
|
// Generate infix
|
||||||
gen_infix! {
|
gen_infix! {
|
||||||
addition => Add;
|
addition => Add;
|
||||||
|
@ -94,33 +147,18 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse parenthesieted expression
|
/// Parse parenthesieted expression
|
||||||
fn parse_paren(&mut self) -> ExprResult {
|
pub(super) fn parse_paren(&mut self) -> ExprResult {
|
||||||
let next = self.lexer.next();
|
let next = self.lexer.next();
|
||||||
let mut buf = self.parse_expr(next)?;
|
let mut buf = self.parse_expr(next)?;
|
||||||
loop {
|
loop {
|
||||||
let next = self.lexer.peek().clone().ok_or(Error {
|
let peek = self.lexer.peek().clone();
|
||||||
kind: ErrorKind::EndOfTokenStream,
|
buf = match peek {
|
||||||
position: self.lexer.span(),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
buf = match Some(next) {
|
|
||||||
Some(Token::Addition) => self.addition(buf)?,
|
|
||||||
Some(Token::Subtract) => self.subtract(buf)?,
|
|
||||||
Some(Token::Multiply) => self.multiply(buf)?,
|
|
||||||
Some(Token::Divide) => self.divide(buf)?,
|
|
||||||
Some(Token::LeftParenthesis) => {
|
|
||||||
return Err(Error {
|
|
||||||
kind: ErrorKind::SyntaxError(
|
|
||||||
"Function call isn't an expression!".to_owned(),
|
|
||||||
),
|
|
||||||
position: self.lexer.span(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Some(Token::RightParenthesis) => {
|
Some(Token::RightParenthesis) => {
|
||||||
self.lexer.next();
|
self.lexer.next();
|
||||||
return Ok(buf);
|
return Ok(buf);
|
||||||
}
|
}
|
||||||
_ => return Ok(buf),
|
None => return Ok(buf),
|
||||||
|
Some(t) => self.parse_operation(Some(t), buf)?,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue