mirror of
https://git.fddl.dev/fddl/fddl.git
synced 2024-12-24 21:30: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,84 +1,164 @@
|
|||
use crate::lexer::token::Token;
|
||||
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,
|
||||
}
|
||||
|
||||
impl Parser {
|
||||
fn parse_statement(&mut self) -> Option<Statement> {
|
||||
if self.match_token(Token::Print) {
|
||||
self.parse_print_statement()
|
||||
} else if self.match_token(Token::Let) {
|
||||
self.parse_variable_declaration()
|
||||
} else if self.match_token(Token::If) {
|
||||
self.parse_if_statement()
|
||||
} else if self.match_token(Token::While) {
|
||||
self.parse_while_statement()
|
||||
} else if self.match_token(Token::For) {
|
||||
self.parse_for_statement()
|
||||
} else {
|
||||
self.parse_expression_statement()
|
||||
}
|
||||
pub struct Parser {
|
||||
tokens: Vec<Token>,
|
||||
current: usize,
|
||||
}
|
||||
|
||||
fn parse_print_statement(&mut self) -> Option<Statement> {
|
||||
let value = self.parse.expression();
|
||||
if self.match_token(Token::Semicolon) {
|
||||
Some(Statement::PrintStatement(value?))
|
||||
} else {
|
||||
#[allow(dead_code)]
|
||||
|
||||
impl Parser {
|
||||
fn parse_statement(&mut self) -> Option<Statement> {
|
||||
if self.match_token(Token::Print) {
|
||||
self.parse_print_statement()
|
||||
} else if self.match_token(Token::Let) {
|
||||
self.parse_variable_declaration()
|
||||
} else if self.match_token(Token::If) {
|
||||
self.parse_if_statement()
|
||||
} else if self.match_token(Token::While) {
|
||||
self.parse_while_statement()
|
||||
} else if self.match_token(Token::For) {
|
||||
self.parse_for_statement()
|
||||
} else {
|
||||
self.parse_expression_statement()
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_print_statement(&mut self) -> Option<Statement> {
|
||||
let value = self.parse_expression()?;
|
||||
if self.match_token(Token::Semicolon) {
|
||||
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,
|
||||
current: 0,
|
||||
pub fn new(tokens: Vec<Token>) -> Self {
|
||||
Parser {
|
||||
tokens,
|
||||
current: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn current_token(&self) -> &Token {
|
||||
&self.tokens[self.current]
|
||||
}
|
||||
|
||||
fn peek(&self) -> &Token {
|
||||
&self.tokens[self.current + 1]
|
||||
}
|
||||
|
||||
fn is_at_end(&self) -> bool {
|
||||
matches!(self.current_token(), Token::EOF)
|
||||
}
|
||||
|
||||
fn advance(&mut self) -> &Token {
|
||||
if !self.is_at_end() {
|
||||
self.current += 1;
|
||||
}
|
||||
self.current_token()
|
||||
}
|
||||
|
||||
fn match_token(&mut self, expected: Token) -> bool {
|
||||
if self.current_token() == &expected {
|
||||
self.advance();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn previous_token(&self) -> &Token {
|
||||
&self.tokens[self.current - 1]
|
||||
}
|
||||
}
|
||||
|
||||
fn current_token(&self) -> &Token {
|
||||
&self.tokens[self.current]
|
||||
}
|
||||
fn main() {
|
||||
let source = String::from("let x = 10;");
|
||||
let mut lexer = Lexer::new(source);
|
||||
let tokens = lexer.scan_tokens();
|
||||
let mut parser = Parser::new(tokens);
|
||||
|
||||
fn peek(&self) -> &Token {
|
||||
&self.tokens[self.current + 1]
|
||||
}
|
||||
|
||||
fn is_at_end(&self) -> bool {
|
||||
matches!(self.current_token(), Token::EOF)
|
||||
}
|
||||
|
||||
fn advance(&mut self) -> &Token {
|
||||
if !self.is_at_end() {
|
||||
self.current += 1;
|
||||
}
|
||||
self.current_token()
|
||||
}
|
||||
|
||||
fn match_token(&mut self, expected: Token) -> bool {
|
||||
if self.current_token() == &expected {
|
||||
self.advance();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
while !parser.is_at_end() {
|
||||
println!("{:?}", parser.current_token());
|
||||
parser.advance();
|
||||
}
|
||||
}
|
||||
|
||||
fn previous_token(&self) -> &Token {
|
||||
&self.tokens[self.current - 1]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let source = String::from("let x = 10;");
|
||||
let mut lexer = Lexer::new(source);
|
||||
let tokens = lexer.scan_tokens();
|
||||
let mut parser = Parser::new(tokens);
|
||||
|
||||
while !parser.is_at_end() {
|
||||
println!("{:?}", parser.current_token());
|
||||
parser.advance();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue