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/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..3a33dfc --- /dev/null +++ b/compiler/ast/src/operators.rs @@ -0,0 +1,94 @@ +//! Operator related utils + +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 { + 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 { + *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()) + }; + + *ind += 1; + + let assigns = match tokens[*ind].tok_type { + LexerTokenType::EqualSign => true, + _ => false + }; + + *ind += 1; + + 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 { + 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..09f0c7a 100644 --- a/compiler/ast/src/tree.rs +++ b/compiler/ast/src/tree.rs @@ -5,9 +5,8 @@ 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 lexer::{toks::{comp::ComparingOperator, math::MathOperator}}; use crate::types::ASTType; @@ -39,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/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..bb7469d 100644 --- a/compiler/ast_parser/src/math.rs +++ b/compiler/ast_parser/src/math.rs @@ -1,13 +1,13 @@ 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 { + 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/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..f176559 100644 --- a/compiler/ast_parser/src/value.rs +++ b/compiler/ast_parser/src/value.rs @@ -4,7 +4,7 @@ use ast::{make_node, 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..9de521c 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}}; @@ -51,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 }, @@ -248,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/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/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/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 4f68fc5..181e9cd 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 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 diagnostics::{DiagnosticResult, builders::make_math_operation_req_assign, unsure_panic}; -use lexer::toks::math::MathOperator; +use compiler_utils::operators::{MathOperator, MathOperatorType}; +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}; 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, &*node)?, _ => 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,27 +49,31 @@ 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)?, + 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()?; 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 Err(make_req_type_kind(node, &"integer".to_string()).into()) }; return Ok(res.into()); 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..4a3a4a3 --- /dev/null +++ b/compiler/compiler_utils/src/operators.rs @@ -0,0 +1,32 @@ +//! Operator utilities + +/// The different math operator types +#[derive(Debug, PartialEq, Clone)] +pub enum MathOperatorType { + Add, + Subtract, + Multiply, + Divide, + ShiftLeft, + ShiftRight, + Modulo +} + +/// 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 +#[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 +} diff --git a/compiler/lexer/src/lexer.rs b/compiler/lexer/src/lexer.rs index 8c6d965..e724251 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,11 @@ 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)), + '~' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::Tidle)), + '%' => tokens.push(LexerToken::make_single_sized(pos, LexerTokenType::PercentSign)), _ => continue } @@ -194,91 +178,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..6574fd3 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,12 @@ pub enum LexerTokenType { Ampersand, Collon, + Plus, + Minus, + Divide, + Tidle, + PercentSign, + BracketOpen, BracketClose, @@ -113,21 +110,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 +117,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 +167,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 +181,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 +195,12 @@ 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 => "/", + Self::Tidle => "~", + Self::PercentSign => "%" }; 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