From b7a6e4f85fa14ae06aa9493c4484b16b7c823513 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:59:08 +0200 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20removed=20op=C3=83erator=20parsing?= =?UTF-8?q?=20from=20lexer=20for=20more=20parsing=20freedom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- compiler/ast/src/lib.rs | 1 + compiler/ast/src/operators.rs | 21 ++++++ compiler/lexer/src/lexer.rs | 111 ++------------------------------ compiler/lexer/src/lib.rs | 3 +- compiler/lexer/src/token.rs | 49 +++----------- compiler/lexer/src/toks/comp.rs | 12 ---- compiler/lexer/src/toks/math.rs | 10 --- compiler/lexer/src/toks/mod.rs | 2 - 8 files changed, 35 insertions(+), 174 deletions(-) create mode 100644 compiler/ast/src/operators.rs delete mode 100644 compiler/lexer/src/toks/comp.rs delete mode 100644 compiler/lexer/src/toks/math.rs delete mode 100644 compiler/lexer/src/toks/mod.rs diff --git a/compiler/ast/src/lib.rs b/compiler/ast/src/lib.rs index e81ff1a..688dee0 100644 --- a/compiler/ast/src/lib.rs +++ b/compiler/ast/src/lib.rs @@ -5,3 +5,4 @@ pub mod tree; pub mod ctx; pub mod types; +pub mod operators; \ No newline at end of file diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs new file mode 100644 index 0000000..e88de57 --- /dev/null +++ b/compiler/ast/src/operators.rs @@ -0,0 +1,21 @@ +//! Operator related utils + +/// The different math operators +#[derive(Debug, PartialEq, Clone)] +pub enum MathOperator { + ADD, + SUBSTRACT, + MULTIPLY, + DIVIDE +} + +/// The different comparing operators +#[derive(Debug, PartialEq, Clone)] +pub enum ComparingOperator { + Equal, // A == B + NotEqual, // A != B + Higher, // A > B + HigherEqual, // A >= B + Lower, // A < B + LowerEqual // A <= B +} \ No newline at end of file diff --git a/compiler/lexer/src/lexer.rs b/compiler/lexer/src/lexer.rs index 8c6d965..cea6193 100644 --- a/compiler/lexer/src/lexer.rs +++ b/compiler/lexer/src/lexer.rs @@ -9,7 +9,7 @@ use diagnostics::DiagnosticResult; use diagnostics::builders::{make_unexpected_simple_error_outside}; use diagnostics::diagnostic::SpanPosition; -use crate::{token::{LexerToken, LexerTokenType}, toks::{comp::ComparingOperator, math::MathOperator}}; +use crate::{token::{LexerToken, LexerTokenType}}; const SHADOWFUNC_KEYWORD_HASH: u64 = hash!("shadowfunc"); const FUNC_KEYWORD_HASH: u64 = hash!("func"); @@ -81,27 +81,6 @@ pub fn lexer_parse_file(file_path: &String) -> DiagnosticResult> continue; } - if c == '+' || c == '-' || c == '*' || c == '/' { - let col = i - last_line_break; - - tokens.push(parse_math_operator(&contents, &mut i, Position::new(file_path.to_string(), line, col))?); - - continue; - } - - if c == '=' || c == '>' || c == '<' { - let col = i - last_line_break; - - let parse = parse_comp_operator(&contents, &mut i, Position::new(file_path.to_string(), line, col)); - - if parse.is_some() { - tokens.push(parse.unwrap()); - continue; - } - - i -= 2; // Try parsing operator as normal token. - } - if c == '/' { let cc = contents.chars().nth(i + 1).unwrap(); if cc == '/' { @@ -140,6 +119,9 @@ pub fn lexer_parse_file(file_path: &String) -> DiagnosticResult> '>' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::AngelBracketClose)), '*' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Asterisk)), ':' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Collon)), + '+' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Plus)), + '-' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Minus)), + '/' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Divide)), _ => continue } @@ -194,91 +176,6 @@ fn parse_global_comment(contents: &String, ind: &mut usize, start_pos: Position) return Ok(LexerToken::new(start_pos, end - start, LexerTokenType::GlobalComment(slice.to_string()))) } -fn parse_math_operator(contents: &String, ind: &mut usize, start_pos: Position) -> DiagnosticResult { - let operator_char = contents.chars().nth(*ind).unwrap(); - - let operator = match operator_char { - '+' => MathOperator::ADD, - '-' => MathOperator::SUBSTRACT, - '*' => MathOperator::MULTIPLY, - '/' => MathOperator::DIVIDE, - _ => return Err(make_unexpected_simple_error_outside(&operator_char, SpanPosition::from_pos(start_pos.clone(), start_pos.col + 1)).into()) - }; - - *ind += 1; - - if contents.chars().nth(*ind).unwrap() != '=' { - return Ok(LexerToken::make_single_sized(start_pos, LexerTokenType::EqualSign)); - } - - let assigns = match contents.chars().nth(*ind) { - Some(v) => { - if v != ' ' && v != '=' { - return Err(make_unexpected_simple_error_outside(&v, SpanPosition::from_pos(start_pos.clone(), start_pos.col + 2).into()).into()) - } - - v == '=' - } - None => false - }; - - if assigns { - *ind += 1; - } - - let mut increment_count = 1; - - if assigns { - increment_count += 1; - } - - return Ok(LexerToken::new(start_pos, increment_count, LexerTokenType::MathOperator(operator, assigns))); - -} - -fn parse_comp_operator(contents: &String, ind: &mut usize, start_pos: Position) -> Option { - let first_char = contents.chars().nth(*ind).unwrap(); - *ind += 1; - let second_char = contents.chars().nth(*ind).unwrap(); - - *ind += 1; - - if second_char != '=' && second_char != ' ' { - return None; - } - - match first_char { - '=' => { - if second_char != '=' { - return None; - } - - return Some(LexerToken::new(start_pos, 2, LexerTokenType::ComparingOperator(ComparingOperator::Equal))); - }, - - '>' => { - if second_char == '=' { - return Some(LexerToken::new(start_pos, 2, LexerTokenType::ComparingOperator(ComparingOperator::HigherEqual))); - } - - return Some(LexerToken::new(start_pos, 2, LexerTokenType::ComparingOperator(ComparingOperator::Higher))); - }, - - '<' => { - if second_char == '=' { - return Some(LexerToken::new(start_pos, 2, LexerTokenType::ComparingOperator(ComparingOperator::LowerEqual))); - } - - return Some(LexerToken::new(start_pos, 2, LexerTokenType::ComparingOperator(ComparingOperator::Lower))); - }, - - _ => { - return None; - } - } - -} - fn parse_number_token(str: &String, ind: &mut usize, start_pos: Position) -> DiagnosticResult { let start = *ind + 1; let mut end: usize = start; diff --git a/compiler/lexer/src/lib.rs b/compiler/lexer/src/lib.rs index 8459f9e..baff5a2 100644 --- a/compiler/lexer/src/lib.rs +++ b/compiler/lexer/src/lib.rs @@ -4,5 +4,4 @@ //! pub mod token; -pub mod lexer; -pub mod toks; +pub mod lexer; \ No newline at end of file diff --git a/compiler/lexer/src/token.rs b/compiler/lexer/src/token.rs index f700669..6a0f2fc 100644 --- a/compiler/lexer/src/token.rs +++ b/compiler/lexer/src/token.rs @@ -7,8 +7,6 @@ use std::fmt::Display; use compiler_utils::{Position}; use diagnostics::{DiagnosticResult, DiagnosticSpanOrigin, builders::make_expected_simple_error, diagnostic::{Diagnostic, Span, SpanKind, SpanPosition}}; -use crate::{toks::{comp::ComparingOperator, math::MathOperator}}; - /// The token type for the lexer #[derive(PartialEq, Debug)] pub enum LexerTokenType { @@ -37,13 +35,6 @@ pub enum LexerTokenType { New, - /// 0: the operator - /// 1: does the operator affect the original variable! - MathOperator(MathOperator, bool), - - ComparingOperator(ComparingOperator), - - /// Represent the ret keyword Return, @@ -65,6 +56,10 @@ pub enum LexerTokenType { Ampersand, Collon, + Plus, + Minus, + Divide, + BracketOpen, BracketClose, @@ -113,21 +108,6 @@ impl LexerToken { return Ok(()); } - pub fn is_angel_bracket_close(&self) -> bool { - match &self.tok_type { - LexerTokenType::AngelBracketClose => true, - LexerTokenType::ComparingOperator(op) => { - if op == &ComparingOperator::Higher { - return true - } - - return false - }, - - _ => return false - } - } - pub fn expects_int_lit(&self) -> DiagnosticResult<(i128, u64)> { match &self.tok_type { LexerTokenType::IntLit(v, h) => return Ok((*v, *h)), @@ -135,20 +115,6 @@ impl LexerToken { }; } - pub fn expects_comp_operator(&self) -> DiagnosticResult { - match &self.tok_type { - LexerTokenType::ComparingOperator(op) => return Ok(op.clone()), - _ => return Err(make_expected_simple_error(self, &"comparing operator".to_string(), &self.tok_type).into()) - }; - } - - pub fn expects_math_operator(&self) -> DiagnosticResult<(MathOperator, bool)> { - match &self.tok_type { - LexerTokenType::MathOperator(a, b) => return Ok((a.clone(), *b)), - _ => return Err(make_expected_simple_error(self, &"math operator".to_string(), &self.tok_type).into()) - }; - } - pub fn expects_string_lit(&self) -> DiagnosticResult { match &self.tok_type { LexerTokenType::StringLit(v) => return Ok(v.to_string()), @@ -199,7 +165,6 @@ impl Display for LexerTokenType { Self::BracketOpen => "{", Self::Comma => ",", Self::Comment(_) => "comment", - Self::ComparingOperator(_) => "comparing operator", Self::Dot => ".", Self::Else => "else", Self::EndOfFile => "end of file", @@ -214,7 +179,6 @@ impl Display for LexerTokenType { Self::Keyword(_, _) => "keyword", Self::Lay => "lay", Self::Layout => "layout", - Self::MathOperator(_, _) => "math operator", Self::New => "new", Self::ParenClose => ")", Self::ParenOpen => "(", @@ -229,7 +193,10 @@ impl Display for LexerTokenType { Self::While => "while", Self::Unwrap => "unwrap", Self::Use => "use", - Self::UnwrapUnsafe => "unsafe_unwrap" + Self::UnwrapUnsafe => "unsafe_unwrap", + Self::Plus => "+", + Self::Minus => "-", + Self::Divide => "/" }; write!(f, "{}", s)?; diff --git a/compiler/lexer/src/toks/comp.rs b/compiler/lexer/src/toks/comp.rs deleted file mode 100644 index d8df3d0..0000000 --- a/compiler/lexer/src/toks/comp.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Comparing token related utils - -/// The different comparing tokens -#[derive(Debug, PartialEq, Clone)] -pub enum ComparingOperator { - Equal, // A == B - NotEqual, // A != B - Higher, // A > B - HigherEqual, // A >= B - Lower, // A < B - LowerEqual // A <= B -} \ No newline at end of file diff --git a/compiler/lexer/src/toks/math.rs b/compiler/lexer/src/toks/math.rs deleted file mode 100644 index 0621019..0000000 --- a/compiler/lexer/src/toks/math.rs +++ /dev/null @@ -1,10 +0,0 @@ -///! Maths token related utils - -/// The different operators -#[derive(Debug, PartialEq, Clone)] -pub enum MathOperator { - ADD, - SUBSTRACT, - MULTIPLY, - DIVIDE -} \ No newline at end of file diff --git a/compiler/lexer/src/toks/mod.rs b/compiler/lexer/src/toks/mod.rs deleted file mode 100644 index 1854b67..0000000 --- a/compiler/lexer/src/toks/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod math; -pub mod comp; \ No newline at end of file From fde3e0207cba4bf22af6b0cf268707e8e68bf429 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:10:05 +0200 Subject: [PATCH 2/9] feat: added AST side operator parsing --- compiler/ast/src/operators.rs | 68 +++++++++++++++++++++++++++++++++++ compiler/ast/src/tree.rs | 3 +- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs index e88de57..c4e73c9 100644 --- a/compiler/ast/src/operators.rs +++ b/compiler/ast/src/operators.rs @@ -1,5 +1,8 @@ //! Operator related utils +use diagnostics::{DiagnosticResult, builders::make_unexpected_simple_error}; +use lexer::token::{LexerToken, LexerTokenType}; + /// The different math operators #[derive(Debug, PartialEq, Clone)] pub enum MathOperator { @@ -18,4 +21,69 @@ pub enum ComparingOperator { HigherEqual, // A >= B Lower, // A < B LowerEqual // A <= B +} + +pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult<(MathOperator, bool)> { + let op = match tokens[*ind].tok_type { + LexerTokenType::Plus => MathOperator::ADD, + LexerTokenType::Minus => MathOperator::SUBSTRACT, + LexerTokenType::Asterisk => MathOperator::MULTIPLY, + LexerTokenType::Divide => MathOperator::DIVIDE, + + _ => return Err(make_unexpected_simple_error(&tokens[*ind], &tokens[*ind].tok_type).into()) + }; + + *ind += 1; + + let assigns = match tokens[*ind].tok_type { + LexerTokenType::EqualSign => true, + _ => false + }; + + *ind += 1; + + return Ok((op, assigns)) +} + +pub fn parse_compare_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult { + let eq = match tokens[*ind + 1].tok_type { + LexerTokenType::EqualSign => true, + _ => false + }; + + let op = match tokens[*ind].tok_type { + LexerTokenType::EqualSign => { + tokens[*ind + 1].expects(LexerTokenType::EqualSign)?; + + ComparingOperator::Equal + }, + + LexerTokenType::ExclamationMark => { + tokens[*ind + 1].expects(LexerTokenType::EqualSign)?; + + ComparingOperator::NotEqual + }, + + LexerTokenType::AngelBracketOpen => { + if eq { + ComparingOperator::LowerEqual + } else { + ComparingOperator::Lower + } + }, + + LexerTokenType::AngelBracketClose => { + if eq { + ComparingOperator::HigherEqual + } else { + ComparingOperator::Higher + } + }, + + _ => { + return Err(make_unexpected_simple_error(&tokens[*ind], &tokens[*ind].tok_type).into()) + } + }; + + return Ok(op); } \ No newline at end of file diff --git a/compiler/ast/src/tree.rs b/compiler/ast/src/tree.rs index 387d1ab..8d771ad 100644 --- a/compiler/ast/src/tree.rs +++ b/compiler/ast/src/tree.rs @@ -7,9 +7,8 @@ use std::{collections::HashMap, fmt::Display}; use compiler_typing::TypeParameterContainer; use compiler_utils::{Position, hash::{HashedString, SelfHash}}; use diagnostics::{DiagnosticSpanOrigin, diagnostic::{Diagnostic, Span, SpanKind, SpanPosition}}; -use lexer::{toks::{comp::ComparingOperator, math::MathOperator}}; -use crate::types::ASTType; +use crate::{operators::{ComparingOperator, MathOperator}, types::ASTType}; #[derive(Debug, PartialEq, Clone)] pub struct FunctionDeclarationArgument { From 1beab3f15e974c42dd42a0d57e6437d42f7ba6e2 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:21:54 +0200 Subject: [PATCH 3/9] feat: fully migrated operators to AST --- Cargo.lock | 1 - compiler/ast/src/operators.rs | 21 +--------------- compiler/ast/src/tree.rs | 4 +-- compiler/ast_parser/src/comp.rs | 16 ++++++++++++ compiler/ast_parser/src/lib.rs | 1 + compiler/ast_parser/src/math.rs | 4 +-- compiler/ast_parser/src/types.rs | 4 +-- compiler/ast_parser/src/value.rs | 25 ++++++------------- compiler/astoir_hir/src/nodes.rs | 3 +-- compiler/astoir_mir_lowering/Cargo.toml | 1 - compiler/astoir_mir_lowering/src/math.rs | 2 +- .../src/values/booleans.rs | 2 +- compiler/compiler_utils/src/lib.rs | 1 + compiler/compiler_utils/src/operators.rs | 21 ++++++++++++++++ 14 files changed, 57 insertions(+), 49 deletions(-) create mode 100644 compiler/ast_parser/src/comp.rs create mode 100644 compiler/compiler_utils/src/operators.rs diff --git a/Cargo.lock b/Cargo.lock index 5009a10..a5fa4b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,7 +82,6 @@ dependencies = [ "compiler_typing", "compiler_utils", "diagnostics", - "lexer", ] [[package]] diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs index c4e73c9..ff92cf5 100644 --- a/compiler/ast/src/operators.rs +++ b/compiler/ast/src/operators.rs @@ -1,28 +1,9 @@ //! Operator related utils +use compiler_utils::operators::{ComparingOperator, MathOperator}; use diagnostics::{DiagnosticResult, builders::make_unexpected_simple_error}; use lexer::token::{LexerToken, LexerTokenType}; -/// The different math operators -#[derive(Debug, PartialEq, Clone)] -pub enum MathOperator { - ADD, - SUBSTRACT, - MULTIPLY, - DIVIDE -} - -/// The different comparing operators -#[derive(Debug, PartialEq, Clone)] -pub enum ComparingOperator { - Equal, // A == B - NotEqual, // A != B - Higher, // A > B - HigherEqual, // A >= B - Lower, // A < B - LowerEqual // A <= B -} - pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult<(MathOperator, bool)> { let op = match tokens[*ind].tok_type { LexerTokenType::Plus => MathOperator::ADD, diff --git a/compiler/ast/src/tree.rs b/compiler/ast/src/tree.rs index 8d771ad..307a8c0 100644 --- a/compiler/ast/src/tree.rs +++ b/compiler/ast/src/tree.rs @@ -5,10 +5,10 @@ use std::{collections::HashMap, fmt::Display}; use compiler_typing::TypeParameterContainer; -use compiler_utils::{Position, hash::{HashedString, SelfHash}}; +use compiler_utils::{Position, hash::{HashedString, SelfHash}, operators::{ComparingOperator, MathOperator}}; use diagnostics::{DiagnosticSpanOrigin, diagnostic::{Diagnostic, Span, SpanKind, SpanPosition}}; -use crate::{operators::{ComparingOperator, MathOperator}, types::ASTType}; +use crate::types::ASTType; #[derive(Debug, PartialEq, Clone)] pub struct FunctionDeclarationArgument { diff --git a/compiler/ast_parser/src/comp.rs b/compiler/ast_parser/src/comp.rs new file mode 100644 index 0000000..b129c83 --- /dev/null +++ b/compiler/ast_parser/src/comp.rs @@ -0,0 +1,16 @@ +use ast::{operators::parse_compare_operator, tree::{ASTTreeNode, ASTTreeNodeKind}}; +use diagnostics::DiagnosticResult; +use lexer::token::LexerToken; + +use crate::value::parse_ast_value; + +pub fn parse_ast_compare(tokens: &Vec, ind: &mut usize, original: Box) -> DiagnosticResult> { + let operator = parse_compare_operator(tokens, ind)?; + + let right_val = parse_ast_value(tokens, ind)?; + + let start_pos = original.start.clone(); + let end_pos = right_val.end.clone(); + + return Ok(Box::new(ASTTreeNode::new(ASTTreeNodeKind::OperatorBasedConditionMember { lval: original, rval: right_val, operator }, start_pos, end_pos))) +} \ No newline at end of file diff --git a/compiler/ast_parser/src/lib.rs b/compiler/ast_parser/src/lib.rs index 6be0672..b96b63f 100644 --- a/compiler/ast_parser/src/lib.rs +++ b/compiler/ast_parser/src/lib.rs @@ -20,6 +20,7 @@ pub mod types; pub mod arrays; pub mod unwraps; pub mod use_statements; +pub mod comp; pub fn parse_ast_ctx(tokens: &Vec) -> DiagnosticResult { let mut ind = 0; diff --git a/compiler/ast_parser/src/math.rs b/compiler/ast_parser/src/math.rs index fe33f4b..c00a5fa 100644 --- a/compiler/ast_parser/src/math.rs +++ b/compiler/ast_parser/src/math.rs @@ -1,11 +1,11 @@ use diagnostics::{DiagnosticResult, DiagnosticSpanOrigin, diagnostic::Level, errors::MATH_OPERATION_ASSIGNS}; use lexer::token::LexerToken; -use ast::{tree::{ASTTreeNode, ASTTreeNodeKind}}; +use ast::{operators::parse_math_operator, tree::{ASTTreeNode, ASTTreeNodeKind}}; use crate::value::parse_ast_value; pub fn parse_math_operation(tokens: &Vec, ind: &mut usize, original: Box, restricts_to_assigns: bool) -> DiagnosticResult> { - let oper = tokens[*ind].expects_math_operator()?; + let oper = parse_math_operator(tokens, ind)?; if !oper.1 && restricts_to_assigns { return Err(tokens[*ind].make_simple_diagnostic(MATH_OPERATION_ASSIGNS.0, Level::Error, MATH_OPERATION_ASSIGNS.1.to_string(), None, vec![], vec!["consider assigning this to variable".to_string()], vec!["add = at the end of the operator".to_string()]).into()) diff --git a/compiler/ast_parser/src/types.rs b/compiler/ast_parser/src/types.rs index cdea242..7f89348 100644 --- a/compiler/ast_parser/src/types.rs +++ b/compiler/ast_parser/src/types.rs @@ -47,7 +47,7 @@ pub fn parse_type_type_parameters(tokens: &Vec, ind: &mut usize) -> types.push(parsed_type); - if tokens[*ind].is_angel_bracket_close() { + if tokens[*ind].tok_type == LexerTokenType::AngelBracketClose { break; } @@ -206,7 +206,7 @@ pub fn parse_type_parameters_declaration(tokens: &Vec, ind: &mut usi *ind += 1; - if tokens[*ind].is_angel_bracket_close() { + if tokens[*ind].tok_type == LexerTokenType::AngelBracketClose { break; } diff --git a/compiler/ast_parser/src/value.rs b/compiler/ast_parser/src/value.rs index 42beefd..bef950b 100644 --- a/compiler/ast_parser/src/value.rs +++ b/compiler/ast_parser/src/value.rs @@ -1,10 +1,10 @@ use compiler_utils::{Position, hash::HashedString}; -use ast::{make_node, tree::{ASTTreeNode, ASTTreeNodeKind}}; +use ast::{make_node, operators::parse_compare_operator, tree::{ASTTreeNode, ASTTreeNodeKind}}; use diagnostics::{DiagnosticResult, builders::{make_expected_simple_error, make_unexpected_simple_error}}; use lexer::token::{LexerToken, LexerTokenType}; -use crate::{arrays::parse_array_access, functions::parse_function_call, structs::val::parse_struct_initialize, unwraps::{parse_unwrap_condition, parse_unwrap_value}}; +use crate::{arrays::parse_array_access, comp::parse_ast_compare, functions::parse_function_call, structs::val::parse_struct_initialize, unwraps::{parse_unwrap_condition, parse_unwrap_value}}; use crate::literals::{parse_integer_literal, parse_string_literal}; use crate::math::parse_math_operation; @@ -78,7 +78,7 @@ pub fn parse_ast_value_dotacess_chain_member(tokens: &Vec, ind: &mut /// pub fn parse_ast_value_post_l(tokens: &Vec, ind: &mut usize, original: DiagnosticResult>, invoked_on_body: bool) -> DiagnosticResult> { match &tokens[*ind].tok_type { - LexerTokenType::MathOperator(_, _) => { + LexerTokenType::Plus | LexerTokenType::Minus | LexerTokenType::Asterisk | LexerTokenType::Divide => { let o = &original?; let k = Box::new(ASTTreeNode::clone(o.as_ref())); @@ -92,6 +92,10 @@ pub fn parse_ast_value_post_l(tokens: &Vec, ind: &mut usize, origina }, LexerTokenType::EqualSign => { + if tokens[*ind + 1].tok_type == LexerTokenType::EqualSign { + return parse_ast_compare(tokens, ind, original.clone()?); + } + *ind += 1; if let Ok(v) = original.as_ref() { @@ -118,20 +122,7 @@ pub fn parse_ast_value_post_l(tokens: &Vec, ind: &mut usize, origina return Ok(Box::new(ASTTreeNode::new(kind, start, end))); }, - LexerTokenType::ComparingOperator(op) => { - let operator = op.clone(); - - let o = &original?; - let k = Box::new(ASTTreeNode::clone(o.as_ref())); - - *ind += 1; - let right_val = parse_ast_value(tokens, ind)?; - - let start_pos = k.start.clone(); - let end_pos = right_val.end.clone(); - - return Ok(Box::new(ASTTreeNode::new(ASTTreeNodeKind::OperatorBasedConditionMember { lval: k, rval: right_val, operator }, start_pos, end_pos))); - }, + LexerTokenType::ExclamationMark | LexerTokenType::AngelBracketOpen | LexerTokenType::AngelBracketClose => return parse_ast_compare(tokens, ind, original.clone()?), _ => return original } diff --git a/compiler/astoir_hir/src/nodes.rs b/compiler/astoir_hir/src/nodes.rs index 3e366e1..9544a52 100644 --- a/compiler/astoir_hir/src/nodes.rs +++ b/compiler/astoir_hir/src/nodes.rs @@ -3,9 +3,8 @@ use std::collections::HashMap; use compiler_typing::{enums::{RawEnumTypeContainer}, raw::RawType, references::TypeReference, structs::RawStructTypeContainer, transmutation::array::can_transmute_inner, tree::Type}; -use compiler_utils::{Position, hash::SelfHash}; +use compiler_utils::{Position, hash::SelfHash, operators::{ComparingOperator, MathOperator}}; use diagnostics::{DiagnosticSpanOrigin, builders::{make_diff_type, make_diff_type_val}, diagnostic::{Diagnostic, Span, SpanKind, SpanPosition}, unsure_panic}; -use lexer::toks::{comp::ComparingOperator, math::MathOperator}; use crate::{ctx::{HIRBranchedContext, HIRContext}, resolve::resolve_to_type, structs::{HIRIfBranch, StructLRUStep}}; diff --git a/compiler/astoir_mir_lowering/Cargo.toml b/compiler/astoir_mir_lowering/Cargo.toml index 0fd841b..82661b5 100644 --- a/compiler/astoir_mir_lowering/Cargo.toml +++ b/compiler/astoir_mir_lowering/Cargo.toml @@ -7,6 +7,5 @@ edition = "2024" astoir_mir = {path = "../astoir_mir"} astoir_hir = {path = "../astoir_hir"} diagnostics = { path = "../diagnostics" } -lexer = {path = "../lexer"} compiler_typing = { path = "../compiler_typing" } compiler_utils = { path = "../compiler_utils" } \ No newline at end of file diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index 4f68fc5..3c78662 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -1,8 +1,8 @@ use astoir_hir::nodes::{HIRNode, HIRNodeKind}; use astoir_mir::{blocks::{refer::MIRBlockReference}, builder::{build_float_add, build_float_div, build_float_mul, build_float_sub, build_int_add, build_int_div, build_int_mul, build_int_sub}, vals::base::BaseMIRValue}; use compiler_typing::raw::RawType; +use compiler_utils::operators::MathOperator; use diagnostics::{DiagnosticResult, builders::make_math_operation_req_assign, unsure_panic}; -use lexer::toks::math::MathOperator; use crate::{MIRLoweringContext, values::lower_hir_value, vars::lower_hir_variable_reference}; diff --git a/compiler/astoir_mir_lowering/src/values/booleans.rs b/compiler/astoir_mir_lowering/src/values/booleans.rs index 54e81a9..4898435 100644 --- a/compiler/astoir_mir_lowering/src/values/booleans.rs +++ b/compiler/astoir_mir_lowering/src/values/booleans.rs @@ -1,7 +1,7 @@ use astoir_hir::nodes::{HIRNode, HIRNodeKind}; use astoir_mir::{blocks::{refer::MIRBlockReference}, builder::{build_bitwise_not, build_comp_eq, build_comp_ge, build_comp_gt, build_comp_le, build_comp_lt, build_comp_neg}, vals::int::MIRIntValue}; +use compiler_utils::operators::ComparingOperator; use diagnostics::DiagnosticResult; -use lexer::toks::comp::ComparingOperator; use crate::{MIRLoweringContext, values::lower_hir_value}; diff --git a/compiler/compiler_utils/src/lib.rs b/compiler/compiler_utils/src/lib.rs index 2cf4462..976aa53 100644 --- a/compiler/compiler_utils/src/lib.rs +++ b/compiler/compiler_utils/src/lib.rs @@ -3,6 +3,7 @@ use std::{fs, io::Error}; pub mod utils; pub mod hash; +pub mod operators; #[derive(Debug, Clone, PartialEq)] pub struct Position { diff --git a/compiler/compiler_utils/src/operators.rs b/compiler/compiler_utils/src/operators.rs new file mode 100644 index 0000000..31c7156 --- /dev/null +++ b/compiler/compiler_utils/src/operators.rs @@ -0,0 +1,21 @@ +//! Operator utilities + +/// The different math operators +#[derive(Debug, PartialEq, Clone)] +pub enum MathOperator { + ADD, + SUBSTRACT, + MULTIPLY, + DIVIDE +} + +/// The different comparing operators +#[derive(Debug, PartialEq, Clone)] +pub enum ComparingOperator { + Equal, // A == B + NotEqual, // A != B + Higher, // A > B + HigherEqual, // A >= B + Lower, // A < B + LowerEqual // A <= B +} From 2561e9c7302008500434f15e549aca846a5eac83 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:28:57 +0200 Subject: [PATCH 4/9] feat: added new MathOperator struct instead of two seperate fields --- compiler/ast/src/operators.rs | 14 +++++----- compiler/ast/src/tree.rs | 2 +- compiler/ast_parser/src/math.rs | 4 +-- compiler/ast_parser/src/value.rs | 2 +- compiler/astoir_hir/src/nodes.rs | 4 +-- compiler/astoir_hir_lowering/src/math.rs | 6 ++--- compiler/astoir_mir_lowering/src/body.rs | 4 +-- compiler/astoir_mir_lowering/src/math.rs | 34 ++++++++++++------------ compiler/compiler_utils/src/operators.rs | 20 +++++++++----- 9 files changed, 49 insertions(+), 41 deletions(-) diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs index ff92cf5..542cef2 100644 --- a/compiler/ast/src/operators.rs +++ b/compiler/ast/src/operators.rs @@ -1,15 +1,15 @@ //! Operator related utils -use compiler_utils::operators::{ComparingOperator, MathOperator}; +use compiler_utils::operators::{ComparingOperator, MathOperator, MathOperatorType}; use diagnostics::{DiagnosticResult, builders::make_unexpected_simple_error}; use lexer::token::{LexerToken, LexerTokenType}; -pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult<(MathOperator, bool)> { +pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult { let op = match tokens[*ind].tok_type { - LexerTokenType::Plus => MathOperator::ADD, - LexerTokenType::Minus => MathOperator::SUBSTRACT, - LexerTokenType::Asterisk => MathOperator::MULTIPLY, - LexerTokenType::Divide => MathOperator::DIVIDE, + LexerTokenType::Plus => MathOperatorType::Add, + LexerTokenType::Minus => MathOperatorType::Subtract, + LexerTokenType::Asterisk => MathOperatorType::Multiply, + LexerTokenType::Divide => MathOperatorType::Divide, _ => return Err(make_unexpected_simple_error(&tokens[*ind], &tokens[*ind].tok_type).into()) }; @@ -23,7 +23,7 @@ pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> Diagnos *ind += 1; - return Ok((op, assigns)) + return Ok(MathOperator { operator: op, assigns, fast: false }); } pub fn parse_compare_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult { diff --git a/compiler/ast/src/tree.rs b/compiler/ast/src/tree.rs index 307a8c0..09f0c7a 100644 --- a/compiler/ast/src/tree.rs +++ b/compiler/ast/src/tree.rs @@ -38,7 +38,7 @@ pub enum ASTTreeNodeKind { OperatorBasedConditionMember { lval: Box, rval: Box, operator: ComparingOperator }, BooleanBasedConditionMember { val: Box, negate: bool }, - MathResult { lval: Box, rval: Box, operator: MathOperator, assigns: bool }, + MathResult { lval: Box, rval: Box, operator: MathOperator }, VariableReference(HashedString), diff --git a/compiler/ast_parser/src/math.rs b/compiler/ast_parser/src/math.rs index c00a5fa..bb7469d 100644 --- a/compiler/ast_parser/src/math.rs +++ b/compiler/ast_parser/src/math.rs @@ -7,7 +7,7 @@ use crate::value::parse_ast_value; pub fn parse_math_operation(tokens: &Vec, ind: &mut usize, original: Box, restricts_to_assigns: bool) -> DiagnosticResult> { let oper = parse_math_operator(tokens, ind)?; - if !oper.1 && restricts_to_assigns { + if !oper.assigns && restricts_to_assigns { return Err(tokens[*ind].make_simple_diagnostic(MATH_OPERATION_ASSIGNS.0, Level::Error, MATH_OPERATION_ASSIGNS.1.to_string(), None, vec![], vec!["consider assigning this to variable".to_string()], vec!["add = at the end of the operator".to_string()]).into()) } @@ -18,5 +18,5 @@ pub fn parse_math_operation(tokens: &Vec, ind: &mut usize, original: let start = original.start.clone(); let end = right_member.end.clone(); - return Ok(Box::new(ASTTreeNode::new(ASTTreeNodeKind::MathResult { lval: original, rval: right_member, operator: oper.0, assigns: oper.1 }, start, end))) + return Ok(Box::new(ASTTreeNode::new(ASTTreeNodeKind::MathResult { lval: original, rval: right_member, operator: oper }, start, end))) } \ No newline at end of file diff --git a/compiler/ast_parser/src/value.rs b/compiler/ast_parser/src/value.rs index bef950b..f176559 100644 --- a/compiler/ast_parser/src/value.rs +++ b/compiler/ast_parser/src/value.rs @@ -1,6 +1,6 @@ use compiler_utils::{Position, hash::HashedString}; -use ast::{make_node, operators::parse_compare_operator, tree::{ASTTreeNode, ASTTreeNodeKind}}; +use ast::{make_node, tree::{ASTTreeNode, ASTTreeNodeKind}}; use diagnostics::{DiagnosticResult, builders::{make_expected_simple_error, make_unexpected_simple_error}}; use lexer::token::{LexerToken, LexerTokenType}; diff --git a/compiler/astoir_hir/src/nodes.rs b/compiler/astoir_hir/src/nodes.rs index 9544a52..9de521c 100644 --- a/compiler/astoir_hir/src/nodes.rs +++ b/compiler/astoir_hir/src/nodes.rs @@ -50,7 +50,7 @@ pub enum HIRNodeKind { VarAssigment { variable: usize, val: Box }, - MathOperation { left: Box, right: Box, operation: MathOperator, assignment: bool }, + MathOperation { left: Box, right: Box, operation: MathOperator }, UnwrapCondition { original: Box, new_type: Type, new_var: Option, unsafe_unwrap: bool }, UnwrapValue { original: Box, new_type: Type, unsafe_unwrap: bool }, @@ -247,7 +247,7 @@ impl HIRNode { return Some(last.clone()) }, - HIRNodeKind::MathOperation { left, right: _, operation: _, assignment: _ } => { + HIRNodeKind::MathOperation { left, right: _, operation: _ } => { return left.get_node_type(context, curr_ctx) }, diff --git a/compiler/astoir_hir_lowering/src/math.rs b/compiler/astoir_hir_lowering/src/math.rs index 0280b4d..8a8a4b5 100644 --- a/compiler/astoir_hir_lowering/src/math.rs +++ b/compiler/astoir_hir_lowering/src/math.rs @@ -5,8 +5,8 @@ use diagnostics::{DiagnosticResult, DiagnosticSpanOrigin, diagnostic::Level, err use crate::values::lower_ast_value; pub fn lower_ast_math_operation(context: &mut HIRContext, curr_ctx: &mut HIRBranchedContext, node: Box, enforce_assign: bool) -> DiagnosticResult> { - if let ASTTreeNodeKind::MathResult { lval, rval, operator, assigns } = node.kind.clone() { - if enforce_assign && !assigns { + if let ASTTreeNodeKind::MathResult { lval, rval, operator } = node.kind.clone() { + if enforce_assign && !operator.assigns { return Err(node.make_simple_diagnostic(MATH_OPERATION_ASSIGNS.0, Level::Error, MATH_OPERATION_ASSIGNS.1.to_string(), None, vec![], vec!["consider assigning this to variable".to_string()], vec!["add = at the end of the operator".to_string()]).into()) } @@ -14,7 +14,7 @@ pub fn lower_ast_math_operation(context: &mut HIRContext, curr_ctx: &mut HIRBran let right = Box::new(lower_ast_value(context, curr_ctx, rval)?.use_as(context, curr_ctx, left.get_node_type(context, curr_ctx).unwrap(), &*node, None)?); - return Ok(Box::new(HIRNode::new(HIRNodeKind::MathOperation { left, right, operation: operator, assignment: assigns }, &node.start, &node.end))) + return Ok(Box::new(HIRNode::new(HIRNodeKind::MathOperation { left, right, operation: operator }, &node.start, &node.end))) } panic!("Invalid node type") diff --git a/compiler/astoir_mir_lowering/src/body.rs b/compiler/astoir_mir_lowering/src/body.rs index d43af45..96b93d3 100644 --- a/compiler/astoir_mir_lowering/src/body.rs +++ b/compiler/astoir_mir_lowering/src/body.rs @@ -15,8 +15,8 @@ pub fn lower_hir_body_member(block: MIRBlockReference, node: Box, ctx: return match node.kind.clone() { HIRNodeKind::VarAssigment { .. } => lower_hir_variable_assignment(block, node, ctx), HIRNodeKind::VarDeclaration { .. } => lower_hir_variable_declaration(block, node, ctx), - HIRNodeKind::MathOperation { left: _, right: _, operation: _, assignment } => { - if !assignment { + HIRNodeKind::MathOperation { left: _, right: _, operation } => { + if !operation.assigns { return Err(make_math_operation_req_assign(&*node).into()) } diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index 3c78662..b942504 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -1,20 +1,20 @@ use astoir_hir::nodes::{HIRNode, HIRNodeKind}; use astoir_mir::{blocks::{refer::MIRBlockReference}, builder::{build_float_add, build_float_div, build_float_mul, build_float_sub, build_int_add, build_int_div, build_int_mul, build_int_sub}, vals::base::BaseMIRValue}; use compiler_typing::raw::RawType; -use compiler_utils::operators::MathOperator; +use compiler_utils::operators::{MathOperator, MathOperatorType}; use diagnostics::{DiagnosticResult, builders::make_math_operation_req_assign, unsure_panic}; use crate::{MIRLoweringContext, values::lower_hir_value, vars::lower_hir_variable_reference}; pub fn lower_hir_math_operation(block: MIRBlockReference, node: Box, ctx: &mut MIRLoweringContext) -> DiagnosticResult { - if let HIRNodeKind::MathOperation { left, right, operation, assignment } = node.clone().kind { - if assignment && !left.is_variable_reference() { + if let HIRNodeKind::MathOperation { left, right, operation } = node.clone().kind { + if operation.assigns && !left.is_variable_reference() { return Err(make_math_operation_req_assign(&*node).into()) } let ptr; - if assignment { + if operation.assigns { ptr = Some(lower_hir_variable_reference(block, &left, ctx)?); } else { ptr = None @@ -25,13 +25,13 @@ pub fn lower_hir_math_operation(block: MIRBlockReference, node: Box, ct let val = match left_val.vtype.get_generic(&ctx.hir_ctx.type_storage) { - RawType::Integer(_, _) | RawType::FixedPoint(_, _, _) => lower_hir_math_operation_int(left_val, right_val, operation, ctx)?, - RawType::Floating(_, _) => lower_hir_math_operation_float(left_val, right_val, operation, ctx)?, + RawType::Integer(_, _) | RawType::FixedPoint(_, _, _) => lower_hir_math_operation_int(left_val, right_val, operation.clone(), ctx)?, + RawType::Floating(_, _) => lower_hir_math_operation_float(left_val, right_val, operation.clone(), ctx)?, _ => unsure_panic!("Cannot use lower_hir_math_operator on this given value kind!") }; - if assignment { + if operation.assigns { let v = ptr.unwrap(); v.write(block, &mut ctx.mir_ctx, val.clone(), &ctx.hir_ctx.type_storage)?; @@ -49,11 +49,11 @@ pub fn lower_hir_math_operation_int(left: BaseMIRValue, right: BaseMIRValue, ope let signed = left.signed; - let res = match operator { - MathOperator::ADD => build_int_add(&mut ctx.mir_ctx, left, right, signed)?, - MathOperator::SUBSTRACT => build_int_sub(&mut ctx.mir_ctx, left, right, signed)?, - MathOperator::MULTIPLY => build_int_mul(&mut ctx.mir_ctx, left, right, signed)?, - MathOperator::DIVIDE => build_int_div(&mut ctx.mir_ctx, left, right, signed)? + let res = match operator.operator { + MathOperatorType::Add => build_int_add(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Subtract => build_int_sub(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Multiply => build_int_mul(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Divide => build_int_div(&mut ctx.mir_ctx, left, right, signed)? }; return Ok(res.into()); @@ -65,11 +65,11 @@ pub fn lower_hir_math_operation_float(left: BaseMIRValue, right: BaseMIRValue, o let signed = left.signed; - let res = match operator { - MathOperator::ADD => build_float_add(&mut ctx.mir_ctx, left, right, signed)?, - MathOperator::SUBSTRACT => build_float_sub(&mut ctx.mir_ctx, left, right, signed)?, - MathOperator::MULTIPLY => build_float_mul(&mut ctx.mir_ctx, left, right, signed)?, - MathOperator::DIVIDE => build_float_div(&mut ctx.mir_ctx, left, right, signed)? + let res = match operator.operator { + MathOperatorType::Add => build_float_add(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Subtract => build_float_sub(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Multiply => build_float_mul(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::Divide => build_float_div(&mut ctx.mir_ctx, left, right, signed)? }; return Ok(res.into()); diff --git a/compiler/compiler_utils/src/operators.rs b/compiler/compiler_utils/src/operators.rs index 31c7156..dc80dee 100644 --- a/compiler/compiler_utils/src/operators.rs +++ b/compiler/compiler_utils/src/operators.rs @@ -1,12 +1,20 @@ //! Operator utilities -/// The different math operators +/// The different math operator types #[derive(Debug, PartialEq, Clone)] -pub enum MathOperator { - ADD, - SUBSTRACT, - MULTIPLY, - DIVIDE +pub enum MathOperatorType { + Add, + Subtract, + Multiply, + Divide +} + +/// Represents an actual math operator +#[derive(Debug, PartialEq, Clone)] +pub struct MathOperator { + pub operator: MathOperatorType, + pub assigns: bool, + pub fast: bool } /// The different comparing operators From 562b66f6d8ca4b504c39f4856a9f62ac32a1b11c Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:31:15 +0200 Subject: [PATCH 5/9] feat: added tidle token --- compiler/lexer/src/lexer.rs | 1 + compiler/lexer/src/token.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/lexer/src/lexer.rs b/compiler/lexer/src/lexer.rs index cea6193..38f5fed 100644 --- a/compiler/lexer/src/lexer.rs +++ b/compiler/lexer/src/lexer.rs @@ -122,6 +122,7 @@ pub fn lexer_parse_file(file_path: &String) -> DiagnosticResult> '+' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Plus)), '-' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Minus)), '/' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Divide)), + '~' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Tidle)), _ => continue } diff --git a/compiler/lexer/src/token.rs b/compiler/lexer/src/token.rs index 6a0f2fc..11162c0 100644 --- a/compiler/lexer/src/token.rs +++ b/compiler/lexer/src/token.rs @@ -59,6 +59,7 @@ pub enum LexerTokenType { Plus, Minus, Divide, + Tidle, BracketOpen, BracketClose, @@ -196,7 +197,8 @@ impl Display for LexerTokenType { Self::UnwrapUnsafe => "unsafe_unwrap", Self::Plus => "+", Self::Minus => "-", - Self::Divide => "/" + Self::Divide => "/", + Self::Tidle => "~" }; write!(f, "{}", s)?; From 14963c83a625549656d0dfc1c72a739e071d2b37 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:32:03 +0200 Subject: [PATCH 6/9] feat: added fast parsing --- compiler/ast/src/operators.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs index 542cef2..89565fa 100644 --- a/compiler/ast/src/operators.rs +++ b/compiler/ast/src/operators.rs @@ -23,7 +23,14 @@ pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> Diagnos *ind += 1; - return Ok(MathOperator { operator: op, assigns, fast: false }); + let fast = match tokens[*ind].tok_type { + LexerTokenType::Tidle => true, + _ => false + }; + + *ind += 1; + + return Ok(MathOperator { operator: op, assigns, fast }); } pub fn parse_compare_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult { From b46a36cf3b14e0d5ef73133b5e3a59feb4e45d1a Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:36:45 +0200 Subject: [PATCH 7/9] feat: added shifting operators parsing --- compiler/ast/src/operators.rs | 20 ++++++++++++++++++-- compiler/astoir_mir_lowering/src/math.rs | 2 +- compiler/compiler_utils/src/operators.rs | 4 +++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs index 89565fa..c1df7e6 100644 --- a/compiler/ast/src/operators.rs +++ b/compiler/ast/src/operators.rs @@ -8,8 +8,24 @@ pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> Diagnos let op = match tokens[*ind].tok_type { LexerTokenType::Plus => MathOperatorType::Add, LexerTokenType::Minus => MathOperatorType::Subtract, - LexerTokenType::Asterisk => MathOperatorType::Multiply, - LexerTokenType::Divide => MathOperatorType::Divide, + LexerTokenType::Asterisk => { + if tokens[*ind + 1].tok_type == LexerTokenType::Asterisk { + *ind += 1; + + MathOperatorType::ShiftLeft + } else { + MathOperatorType::Multiply + } + } + LexerTokenType::Divide => { + if tokens[*ind + 1].tok_type == LexerTokenType::Divide { + *ind += 1; + + MathOperatorType::ShiftRight + } else { + MathOperatorType::Divide + } + } _ => return Err(make_unexpected_simple_error(&tokens[*ind], &tokens[*ind].tok_type).into()) }; diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index b942504..24609a4 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -53,7 +53,7 @@ pub fn lower_hir_math_operation_int(left: BaseMIRValue, right: BaseMIRValue, ope MathOperatorType::Add => build_int_add(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Subtract => build_int_sub(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Multiply => build_int_mul(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Divide => build_int_div(&mut ctx.mir_ctx, left, right, signed)? + MathOperatorType::Divide => build_int_div(&mut ctx.mir_ctx, left, right, signed)?, }; return Ok(res.into()); diff --git a/compiler/compiler_utils/src/operators.rs b/compiler/compiler_utils/src/operators.rs index dc80dee..d6d8adf 100644 --- a/compiler/compiler_utils/src/operators.rs +++ b/compiler/compiler_utils/src/operators.rs @@ -6,7 +6,9 @@ pub enum MathOperatorType { Add, Subtract, Multiply, - Divide + Divide, + ShiftLeft, + ShiftRight } /// Represents an actual math operator From 4cf4391958f724b57343b95e5412ae6e9b6458d9 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:40:49 +0200 Subject: [PATCH 8/9] feat: added MIR bridge support --- compiler/astoir_mir/src/builder.rs | 12 ++++++++++++ compiler/astoir_mir_lowering/src/math.rs | 14 +++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/compiler/astoir_mir/src/builder.rs b/compiler/astoir_mir/src/builder.rs index 188073f..2b8322b 100644 --- a/compiler/astoir_mir/src/builder.rs +++ b/compiler/astoir_mir/src/builder.rs @@ -121,6 +121,18 @@ pub fn build_int_div(ctx: &mut MIRContext, left: MIRIntValue, right: MIRIntValue return res.as_int(); } +pub fn build_int_shift_left(ctx: &mut MIRContext, left: MIRIntValue, shift: MIRIntValue) -> DiagnosticResult { + let res = ctx.append_inst(MIRInstruction::ShiftLeft { a: left, shift }).get()?; + + return res.as_int(); +} + +pub fn build_int_shift_right(ctx: &mut MIRContext, left: MIRIntValue, shift: MIRIntValue) -> DiagnosticResult { + let res = ctx.append_inst(MIRInstruction::ShiftRight { a: left, shift }).get()?; + + return res.as_int(); +} + pub fn build_int_neg(ctx: &mut MIRContext, val: MIRIntValue) -> DiagnosticResult { let res = ctx.append_inst(MIRInstruction::IntegerNeg { val }).get()?; diff --git a/compiler/astoir_mir_lowering/src/math.rs b/compiler/astoir_mir_lowering/src/math.rs index 24609a4..181e9cd 100644 --- a/compiler/astoir_mir_lowering/src/math.rs +++ b/compiler/astoir_mir_lowering/src/math.rs @@ -1,8 +1,8 @@ use astoir_hir::nodes::{HIRNode, HIRNodeKind}; -use astoir_mir::{blocks::{refer::MIRBlockReference}, builder::{build_float_add, build_float_div, build_float_mul, build_float_sub, build_int_add, build_int_div, build_int_mul, build_int_sub}, vals::base::BaseMIRValue}; +use astoir_mir::{blocks::refer::MIRBlockReference, builder::{build_float_add, build_float_div, build_float_mul, build_float_sub, build_int_add, build_int_div, build_int_mul, build_int_sub, build_shift_left, build_shift_right}, vals::base::BaseMIRValue}; use compiler_typing::raw::RawType; use compiler_utils::operators::{MathOperator, MathOperatorType}; -use diagnostics::{DiagnosticResult, builders::make_math_operation_req_assign, unsure_panic}; +use diagnostics::{DiagnosticResult, builders::{make_math_operation_req_assign, make_req_type_kind}, unsure_panic}; use crate::{MIRLoweringContext, values::lower_hir_value, vars::lower_hir_variable_reference}; @@ -26,7 +26,7 @@ pub fn lower_hir_math_operation(block: MIRBlockReference, node: Box, ct let val = match left_val.vtype.get_generic(&ctx.hir_ctx.type_storage) { RawType::Integer(_, _) | RawType::FixedPoint(_, _, _) => lower_hir_math_operation_int(left_val, right_val, operation.clone(), ctx)?, - RawType::Floating(_, _) => lower_hir_math_operation_float(left_val, right_val, operation.clone(), ctx)?, + RawType::Floating(_, _) => lower_hir_math_operation_float(left_val, right_val, operation.clone(), ctx, &*node)?, _ => unsure_panic!("Cannot use lower_hir_math_operator on this given value kind!") }; @@ -54,12 +54,14 @@ pub fn lower_hir_math_operation_int(left: BaseMIRValue, right: BaseMIRValue, ope MathOperatorType::Subtract => build_int_sub(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Multiply => build_int_mul(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Divide => build_int_div(&mut ctx.mir_ctx, left, right, signed)?, + MathOperatorType::ShiftLeft => build_shift_left(&mut ctx.mir_ctx, left, right)?, + MathOperatorType::ShiftRight => build_shift_right(&mut ctx.mir_ctx, left, right)? }; return Ok(res.into()); } -pub fn lower_hir_math_operation_float(left: BaseMIRValue, right: BaseMIRValue, operator: MathOperator, ctx: &mut MIRLoweringContext) -> DiagnosticResult { +pub fn lower_hir_math_operation_float(left: BaseMIRValue, right: BaseMIRValue, operator: MathOperator, ctx: &mut MIRLoweringContext, node: &HIRNode) -> DiagnosticResult { let left = left.as_float()?; let right = right.as_float()?; @@ -69,7 +71,9 @@ pub fn lower_hir_math_operation_float(left: BaseMIRValue, right: BaseMIRValue, o MathOperatorType::Add => build_float_add(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Subtract => build_float_sub(&mut ctx.mir_ctx, left, right, signed)?, MathOperatorType::Multiply => build_float_mul(&mut ctx.mir_ctx, left, right, signed)?, - MathOperatorType::Divide => build_float_div(&mut ctx.mir_ctx, left, right, signed)? + MathOperatorType::Divide => build_float_div(&mut ctx.mir_ctx, left, right, signed)?, + + _ => return Err(make_req_type_kind(node, &"integer".to_string()).into()) }; return Ok(res.into()); From a9223e7b531c68a31b3ee3bf0cf3ec2f30df5aa3 Mon Sep 17 00:00:00 2001 From: Zffu <103074097+Zffu@users.noreply.github.com> Date: Tue, 14 Apr 2026 01:43:17 +0200 Subject: [PATCH 9/9] feat: added modulo operator --- compiler/ast/src/operators.rs | 1 + compiler/compiler_utils/src/operators.rs | 3 ++- compiler/lexer/src/lexer.rs | 1 + compiler/lexer/src/token.rs | 4 +++- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/ast/src/operators.rs b/compiler/ast/src/operators.rs index c1df7e6..3a33dfc 100644 --- a/compiler/ast/src/operators.rs +++ b/compiler/ast/src/operators.rs @@ -7,6 +7,7 @@ use lexer::token::{LexerToken, LexerTokenType}; pub fn parse_math_operator(tokens: &Vec, ind: &mut usize) -> DiagnosticResult { let op = match tokens[*ind].tok_type { LexerTokenType::Plus => MathOperatorType::Add, + LexerTokenType::PercentSign => MathOperatorType::Modulo, LexerTokenType::Minus => MathOperatorType::Subtract, LexerTokenType::Asterisk => { if tokens[*ind + 1].tok_type == LexerTokenType::Asterisk { diff --git a/compiler/compiler_utils/src/operators.rs b/compiler/compiler_utils/src/operators.rs index d6d8adf..4a3a4a3 100644 --- a/compiler/compiler_utils/src/operators.rs +++ b/compiler/compiler_utils/src/operators.rs @@ -8,7 +8,8 @@ pub enum MathOperatorType { Multiply, Divide, ShiftLeft, - ShiftRight + ShiftRight, + Modulo } /// Represents an actual math operator diff --git a/compiler/lexer/src/lexer.rs b/compiler/lexer/src/lexer.rs index 38f5fed..e724251 100644 --- a/compiler/lexer/src/lexer.rs +++ b/compiler/lexer/src/lexer.rs @@ -123,6 +123,7 @@ pub fn lexer_parse_file(file_path: &String) -> DiagnosticResult> '-' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Minus)), '/' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Divide)), '~' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Tidle)), + '%' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::PercentSign)), _ => continue } diff --git a/compiler/lexer/src/token.rs b/compiler/lexer/src/token.rs index 11162c0..6574fd3 100644 --- a/compiler/lexer/src/token.rs +++ b/compiler/lexer/src/token.rs @@ -60,6 +60,7 @@ pub enum LexerTokenType { Minus, Divide, Tidle, + PercentSign, BracketOpen, BracketClose, @@ -198,7 +199,8 @@ impl Display for LexerTokenType { Self::Plus => "+", Self::Minus => "-", Self::Divide => "/", - Self::Tidle => "~" + Self::Tidle => "~", + Self::PercentSign => "%" }; write!(f, "{}", s)?;