Skip to content

Commit

Permalink
parser: add first implementation to parse statement
Browse files Browse the repository at this point in the history
Signed-off-by: FedericoBruzzone <[email protected]>
  • Loading branch information
FedericoBruzzone committed Aug 19, 2024
1 parent 3013597 commit 978ece0
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 19 deletions.
4 changes: 4 additions & 0 deletions src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ impl Lexer {
lexer
}

pub fn cursor(&self) -> &Cursor {
&self.cursor
}

fn proceed(state: Box<dyn State>, transition_kind: TransitionKind) -> Transition {
Transition::new(state, transition_kind)
}
Expand Down
13 changes: 5 additions & 8 deletions src/lexer/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,11 @@ impl State for StateSymbol {
TransitionKind::EmitToken(Token::new(token_kind, lexeme, location)),
))
}
Some(c) => Ok(Lexer::proceed(
Box::new(StateStart),
TransitionKind::EmitToken(Token::new(
TokenKind::TokenUnknown,
c.to_string(),
cursor.location().clone(),
)),
)),
Some(c) => Err(LexerError::UnexpectedToken(Token::new(
TokenKind::TokenUnknown,
c.to_string(),
cursor.location().clone(),
))),
None => Ok(Lexer::proceed(Box::new(StateEOF), TransitionKind::Consume)),
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/lexer/token.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::utils::color;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -320,7 +319,7 @@ impl From<&PathBuf> for TokenLocation {
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct Token {
/// The kind of the token
kind: TokenKind,
pub kind: TokenKind,
/// The lexeme is the string representation of the token
///
/// For example:
Expand Down Expand Up @@ -435,13 +434,14 @@ impl std::fmt::Display for TokenLocation {

impl std::fmt::Display for Token {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
// use crate::utils::color;
write!(
f,
"{} {{ {}, \"{}\", {} }}",
color::cyan("Token"),
color::yellow(&format!("{}", self.kind)),
color::magenta(&self.lexeme),
color::blue(&format!("{}", self.location))
"Token {{ {}, \"{}\", {} }}",
// color::cyan("Token"),
self.kind, // color::yellow(&format!("{}", self.kind)),
self.lexeme, // color::magenta(&self.lexeme),
self.location, // color::blue(&format!("{}", self.location))
)
}
}
17 changes: 13 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
pub mod lexer;
pub mod logger;
pub mod parser;
pub mod source;
pub mod utils;

use lexer::{token::Token, Lexer};
use lexer::Lexer;
use logger::Logger;
use parser::Parser;
use source::Source;
use std::{env, path::PathBuf};

Expand All @@ -29,7 +31,14 @@ fn main() {

let file_path: &str = &args[0];
let source = Source::new(file_path);
let mut lexer = Lexer::new(&source);
let _tokens = (&mut lexer).collect::<Vec<Token>>();
lexer.emit_errors();
let lexer = Lexer::new(&source);
// let _tokens = (&mut lexer).collect::<Vec<Token>>();
// if lexer.errors().is_empty() {
// println!("No errors found");
// } else {
// lexer.emit_errors();
// }
let mut parser = Parser::new(lexer);
// let _ast = (&mut parser).collect::<Vec<parser::ast::Block>>();
println!("{}", parser.parse());
}
119 changes: 119 additions & 0 deletions src/parser/ast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
use crate::source::Source;

pub struct Ast {
pub source: Source,
pub root: Block,
}

#[derive(Debug)]
pub struct Block {
pub stmts: Box<[Stmt]>,
}

#[derive(Debug)]
pub enum Stmt {
Assign {
ident: Identifier,
type_: Type,
expr: Expr,
},
Expr(Expr),
}

#[derive(Debug)]
pub enum Type {
Int,
Float,
Bool,
Str,
}

#[derive(Debug)]
pub enum Expr {
Literal(Literal),
Identifier(Identifier),
}

#[derive(Debug)]
pub enum Literal {
Int(i64),
Float(f64),
Bool(bool),
Str(String),
}

#[derive(Debug)]
pub struct Identifier {
pub name: String,
}

impl Ast {
pub fn new(source: Source, root: Block) -> Ast {
Ast { source, root }
}
}

impl std::fmt::Display for Ast {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Block [{}]", self.root)
}
}

impl std::fmt::Display for Block {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
for stmt in self.stmts.iter() {
write!(f, " {} ", stmt)?;
}
Ok(())
}
}

impl std::fmt::Display for Stmt {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Stmt::Assign { ident, type_, expr } => write!(
f,
"Stmt::Assign {{ ident: {}, type: {}, expr: {} }}",
ident, type_, expr
),
Stmt::Expr(expr) => write!(f, "Stmt::Expr({})", expr),
}
}
}

impl std::fmt::Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Type::Int => write!(f, "int"),
Type::Float => write!(f, "float"),
Type::Bool => write!(f, "bool"),
Type::Str => write!(f, "str"),
}
}
}

impl std::fmt::Display for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Expr::Literal(literal) => write!(f, "{}", literal),
Expr::Identifier(ident) => write!(f, "{}", ident),
}
}
}

impl std::fmt::Display for Literal {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Literal::Int(int) => write!(f, "{}", int),
Literal::Float(float) => write!(f, "{}", float),
Literal::Bool(bool) => write!(f, "{}", bool),
Literal::Str(string) => write!(f, "{}", string),
}
}
}

impl std::fmt::Display for Identifier {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.name)
}
}
Loading

0 comments on commit 978ece0

Please sign in to comment.