mirror of
https://git.fddl.dev/fddl/fddl.git
synced 2024-12-25 21:50:31 +00:00
building parser
This commit is contained in:
parent
6273dbdd7b
commit
c08f292bd8
7 changed files with 142 additions and 24 deletions
|
@ -1,3 +1,3 @@
|
||||||
func main() {
|
func main() {
|
||||||
print(`hello, world in fddl`);
|
print("hello, world in fddl");
|
||||||
}
|
}
|
||||||
|
|
5
hello.fddl
Normal file
5
hello.fddl
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
!test
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
print("Hello World");
|
||||||
|
}
|
29
readme.md
29
readme.md
|
@ -27,11 +27,20 @@ To start experimenting with fddl, you can run it in two ways:
|
||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run a fddl Script
|
### Parse a fddl Script
|
||||||
```sh
|
```sh
|
||||||
cargo run path/to/script.fddl
|
cargo run path/to/script.fddl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Running the Project
|
||||||
|
|
||||||
|
Make sure your project compiles and the tests pass:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build
|
||||||
|
cargo test
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
@ -77,7 +86,7 @@ fddl is very much a work in progress, with lots of planned improvements and addi
|
||||||
- [ ] Currently a placeholder. Implement parsing for function calls, expressions, etc.
|
- [ ] Currently a placeholder. Implement parsing for function calls, expressions, etc.
|
||||||
|
|
||||||
- **Compiler**:
|
- **Compiler**:
|
||||||
- [ ] Currently a placeholder. Implement the compiler to execute parsed code.
|
- [ ] Currently a placeholder. Implement the compiler to compile parsed code.
|
||||||
|
|
||||||
- **Comments**:
|
- **Comments**:
|
||||||
- [x] Added support for single-line and documentation comments.
|
- [x] Added support for single-line and documentation comments.
|
||||||
|
@ -85,26 +94,14 @@ fddl is very much a work in progress, with lots of planned improvements and addi
|
||||||
- [ ] Implement document building comments.
|
- [ ] Implement document building comments.
|
||||||
|
|
||||||
- **Error Handling**:
|
- **Error Handling**:
|
||||||
- [ ] Replace basic error reporting with a more robust error handling mechanism.
|
- [ ] Replace `stderr` with a more robust error handling mechanism.
|
||||||
|
|
||||||
- **String Interpolation**:
|
|
||||||
- [ ] Implement string interpolation using backticks with `$variable` syntax.
|
|
||||||
|
|
||||||
- **Testing**:
|
- **Testing**:
|
||||||
- [x] Added initial lexer tests.
|
- [x] Added initial `lexer` tests.
|
||||||
- [ ] Expand tests to cover more syntax and edge cases.
|
- [ ] Expand tests to cover more syntax and edge cases.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Running the Project
|
|
||||||
|
|
||||||
Make sure your project compiles and the tests pass:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo build
|
|
||||||
cargo test
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License.
|
This project is licensed under the MIT License.
|
||||||
|
|
|
@ -23,7 +23,12 @@ impl Lexer {
|
||||||
while !self.is_at_end() {
|
while !self.is_at_end() {
|
||||||
self.start = self.current;
|
self.start = self.current;
|
||||||
if let Some(token) = self.scan_token() {
|
if let Some(token) = self.scan_token() {
|
||||||
tokens.push(token);
|
if matches!(token, Token::Error(_)) {
|
||||||
|
tokens.push(token);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
tokens.push(token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +76,7 @@ impl Lexer {
|
||||||
if self.match_char('=') {
|
if self.match_char('=') {
|
||||||
Some(Token::BangEqual)
|
Some(Token::BangEqual)
|
||||||
} else {
|
} else {
|
||||||
None // Or handle as an error or another token if needed
|
Some(Token::Error(format!("Unexpected character '{}'", c)))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'=' => {
|
'=' => {
|
||||||
|
@ -111,7 +116,7 @@ impl Lexer {
|
||||||
// Any other character
|
// Any other character
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Unexpected character '{}' on line {}", c, self.line);
|
eprintln!("Unexpected character '{}' on line {}", c, self.line);
|
||||||
None
|
Some(Token::Error(format!("Unexpected character '{}'", c)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +243,8 @@ impl Lexer {
|
||||||
"print" => Token::Print,
|
"print" => Token::Print,
|
||||||
"pub" => Token::Pub,
|
"pub" => Token::Pub,
|
||||||
"sym" => Token::Sym,
|
"sym" => Token::Sym,
|
||||||
|
"module" => Token::Module,
|
||||||
|
"import" => Token::Import,
|
||||||
_ => Token::Identifier(text),
|
_ => Token::Identifier(text),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,14 @@ pub enum Token {
|
||||||
Print,
|
Print,
|
||||||
Pub,
|
Pub,
|
||||||
Sym,
|
Sym,
|
||||||
|
Module,
|
||||||
|
Import,
|
||||||
|
|
||||||
// Comments
|
// Comments
|
||||||
Comment(String),
|
Comment(String),
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
Error(String),
|
||||||
|
|
||||||
EOF,
|
EOF,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,47 @@
|
||||||
// placeholder for ast defintions
|
|
||||||
|
|
||||||
pub enum Expression {
|
pub enum Expression {
|
||||||
// Define expression types
|
Literal(Literal),
|
||||||
|
Variable(String),
|
||||||
|
Binary(Box<Expression>, Operator, Box<Expression>),
|
||||||
|
Unary(Operator, Box<Expression>),
|
||||||
|
Grouping(Box<Expression>),
|
||||||
|
Assignment(String, Box<Expression>),
|
||||||
|
FunctionCall(Box<Expression>, Vec<Expression>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Literal {
|
||||||
|
Number(f64),
|
||||||
|
String(String),
|
||||||
|
Boolean(bool),
|
||||||
|
Nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Operator {
|
||||||
|
Plus,
|
||||||
|
Minux,
|
||||||
|
Multiply,
|
||||||
|
Divide,
|
||||||
|
Greater,
|
||||||
|
Less,
|
||||||
|
GreaterEqual,
|
||||||
|
LessEqual,
|
||||||
|
EqualEqual,
|
||||||
|
NotEqual,
|
||||||
|
AlmostEqual,
|
||||||
|
Almost,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
// Define statement types
|
ExpressionStatement(Expression),
|
||||||
|
PrintStatement(Expression),
|
||||||
|
VariableDeclaration(String, Option<Expression>),
|
||||||
|
Block(Vec<Statement>),
|
||||||
|
IfStatement(Expression, Box<Statement>, Option<Box<Statement>>),
|
||||||
|
WhileStatement(Expression, Box<Statement>),
|
||||||
|
ForStatement(Box<Statement>, Expression, Box<Statement>, Box<Statement>),
|
||||||
|
FunctionDeclaration {
|
||||||
|
name: String,
|
||||||
|
params: Vec<String>,
|
||||||
|
body: Vec<Statement>,
|
||||||
|
},
|
||||||
|
ReturnStatement(Option<Expression>),
|
||||||
}
|
}
|
66
src/parser/parser.rs
Normal file
66
src/parser/parser.rs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
use crate::lexer::token::Token;
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 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