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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wavec"
version = "0.1.5-pre-beta"
version = "0.1.6-pre-beta"
edition = "2021"

[lib]
Expand Down
2 changes: 0 additions & 2 deletions front/lexer/src/lexer/common.rs

This file was deleted.

3 changes: 1 addition & 2 deletions front/lexer/src/lexer/core.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::token::TokenType;
use super::common::*;

#[derive(Debug, Clone)]
pub struct Token {
Expand Down Expand Up @@ -39,7 +38,7 @@ impl<'a> Lexer<'a> {
pub fn tokenize(&mut self) -> Vec<Token> {
let mut tokens = Vec::new();
loop {
let token = self.next_token(); // scan.rs에 구현
let token = self.next_token();
if token.token_type == TokenType::Eof {
tokens.push(token);
break;
Expand Down
4 changes: 0 additions & 4 deletions front/lexer/src/lexer/ident.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::token::*;
use super::common::*;
use super::{Lexer, Token};

impl<'a> Lexer<'a> {
Expand All @@ -19,9 +18,6 @@ impl<'a> Lexer<'a> {
}

pub(crate) fn keyword_or_ident_token(&self, ident: String) -> Token {
// 여기엔 기존 match identifier.as_str() { ... } 통째로 옮겨와
// 단, Token { token_type: ..., lexeme: ..., line: self.line } 형태 그대로 유지
// 마지막 default는 Identifier(ident.clone())
match ident.as_str() {
"fun" => Token {
token_type: TokenType::Fun,
Expand Down
1 change: 0 additions & 1 deletion front/lexer/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
clippy::new_without_default
)]

mod common;
mod core;
mod cursor;
mod trivia;
Expand Down
1 change: 0 additions & 1 deletion front/lexer/src/lexer/scan.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::token::*;
use super::common::*;
use super::{Lexer, Token};

impl<'a> Lexer<'a> {
Expand Down
41 changes: 41 additions & 0 deletions front/parser/src/expr/assign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use lexer::Token;
use lexer::token::TokenType;
use crate::ast::{AssignOperator, Expression};
use crate::expr::binary::parse_logical_or_expression;

pub fn parse_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
parse_assignment_expression(tokens)
}

pub fn parse_assignment_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let left = parse_logical_or_expression(tokens)?;

if let Some(token) = tokens.peek() {
let op = match token.token_type {
TokenType::Equal => AssignOperator::Assign,
TokenType::PlusEq => AssignOperator::AddAssign,
TokenType::MinusEq => AssignOperator::SubAssign,
TokenType::StarEq => AssignOperator::MulAssign,
TokenType::DivEq => AssignOperator::DivAssign,
TokenType::RemainderEq => AssignOperator::RemAssign,
_ => return Some(left),
};

tokens.next(); // consume op

let right = parse_assignment_expression(tokens)?;
return Some(Expression::AssignOperation {
target: Box::new(left),
operator: op,
value: Box::new(right),
});
}

Some(left)
}
223 changes: 223 additions & 0 deletions front/parser/src/expr/binary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
use lexer::Token;
use lexer::token::TokenType;
use crate::ast::{Expression, Operator};
use crate::expr::unary::parse_unary_expression;

pub fn parse_logical_or_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_logical_and_expression(tokens)?;

while matches!(tokens.peek().map(|t| &t.token_type), Some(TokenType::LogicalOr)) {
tokens.next();
let right = parse_logical_and_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: Operator::LogicalOr,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_logical_and_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_bitwise_or_expression(tokens)?;

while matches!(tokens.peek().map(|t| &t.token_type), Some(TokenType::LogicalAnd)) {
tokens.next();
let right = parse_bitwise_or_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: Operator::LogicalAnd,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_bitwise_or_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_bitwise_xor_expression(tokens)?;

while matches!(tokens.peek().map(|t| &t.token_type), Some(TokenType::BitwiseOr)) {
tokens.next();
let right = parse_bitwise_xor_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: Operator::BitwiseOr,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_bitwise_xor_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_bitwise_and_expression(tokens)?;

while matches!(tokens.peek().map(|t| &t.token_type), Some(TokenType::Xor)) {
tokens.next();
let right = parse_bitwise_and_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: Operator::BitwiseXor,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_bitwise_and_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_equality_expression(tokens)?;

while matches!(tokens.peek().map(|t| &t.token_type), Some(TokenType::AddressOf)) {
tokens.next();
let right = parse_equality_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: Operator::BitwiseAnd,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_equality_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_relational_expression(tokens)?;

while let Some(token) = tokens.peek() {
let op = match token.token_type {
TokenType::EqualTwo => Operator::Equal,
TokenType::NotEqual => Operator::NotEqual,
_ => break,
};
tokens.next();
let right = parse_relational_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: op,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_relational_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_shift_expression(tokens)?;

while let Some(token) = tokens.peek() {
let op = match token.token_type {
TokenType::Rchevr => Operator::Greater,
TokenType::RchevrEq => Operator::GreaterEqual,
TokenType::Lchevr => Operator::Less,
TokenType::LchevrEq => Operator::LessEqual,
_ => break,
};
tokens.next();
let right = parse_shift_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: op,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_shift_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_additive_expression(tokens)?;

while let Some(token) = tokens.peek() {
let op = match token.token_type {
TokenType::Rol => Operator::ShiftLeft,
TokenType::Ror => Operator::ShiftRight,
_ => break,
};

tokens.next();
let right = parse_additive_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: op,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_additive_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_multiplicative_expression(tokens)?;

while let Some(token) = tokens.peek() {
let op = match token.token_type {
TokenType::Plus => Operator::Add,
TokenType::Minus => Operator::Subtract,
_ => break,
};
tokens.next();
let right = parse_multiplicative_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: op,
right: Box::new(right),
};
}

Some(left)
}

pub fn parse_multiplicative_expression<'a, T>(tokens: &mut std::iter::Peekable<T>) -> Option<Expression>
where
T: Iterator<Item = &'a Token>,
{
let mut left = parse_unary_expression(tokens)?;

while let Some(token) = tokens.peek() {
let op = match token.token_type {
TokenType::Star => Operator::Multiply,
TokenType::Div => Operator::Divide,
TokenType::Remainder => Operator::Remainder,
_ => break,
};
tokens.next();
let right = parse_unary_expression(tokens)?;
left = Expression::BinaryExpression {
left: Box::new(left),
operator: op,
right: Box::new(right),
};
}

Some(left)
}
39 changes: 39 additions & 0 deletions front/parser/src/expr/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use std::iter::Peekable;
use std::slice::Iter;
use lexer::Token;
use lexer::token::TokenType;
use crate::ast::Expression;
pub fn is_assignable(expr: &Expression) -> bool {
match expr {
Expression::Variable(_) => true,
Expression::Deref(_) => true,
Expression::FieldAccess { .. } => true,
Expression::IndexAccess { .. } => true,

Expression::Grouped(inner) => is_assignable(inner),

_ => false,
}
}

pub fn parse_expression_from_token(
first_token: &Token,
tokens: &mut Peekable<Iter<Token>>,
) -> Option<Expression> {
match &first_token.token_type {
TokenType::Identifier(name) => Some(Expression::Variable(name.clone())),

TokenType::Deref => {
if let Some(next_token) = tokens.next() {
if let TokenType::Identifier(name) = &next_token.token_type {
return Some(Expression::Deref(Box::new(Expression::Variable(
name.clone(),
))));
}
}
None
}

_ => None,
}
}
9 changes: 9 additions & 0 deletions front/parser/src/expr/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod helpers;
mod primary;
mod postfix;
mod unary;
mod binary;
mod assign;

pub use helpers::*;
pub use assign::parse_expression;
Loading