Change parsing implementation to lua spec
This commit is contained in:
parent
9c56d807fe
commit
c051e8ee6b
41
src/ast.rs
41
src/ast.rs
@ -188,7 +188,10 @@ impl Parse for Block {
|
||||
let pre = Metadata::pre(&mut stream, "block")?;
|
||||
let mut statements = Vec::new();
|
||||
|
||||
while stream.peek() != Some(Token::Keyword(Keyword::End)) {
|
||||
while !matches!(
|
||||
stream.peek(),
|
||||
Some(Token::Keyword(Keyword::End) | Token::Eof)
|
||||
) {
|
||||
statements.push(stream.parse()?);
|
||||
}
|
||||
|
||||
@ -201,7 +204,7 @@ impl Parse for Block {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Statement {
|
||||
Assignment(Option<DefinitionKind>, Node<String>, Node<Expression>),
|
||||
Assignment(AccessModifier, Node<String>, Node<Expression>),
|
||||
Return(Node<Expression>),
|
||||
If(Node<Expression>, Block),
|
||||
}
|
||||
@ -209,7 +212,24 @@ pub enum Statement {
|
||||
impl Parse for Statement {
|
||||
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
|
||||
let peeked = stream.peek();
|
||||
if peeked == Some(Token::Keyword(Keyword::Return)) {
|
||||
if peeked == Some(Token::Keyword(Keyword::Function)) {
|
||||
let function = stream.parse::<Node<Function>>()?;
|
||||
if let Some(name) = function.kind.name {
|
||||
Ok(Self::Assignment(
|
||||
AccessModifier::Global,
|
||||
name,
|
||||
Node {
|
||||
kind: Expression::FunctionDefinition(
|
||||
function.kind.params,
|
||||
function.kind.block,
|
||||
),
|
||||
meta: function.meta,
|
||||
},
|
||||
))
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
} else if peeked == Some(Token::Keyword(Keyword::Return)) {
|
||||
stream.next();
|
||||
Ok(Statement::Return(stream.parse()?))
|
||||
} else if peeked == Some(Token::Keyword(Keyword::If)) {
|
||||
@ -224,17 +244,17 @@ impl Parse for Statement {
|
||||
let name = stream.parse()?;
|
||||
stream.expect(Token::Symbol('='))?;
|
||||
let expr = stream.parse()?;
|
||||
Ok(Statement::Assignment(
|
||||
Some(DefinitionKind::Local),
|
||||
name,
|
||||
expr,
|
||||
))
|
||||
Ok(Statement::Assignment(AccessModifier::Local, name, expr))
|
||||
} else if let Some(Token::Word(_)) = peeked
|
||||
&& stream.peek2() == Some(Token::Symbol('='))
|
||||
{
|
||||
let name = stream.parse()?;
|
||||
stream.expect(Token::Symbol('='))?;
|
||||
Ok(Self::Assignment(None, name, stream.parse()?))
|
||||
Ok(Self::Assignment(
|
||||
AccessModifier::Global,
|
||||
name,
|
||||
stream.parse()?,
|
||||
))
|
||||
} else {
|
||||
Err(stream.expecting_err("statement"))
|
||||
}
|
||||
@ -242,7 +262,7 @@ impl Parse for Statement {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DefinitionKind {
|
||||
pub enum AccessModifier {
|
||||
Local,
|
||||
Global,
|
||||
}
|
||||
@ -251,6 +271,7 @@ pub enum DefinitionKind {
|
||||
pub enum Expression {
|
||||
ValueRef(String),
|
||||
BinOp(BinaryOperator, Box<Node<Expression>>, Box<Node<Expression>>),
|
||||
FunctionDefinition(Vec<Node<String>>, Block),
|
||||
}
|
||||
|
||||
impl Parse for Expression {
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@ -1,7 +1,7 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{
|
||||
ast::Function,
|
||||
ast::{Block, Function},
|
||||
token_stream::{
|
||||
TokenStream,
|
||||
lexer::{Token, tokenize},
|
||||
@ -20,12 +20,10 @@ fn main() {
|
||||
|
||||
dbg!(&tokens);
|
||||
|
||||
let mut functions = Vec::new();
|
||||
while stream.peek() != Some(Token::Eof) {
|
||||
functions.push(stream.parse::<Function>().unwrap());
|
||||
}
|
||||
let block = stream.parse::<Block>().unwrap();
|
||||
stream.expect(Token::Eof).unwrap();
|
||||
|
||||
dbg!(functions);
|
||||
dbg!(block);
|
||||
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user