Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions front/parser/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
pub mod parser;
pub mod ast;
pub mod format;
pub mod import;
pub mod stdlib;
pub mod type_system;
pub mod verification;

pub use parser::*;
140 changes: 140 additions & 0 deletions front/parser/src/parser/asm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use std::iter::Peekable;
use std::slice::Iter;
use lexer::{Token, TokenType};
use crate::ast::{ASTNode, StatementNode};

pub fn parse_asm_block(tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
if tokens.peek()?.token_type != TokenType::Lbrace {
println!("Expected '{{' after 'asm'");
return None;
}
tokens.next();

let mut instructions = vec![];
let mut inputs = vec![];
let mut outputs = vec![];

while let Some(token) = tokens.next() {
match &token.token_type {
TokenType::Rbrace => break,

TokenType::In | TokenType::Out => {
let is_input = matches!(token.token_type, TokenType::In);

if tokens.next().map(|t| t.token_type.clone()) != Some(TokenType::Lparen) {
println!("Expected '(' after in/out");
return None;
}

let reg_token = tokens.next();
let reg = match reg_token {
Some(Token {
token_type: TokenType::String(s),
..
}) => s.clone(),
Some(Token {
token_type: TokenType::Identifier(s),
..
}) => s.clone(),
Some(other) => {
println!(
"Expected register string or identifier, got {:?}",
other.token_type
);
return None;
}
None => {
println!("Expected register in in/out(...)");
return None;
}
};

if tokens.next().map(|t| t.token_type.clone()) != Some(TokenType::Rparen) {
println!("Expected ')' after in/out");
return None;
}

let value_token = tokens.next();
let value = match value_token {
Some(Token {
token_type: TokenType::Minus,
..
}) => match tokens.next() {
Some(Token {
token_type: TokenType::Number(n),
..
}) => format!("-{}", n),
Some(other) => {
println!("Expected number after '-', got {:?}", other.token_type);
return None;
}
None => {
println!("Expected number after '-'");
return None;
}
},
Some(Token {
token_type: TokenType::AddressOf,
..
}) => match tokens.next() {
Some(Token {
token_type: TokenType::Identifier(s),
..
}) => format!("&{}", s),
Some(other) => {
println!("Expected identifier after '&', got {:?}", other.token_type);
return None;
}
None => {
println!("Expected identifier after '&'");
return None;
}
},
Some(Token {
token_type: TokenType::Identifier(s),
..
}) => s.clone(),
Some(Token {
token_type: TokenType::Number(n),
..
}) => n.to_string(),
Some(Token {
token_type: TokenType::String(n),
..
}) => n.to_string(),
Some(other) => {
println!(
"Expected identifier or number after in/out(...), got {:?}",
other.token_type
);
return None;
}
None => {
println!("Expected value after in/out(...)");
return None;
}
};

if is_input {
inputs.push((reg.clone(), value));
} else {
outputs.push((reg.clone(), value));
}
}

TokenType::String(s) => {
instructions.push(s.clone());
}

other => {
println!("Unexpected token in asm expression {:?}", other);
}
}
}

Some(ASTNode::Statement(StatementNode::AsmBlock {
instructions,
inputs,
outputs,
}))
}
149 changes: 149 additions & 0 deletions front/parser/src/parser/control.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use std::iter::Peekable;
use std::slice::Iter;
use lexer::{Token, TokenType};
use crate::ast::{ASTNode, Expression, StatementNode};
use crate::format::parse_expression;
use crate::parser::stmt::parse_block;

pub fn parse_if(tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
if tokens.peek()?.token_type != TokenType::Lparen {
println!("Error: Expected '(' after 'if'");
return None;
}
tokens.next(); // Consume '('

let condition = parse_expression(tokens)?;

if tokens.peek()?.token_type != TokenType::Rparen {
println!("Error: Expected ')' after 'if' condition");
return None;
}
tokens.next(); // Consume ')'

if tokens.peek()?.token_type != TokenType::Lbrace {
println!("Error: Expected '{{' after 'if' condition");
return None;
}
tokens.next(); // Consume '{'
let body = parse_block(tokens)?;

let mut else_if_blocks: Vec<(Expression, Vec<ASTNode>)> = Vec::new(); // Changed to store conditions and bodies
let mut else_block = None;

while let Some(token) = tokens.peek() {
if token.token_type != TokenType::Else {
break;
}
tokens.next(); // consume 'else'

if let Some(Token {
token_type: TokenType::If,
..
}) = tokens.peek()
{
tokens.next(); // consume 'if'

if tokens.peek()?.token_type != TokenType::Lparen {
println!("Error: Expected '(' after 'else if'");
return None;
}
tokens.next();
let else_if_condition = parse_expression(tokens)?;

if tokens.peek()?.token_type != TokenType::Rparen {
println!("Error: Expected ')' after 'else if' condition");
return None;
}
tokens.next();

if tokens.peek()?.token_type != TokenType::Lbrace {
println!("Error: Expected '{{' after 'else if'");
return None;
}
tokens.next();
let else_if_body = parse_block(tokens)?;

// Store condition and body directly instead of nested If node
else_if_blocks.push((else_if_condition, else_if_body));
} else {
if tokens.peek()?.token_type != TokenType::Lbrace {
println!("Error: Expected '{{' after 'else'");
return None;
}
tokens.next();
else_block = Some(Box::new(parse_block(tokens)?));
break;
}
}

Some(ASTNode::Statement(StatementNode::If {
condition,
body,
else_if_blocks: if else_if_blocks.is_empty() {
None
} else {
Some(Box::new(else_if_blocks))
},
else_block,
}))
}

// FOR parsing
pub fn parse_for(_tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
// TODO: Implement proper for loop parsing
/*
// Check 'for' keyword and see if there is '()
if tokens.peek()?.token_type != TokenType::Lparen {
println!("Error: Expected '(' after 'if'");
return None;
}
tokens.next(); // '(' Consumption

// Conditional parsing (where condition must be made ASTNode)
let initialization = parse_expression(tokens)?; // Parsing conditions with expressions
let condition = parse_expression(tokens)?;
let increment = parse_expression(tokens)?;
let body = parse_expression(tokens)?;

if tokens.peek()?.token_type != TokenType::Rparen {
println!("Error: Expected ')' after condition");
return None;
}
tokens.next(); // ')' Consumption

Some(ASTNode::Statement(StatementNode::For {
initialization,
condition,
increment,
body,
}))
*/
None
}

// WHILE parsing
pub fn parse_while(tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
if tokens.peek()?.token_type != TokenType::Lparen {
println!("Error: Expected '(' after 'while'");
return None;
}
tokens.next(); // Consume '('

let condition = parse_expression(tokens)?;

if tokens.peek()?.token_type != TokenType::Rparen {
println!("Error: Expected ')' after 'while' condition");
return None;
}
tokens.next(); // Consume ')'

if tokens.peek()?.token_type != TokenType::Lbrace {
println!("Error: Expected '{{' after 'while'");
return None;
}
tokens.next(); // Consume '{'

let body = parse_block(tokens)?;

Some(ASTNode::Statement(StatementNode::While { condition, body }))
}
Loading