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
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions compiler/ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
pub mod tree;
pub mod ctx;
pub mod types;
pub mod operators;
94 changes: 94 additions & 0 deletions compiler/ast/src/operators.rs
Original file line number Diff line number Diff line change
@@ -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<LexerToken>, ind: &mut usize) -> DiagnosticResult<MathOperator> {
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<LexerToken>, ind: &mut usize) -> DiagnosticResult<ComparingOperator> {
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);
}
5 changes: 2 additions & 3 deletions compiler/ast/src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -39,7 +38,7 @@ pub enum ASTTreeNodeKind {
OperatorBasedConditionMember { lval: Box<ASTTreeNode>, rval: Box<ASTTreeNode>, operator: ComparingOperator },
BooleanBasedConditionMember { val: Box<ASTTreeNode>, negate: bool },

MathResult { lval: Box<ASTTreeNode>, rval: Box<ASTTreeNode>, operator: MathOperator, assigns: bool },
MathResult { lval: Box<ASTTreeNode>, rval: Box<ASTTreeNode>, operator: MathOperator },

VariableReference(HashedString),

Expand Down
16 changes: 16 additions & 0 deletions compiler/ast_parser/src/comp.rs
Original file line number Diff line number Diff line change
@@ -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<LexerToken>, ind: &mut usize, original: Box<ASTTreeNode>) -> DiagnosticResult<Box<ASTTreeNode>> {
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)))
}
1 change: 1 addition & 0 deletions compiler/ast_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<LexerToken>) -> DiagnosticResult<ParserCtx> {
let mut ind = 0;
Expand Down
8 changes: 4 additions & 4 deletions compiler/ast_parser/src/math.rs
Original file line number Diff line number Diff line change
@@ -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<LexerToken>, ind: &mut usize, original: Box<ASTTreeNode>, restricts_to_assigns: bool) -> DiagnosticResult<Box<ASTTreeNode>> {
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())
}

Expand All @@ -18,5 +18,5 @@ pub fn parse_math_operation(tokens: &Vec<LexerToken>, 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)))
}
4 changes: 2 additions & 2 deletions compiler/ast_parser/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub fn parse_type_type_parameters(tokens: &Vec<LexerToken>, ind: &mut usize) ->

types.push(parsed_type);

if tokens[*ind].is_angel_bracket_close() {
if tokens[*ind].tok_type == LexerTokenType::AngelBracketClose {
break;
}

Expand Down Expand Up @@ -206,7 +206,7 @@ pub fn parse_type_parameters_declaration(tokens: &Vec<LexerToken>, ind: &mut usi

*ind += 1;

if tokens[*ind].is_angel_bracket_close() {
if tokens[*ind].tok_type == LexerTokenType::AngelBracketClose {
break;
}

Expand Down
23 changes: 7 additions & 16 deletions compiler/ast_parser/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -78,7 +78,7 @@ pub fn parse_ast_value_dotacess_chain_member(tokens: &Vec<LexerToken>, ind: &mut
///
pub fn parse_ast_value_post_l(tokens: &Vec<LexerToken>, ind: &mut usize, original: DiagnosticResult<Box<ASTTreeNode>>, invoked_on_body: bool) -> DiagnosticResult<Box<ASTTreeNode>> {
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()));

Expand All @@ -92,6 +92,10 @@ pub fn parse_ast_value_post_l(tokens: &Vec<LexerToken>, 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() {
Expand All @@ -118,20 +122,7 @@ pub fn parse_ast_value_post_l(tokens: &Vec<LexerToken>, 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
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/astoir_hir/src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}};

Expand Down Expand Up @@ -51,7 +50,7 @@ pub enum HIRNodeKind {

VarAssigment { variable: usize, val: Box<HIRNode> },

MathOperation { left: Box<HIRNode>, right: Box<HIRNode>, operation: MathOperator, assignment: bool },
MathOperation { left: Box<HIRNode>, right: Box<HIRNode>, operation: MathOperator },

UnwrapCondition { original: Box<HIRNode>, new_type: Type, new_var: Option<usize>, unsafe_unwrap: bool },
UnwrapValue { original: Box<HIRNode>, new_type: Type, unsafe_unwrap: bool },
Expand Down Expand Up @@ -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)
},

Expand Down
6 changes: 3 additions & 3 deletions compiler/astoir_hir_lowering/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ 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<ASTTreeNode>, enforce_assign: bool) -> DiagnosticResult<Box<HIRNode>> {
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())
}

let left = lower_ast_value(context, curr_ctx, lval)?;

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")
Expand Down
12 changes: 12 additions & 0 deletions compiler/astoir_mir/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<MIRIntValue> {
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<MIRIntValue> {
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<MIRIntValue> {
let res = ctx.append_inst(MIRInstruction::IntegerNeg { val }).get()?;

Expand Down
1 change: 0 additions & 1 deletion compiler/astoir_mir_lowering/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
4 changes: 2 additions & 2 deletions compiler/astoir_mir_lowering/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ pub fn lower_hir_body_member(block: MIRBlockReference, node: Box<HIRNode>, 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())
}

Expand Down
Loading