mirror of
https://git.fddl.dev/fddl/fddl.git
synced 2024-12-25 13:50:26 +00:00
continued building out parser, connected parser to main
This commit is contained in:
parent
94ac0863bc
commit
513dddce85
6 changed files with 169 additions and 77 deletions
|
@ -83,7 +83,8 @@ fddl is very much a work in progress, with lots of planned improvements and addi
|
|||
- [ ] Add support for more complex syntax and features.
|
||||
|
||||
- **Parser**:
|
||||
- [ ] Currently a placeholder. Implement parsing for function calls, expressions, etc.
|
||||
- [ ] Working on building out functions to parse simple functionality in the language (if, while, for), and to read their expressions and values
|
||||
- [ ] Implement parsing for function calls, expressions, checks, literally everything.
|
||||
|
||||
- **Compiler**:
|
||||
- [ ] Currently a placeholder. Implement the compiler to compile parsed code.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::lexer::token::Token;
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
||||
pub struct Lexer {
|
||||
source: Vec<char>,
|
||||
start: usize,
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -6,20 +6,22 @@ use std::env;
|
|||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use lexer::Lexer;
|
||||
// use lexer::Lexer;
|
||||
use fddl::lexer::Lexer;
|
||||
use fddl::parser::Parser;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
// runs file or REPL
|
||||
if args.len() > 1 {
|
||||
// If a file is provided, run it
|
||||
run_file(&args[1]);
|
||||
} else {
|
||||
// Otherwise start the REPL
|
||||
run_repl();
|
||||
}
|
||||
}
|
||||
|
||||
// basic REPL
|
||||
fn run_repl() {
|
||||
println!("fddl REPL");
|
||||
loop {
|
||||
|
@ -36,11 +38,14 @@ fn run_repl() {
|
|||
run(buffer.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// runs file
|
||||
fn run_file(path: &str) {
|
||||
let source = fs::read_to_string(path).expect("Failed to read source file");
|
||||
run(source);
|
||||
}
|
||||
|
||||
// runs source code
|
||||
fn run(source: String) {
|
||||
let mut lexer = Lexer::new(source);
|
||||
let tokens = lexer.scan_tokens();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#[allow(dead_code)]
|
||||
|
||||
pub enum Expression {
|
||||
Literal(Literal),
|
||||
Variable(String),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// pub mod ast;
|
||||
pub mod ast;
|
||||
pub mod parser;
|
||||
|
||||
// pub use ast::*;
|
||||
pub use parser::*;
|
|
@ -1,10 +1,15 @@
|
|||
use crate::lexer::token::Token;
|
||||
use crate::parser::ast::Expression;
|
||||
use crate::parser::ast::Statement;
|
||||
use crate::lexer::Lexer;
|
||||
|
||||
pub struct Parser {
|
||||
tokens: Vec<Token>,
|
||||
current: usize,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
||||
impl Parser {
|
||||
fn parse_statement(&mut self) -> Option<Statement> {
|
||||
if self.match_token(Token::Print) {
|
||||
|
@ -23,14 +28,89 @@ impl Parser {
|
|||
}
|
||||
|
||||
fn parse_print_statement(&mut self) -> Option<Statement> {
|
||||
let value = self.parse.expression();
|
||||
let value = self.parse_expression()?;
|
||||
if self.match_token(Token::Semicolon) {
|
||||
Some(Statement::PrintStatement(value?))
|
||||
Some(Statement::PrintStatement(value))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_variable_declaration(&mut self) -> Option<Statement> {
|
||||
let token = self.advance().clone();
|
||||
|
||||
if let Token::Identifier(name) = token {
|
||||
let has_initializer = self.match_token(Token::Equal);
|
||||
|
||||
let initializer = if has_initializer {
|
||||
self.parse_expression()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if self.match_token(Token::Semicolon) {
|
||||
Some(Statement::VariableDeclaration(name, initializer))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_if_statement(&mut self) -> Option<Statement> {
|
||||
self.match_token(Token::LeftParen);
|
||||
let condition = self.parse_expression()?;
|
||||
self.match_token(Token::RightParen);
|
||||
|
||||
let then_branch = Box::new(self.parse_statement()?);
|
||||
let else_branch = if self.match_token(Token::Else) {
|
||||
Some(Box::new(self.parse_statement()?))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Some(Statement::IfStatement(condition, then_branch, else_branch))
|
||||
}
|
||||
|
||||
fn parse_while_statement(&mut self) -> Option<Statement> {
|
||||
self.match_token(Token::LeftParen);
|
||||
let condition = self.parse_expression()?;
|
||||
self.match_token(Token::RightParen);
|
||||
|
||||
let body = Box::new(self.parse_statement()?);
|
||||
|
||||
Some(Statement::WhileStatement(condition, body))
|
||||
}
|
||||
|
||||
fn parse_for_statement(&mut self) -> Option<Statement> {
|
||||
self.match_token(Token::LeftParen);
|
||||
|
||||
let initializer = Box::new(self.parse_statement()?);
|
||||
let condition = self.parse_expression()?;
|
||||
self.match_token(Token::Semicolon);
|
||||
let increment = Box::new(self.parse_statement()?);
|
||||
|
||||
self.match_token(Token::RightParen);
|
||||
let body = Box::new(self.parse_statement()?);
|
||||
|
||||
Some(Statement::ForStatement(initializer, condition, increment, body))
|
||||
}
|
||||
|
||||
fn parse_expression_statement(&mut self) -> Option<Statement> {
|
||||
let expr = self.parse_expression()?;
|
||||
if self.match_token(Token::Semicolon) {
|
||||
Some(Statement::ExpressionStatement(expr))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_expression(&mut self) -> Option<Expression> {
|
||||
// Placeholder for expression parsing logic
|
||||
None
|
||||
}
|
||||
|
||||
pub fn new(tokens: Vec<Token>) -> Self {
|
||||
Parser {
|
||||
tokens,
|
||||
|
|
Loading…
Reference in a new issue