From c051e8ee6beda01c5ef026f86c3147d0a7845cc9 Mon Sep 17 00:00:00 2001 From: Sofia Date: Sat, 14 Mar 2026 16:56:13 +0200 Subject: [PATCH] Change parsing implementation to lua spec --- src/ast.rs | 41 +++++++++++++++++++++++++++++++---------- src/main.rs | 10 ++++------ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index decb2ae..bf9186c 100644 --- a/src/ast.rs +++ b/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, Node, Node), + Assignment(AccessModifier, Node, Node), Return(Node), If(Node, Block), } @@ -209,7 +212,24 @@ pub enum Statement { impl Parse for Statement { fn parse(mut stream: TokenStream) -> Result { let peeked = stream.peek(); - if peeked == Some(Token::Keyword(Keyword::Return)) { + if peeked == Some(Token::Keyword(Keyword::Function)) { + let function = stream.parse::>()?; + 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>, Box>), + FunctionDefinition(Vec>, Block), } impl Parse for Expression { diff --git a/src/main.rs b/src/main.rs index 364fbea..7eaa5d2 100644 --- a/src/main.rs +++ b/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::().unwrap()); - } + let block = stream.parse::().unwrap(); + stream.expect(Token::Eof).unwrap(); - dbg!(functions); + dbg!(block); println!("Hello, world!"); }