Merge pull request #15 from erindesu/master

Fixed some incompatible old code
This commit is contained in:
Able 2021-05-03 18:41:23 -05:00 committed by GitHub
commit 143ae613d8
4 changed files with 119 additions and 70 deletions

View file

@ -88,9 +88,6 @@ pub enum Token {
#[token("if")] #[token("if")]
If, If,
#[token("else")]
Else,
#[token("loop")] #[token("loop")]
Loop, Loop,

View file

@ -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),

View file

@ -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(),

View file

@ -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)?,
}; };
} }
} }