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