diff --git a/src/ast.rs b/src/ast.rs index 8665df8..013b0ed 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -3,6 +3,7 @@ //! represent full cycle and aspects of the programming language, and //! represent `Turing-complete` state machine. +use crate::types::semantic::ExtendedExpression; use nom_locate::LocatedSpan; #[cfg(feature = "codec")] use serde::{ @@ -519,7 +520,7 @@ pub struct FunctionParameter<'a> { /// function body. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] -pub struct FunctionStatement<'a> { +pub struct FunctionStatement<'a, E: ExtendedExpression> { /// Function name #[cfg_attr(feature = "codec", serde(borrow))] pub name: FunctionName<'a>, @@ -528,16 +529,16 @@ pub struct FunctionStatement<'a> { /// Function result type pub result_type: Type<'a>, /// Function body - pub body: Vec>, + pub body: Vec>, } -impl GetLocation for FunctionStatement<'_> { +impl GetLocation for FunctionStatement<'_, E> { fn location(&self) -> CodeLocation { self.name.location() } } -impl GetName for FunctionStatement<'_> { +impl GetName for FunctionStatement<'_, E> { fn name(&self) -> String { (*self.name.0.fragment()).to_string() } @@ -608,18 +609,20 @@ impl PrimitiveValue { derive(Serialize, Deserialize), serde(tag = "type", content = "content") )] -pub enum ExpressionValue<'a> { +pub enum ExpressionValue<'a, E: ExtendedExpression> { /// Value name of expression #[cfg_attr(feature = "codec", serde(borrow))] ValueName(ValueName<'a>), /// Primitive value of expression (like numbers etc.) PrimitiveValue(PrimitiveValue), /// Function call (with parameters) of expression - FunctionCall(FunctionCall<'a>), + FunctionCall(FunctionCall<'a, E>), /// Value of expression based on `Struct` types. StructValue(ExpressionStructValue<'a>), /// Expression representation (sub branch) - Expression(Box>), + Expression(Box>), + /// Extended expression + ExtendedExpression(Box), } /// `ExpressionOperations` expression operation element of AST. @@ -679,15 +682,15 @@ impl ExpressionOperations { /// with expression operations. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] -pub struct Expression<'a> { +pub struct Expression<'a, E: ExtendedExpression> { /// Expression value itself #[cfg_attr(feature = "codec", serde(borrow))] - pub expression_value: ExpressionValue<'a>, + pub expression_value: ExpressionValue<'a, E>, /// Optional expression operation with other expression value - pub operation: Option<(ExpressionOperations, Box>)>, + pub operation: Option<(ExpressionOperations, Box>)>, } -impl GetLocation for Expression<'_> { +impl GetLocation for Expression<'_, E> { fn location(&self) -> CodeLocation { // TODO: extend it CodeLocation::new(1, 0) @@ -698,7 +701,7 @@ impl GetLocation for Expression<'_> { /// for `values` declarations. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize), serde(tag = "type"))] -pub struct LetBinding<'a> { +pub struct LetBinding<'a, E: ExtendedExpression> { /// Value name of let binding #[cfg_attr(feature = "codec", serde(borrow))] pub name: ValueName<'a>, @@ -707,16 +710,16 @@ pub struct LetBinding<'a> { /// Optional type of value pub value_type: Option>, /// Value expression to bind as result of let bending - pub value: Box>, + pub value: Box>, } -impl GetLocation for LetBinding<'_> { +impl GetLocation for LetBinding<'_, E> { fn location(&self) -> CodeLocation { self.name.location() } } -impl GetName for LetBinding<'_> { +impl GetName for LetBinding<'_, E> { fn name(&self) -> String { self.name.0.to_string() } @@ -727,21 +730,21 @@ impl GetName for LetBinding<'_> { /// declared values. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] -pub struct Binding<'a> { +pub struct Binding<'a, E: ExtendedExpression> { /// Binding value name #[cfg_attr(feature = "codec", serde(borrow))] pub name: ValueName<'a>, /// Value expression as result of binding - pub value: Box>, + pub value: Box>, } -impl GetLocation for Binding<'_> { +impl GetLocation for Binding<'_, E> { fn location(&self) -> CodeLocation { self.name.location() } } -impl GetName for Binding<'_> { +impl GetName for Binding<'_, E> { fn name(&self) -> String { self.name.0.to_string() } @@ -751,21 +754,21 @@ impl GetName for Binding<'_> { /// Basic entity for function call representation. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] -pub struct FunctionCall<'a> { +pub struct FunctionCall<'a, E: ExtendedExpression> { /// Function name of called function #[cfg_attr(feature = "codec", serde(borrow))] pub name: FunctionName<'a>, /// Function parameters, represented through expression - pub parameters: Vec>, + pub parameters: Vec>, } -impl GetLocation for FunctionCall<'_> { +impl GetLocation for FunctionCall<'_, E> { fn location(&self) -> CodeLocation { self.name.location() } } -impl GetName for FunctionCall<'_> { +impl GetName for FunctionCall<'_, E> { fn name(&self) -> String { (*self.name.0.fragment()).to_string() } @@ -807,14 +810,14 @@ pub enum LogicCondition { /// It contains condition between twe expressions. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] -pub struct ExpressionCondition<'a> { +pub struct ExpressionCondition<'a, E: ExtendedExpression> { /// Left expression #[cfg_attr(feature = "codec", serde(borrow))] - pub left: Expression<'a>, + pub left: Expression<'a, E>, /// Condition between left and right expressions pub condition: Condition, /// Righ expression - pub right: Expression<'a>, + pub right: Expression<'a, E>, } /// # Logic expression condition @@ -826,12 +829,12 @@ pub struct ExpressionCondition<'a> { /// expressions logic conditions. #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] -pub struct ExpressionLogicCondition<'a> { +pub struct ExpressionLogicCondition<'a, E: ExtendedExpression> { /// Left expression condition #[cfg_attr(feature = "codec", serde(borrow))] - pub left: ExpressionCondition<'a>, + pub left: ExpressionCondition<'a, E>, /// Optional right side contain logic operation to other `ExpressionLogicCondition` - pub right: Option<(LogicCondition, Box>)>, + pub right: Option<(LogicCondition, Box>)>, } /// `IfCondition` if-condition control flow element of AST. @@ -844,12 +847,12 @@ pub struct ExpressionLogicCondition<'a> { derive(Serialize, Deserialize), serde(tag = "type", content = "content") )] -pub enum IfCondition<'a> { +pub enum IfCondition<'a, E: ExtendedExpression> { /// Single if condition based on expression #[cfg_attr(feature = "codec", serde(borrow))] - Single(Expression<'a>), + Single(Expression<'a, E>), /// Logic expression condition tree - Logic(ExpressionLogicCondition<'a>), + Logic(ExpressionLogicCondition<'a, E>), } /// `IfStatement` if statement AST element. @@ -860,19 +863,19 @@ pub enum IfCondition<'a> { /// - Else-if-body statement - body of else-if-condition success #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] -pub struct IfStatement<'a> { +pub struct IfStatement<'a, E: ExtendedExpression> { /// If-condition #[cfg_attr(feature = "codec", serde(borrow))] - pub condition: IfCondition<'a>, + pub condition: IfCondition<'a, E>, /// If-body statement - body of if-condition success - pub body: IfBodyStatements<'a>, + pub body: IfBodyStatements<'a, E>, /// If-else-body statement - body of else-condition success - pub else_statement: Option>, + pub else_statement: Option>, /// Else-if-body statement - body of else-if-condition success - pub else_if_statement: Option>>, + pub else_if_statement: Option>>, } -impl GetLocation for IfStatement<'_> { +impl GetLocation for IfStatement<'_, E> { fn location(&self) -> CodeLocation { // TODO CodeLocation::new(1, 0) @@ -887,22 +890,22 @@ impl GetLocation for IfStatement<'_> { derive(Serialize, Deserialize), serde(tag = "type", content = "content") )] -pub enum BodyStatement<'a> { +pub enum BodyStatement<'a, E: ExtendedExpression> { /// Let-binding function declaration #[cfg_attr(feature = "codec", serde(borrow))] - LetBinding(LetBinding<'a>), + LetBinding(LetBinding<'a, E>), /// Binding function declaration - Binding(Binding<'a>), + Binding(Binding<'a, E>), /// Function call - FunctionCall(FunctionCall<'a>), + FunctionCall(FunctionCall<'a, E>), /// If-condition control flow statement - If(IfStatement<'a>), + If(IfStatement<'a, E>), /// Loop control flow statement - Loop(Vec>), + Loop(Vec>), /// Expression statement - Expression(Expression<'a>), + Expression(Expression<'a, E>), /// Return statement - Return(Expression<'a>), + Return(Expression<'a, E>), } /// `IfBodyStatement` statement of if-body elements tree of AST. @@ -913,14 +916,14 @@ pub enum BodyStatement<'a> { derive(Serialize, Deserialize), serde(tag = "type", content = "content") )] -pub enum IfBodyStatement<'a> { +pub enum IfBodyStatement<'a, E: ExtendedExpression> { #[cfg_attr(feature = "codec", serde(borrow))] - LetBinding(LetBinding<'a>), - Binding(Binding<'a>), - FunctionCall(FunctionCall<'a>), - If(IfStatement<'a>), - Loop(Vec>), - Return(Expression<'a>), + LetBinding(LetBinding<'a, E>), + Binding(Binding<'a, E>), + FunctionCall(FunctionCall<'a, E>), + If(IfStatement<'a, E>), + Loop(Vec>), + Return(Expression<'a, E>), } /// `IfLoopBodyStatement` statement of loop-if-body elements tree of AST. @@ -928,14 +931,14 @@ pub enum IfBodyStatement<'a> { #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "codec", derive(Serialize, Deserialize))] #[cfg_attr(feature = "codec", serde(tag = "type", content = "content"))] -pub enum IfLoopBodyStatement<'a> { +pub enum IfLoopBodyStatement<'a, E: ExtendedExpression> { #[cfg_attr(feature = "codec", serde(borrow))] - LetBinding(LetBinding<'a>), - Binding(Binding<'a>), - FunctionCall(FunctionCall<'a>), - If(IfStatement<'a>), - Loop(Vec>), - Return(Expression<'a>), + LetBinding(LetBinding<'a, E>), + Binding(Binding<'a, E>), + FunctionCall(FunctionCall<'a, E>), + If(IfStatement<'a, E>), + Loop(Vec>), + Return(Expression<'a, E>), Break, Continue, } @@ -948,10 +951,10 @@ pub enum IfLoopBodyStatement<'a> { derive(Serialize, Deserialize), serde(tag = "type", content = "content") )] -pub enum IfBodyStatements<'a> { +pub enum IfBodyStatements<'a, E: ExtendedExpression> { #[cfg_attr(feature = "codec", serde(borrow))] - If(Vec>), - Loop(Vec>), + If(Vec>), + Loop(Vec>), } /// `LoopBodyStatement` statement of loop-body elements tree of AST. @@ -962,14 +965,14 @@ pub enum IfBodyStatements<'a> { derive(Serialize, Deserialize), serde(tag = "type", content = "content") )] -pub enum LoopBodyStatement<'a> { +pub enum LoopBodyStatement<'a, E: ExtendedExpression> { #[cfg_attr(feature = "codec", serde(borrow))] - LetBinding(LetBinding<'a>), - Binding(Binding<'a>), - FunctionCall(FunctionCall<'a>), - If(IfStatement<'a>), - Loop(Vec>), - Return(Expression<'a>), + LetBinding(LetBinding<'a, E>), + Binding(Binding<'a, E>), + FunctionCall(FunctionCall<'a, E>), + If(IfStatement<'a, E>), + Loop(Vec>), + Return(Expression<'a, E>), Break, Continue, } @@ -981,7 +984,7 @@ pub enum LoopBodyStatement<'a> { derive(Serialize, Deserialize), serde(tag = "type", content = "content") )] -pub enum MainStatement<'a> { +pub enum MainStatement<'a, E: ExtendedExpression> { /// Import declarations #[cfg_attr(feature = "codec", serde(borrow))] Import(ImportPath<'a>), @@ -990,10 +993,10 @@ pub enum MainStatement<'a> { /// Type declaration Types(StructTypes<'a>), /// Function declaration and function body-statement - Function(FunctionStatement<'a>), + Function(FunctionStatement<'a, E>), } /// # Main /// Stack of `MainStatement` main AST elements. That gather /// tries of AST, to represent full sort of source code. -pub type Main<'a> = Vec>; +pub type Main<'a, E> = Vec>; diff --git a/src/semantic.rs b/src/semantic.rs index da96db5..028e6fd 100644 --- a/src/semantic.rs +++ b/src/semantic.rs @@ -15,7 +15,9 @@ use crate::types::block_state::BlockState; use crate::types::expression::{ Expression, ExpressionResult, ExpressionResultValue, ExpressionStructValue, }; -use crate::types::semantic::{GlobalSemanticContext, SemanticContext, SemanticStack}; +use crate::types::semantic::{ + ExtendedExpression, GlobalSemanticContext, SemanticContext, SemanticStack, +}; use crate::types::types::{Type, TypeName}; use crate::types::{ error, Binding, Constant, ConstantName, Function, FunctionCall, FunctionName, @@ -129,7 +131,7 @@ impl State { /// Run semantic analyzer that covers all flow for AST. /// It's do not return any results, but fill results fir the `Semantic State`. /// - pub fn run(&mut self, data: &ast::Main<'_>) { + pub fn run(&mut self, data: &ast::Main<'_, E>) { // Execute each kind of analyzing and return errors data. // For functions - fetch only declaration for fast-forward // identification for using it in functions body. @@ -245,7 +247,10 @@ impl State { } /// Function declaration analyze. Add it to Global State/M - pub fn function_declaration(&mut self, data: &ast::FunctionStatement<'_>) { + pub fn function_declaration( + &mut self, + data: &ast::FunctionStatement<'_, E>, + ) { if self.global.functions.contains_key(&data.name().into()) { self.add_error(error::StateErrorResult::new( error::StateErrorKind::FunctionAlreadyExist, @@ -342,7 +347,7 @@ impl State { /// It is basic execution entity for program flow. /// It's operate sub analyze for function elements. It's contain /// Body State for current and child states. - pub fn function_body(&mut self, data: &ast::FunctionStatement<'_>) { + pub fn function_body(&mut self, data: &ast::FunctionStatement<'_, E>) { // Init empty function body state let body_state = Rc::new(RefCell::new(BlockState::new(None))); self.add_state_context(body_state.clone()); @@ -389,7 +394,7 @@ impl State { } if let Some(res) = expr_result { // Check expression type and do not exist from flow - self.check_type_exists(&res.expr_type, &expr, &expression.clone()); + self.check_type_exists(&res.expr_type, &expr, expression); let fn_ty: Type = data.result_type.clone().into(); if fn_ty != res.expr_type { self.add_error(error::StateErrorResult::new( @@ -441,9 +446,9 @@ impl State { /// 4. Insert value to current values state map: value `name` -> `Data` /// 5. Store `inner_name` in current and parent states /// 6. Codegen - pub fn let_binding( + pub fn let_binding( &mut self, - data: &ast::LetBinding<'_>, + data: &ast::LetBinding<'_, E>, function_state: &Rc>, ) { // Call value analytics before putting let-value to state @@ -509,7 +514,11 @@ impl State { /// 2. Read value for current state. /// 3. Update value to current values state map: value `name` -> `Data` /// 4. Codegen with Store action - pub fn binding(&mut self, data: &ast::Binding<'_>, function_state: &Rc>) { + pub fn binding( + &mut self, + data: &ast::Binding<'_, E>, + function_state: &Rc>, + ) { // Call value analytics before putting let-value to state let Some(expr_result) = self.expression(&data.value, function_state) else { return; @@ -549,9 +558,9 @@ impl State { /// /// ## Errors /// Return error if function name doesn't exist in global state - pub fn function_call( + pub fn function_call( &mut self, - data: &ast::FunctionCall<'_>, + data: &ast::FunctionCall<'_, E>, body_state: &Rc>, ) -> Option { let func_call_data: FunctionCall = data.clone().into(); @@ -597,9 +606,9 @@ impl State { /// Analyse condition operations. /// ## Return /// Return result register of `condition-expression` calculation. - pub fn condition_expression( + pub fn condition_expression( &mut self, - data: &ast::ExpressionLogicCondition<'_>, + data: &ast::ExpressionLogicCondition<'_, E>, function_body_state: &Rc>, ) -> u64 { // Analyse left expression of left condition @@ -680,9 +689,9 @@ impl State { /// NOTE: `label_end` - is always already exists /// ## Return /// Return body statement "return" status - pub fn if_condition_body( + pub fn if_condition_body( &mut self, - body: &[ast::IfBodyStatement<'_>], + body: &[ast::IfBodyStatement<'_, E>], if_body_state: &Rc>, label_end: &LabelName, label_loop: Option<(&LabelName, &LabelName)>, @@ -738,9 +747,9 @@ impl State { /// - if, else, if-else /// ## Return /// Return body statement "return" status - pub fn if_condition_loop_body( + pub fn if_condition_loop_body( &mut self, - body: &[ast::IfLoopBodyStatement<'_>], + body: &[ast::IfLoopBodyStatement<'_, E>], if_body_state: &Rc>, label_if_end: &LabelName, label_loop_start: &LabelName, @@ -823,9 +832,9 @@ impl State { /// # If conditions calculations /// Calculate conditions for if-condition. It can contain /// simple and logic conditions. - pub fn if_condition_calculation( + pub fn if_condition_calculation( &mut self, - condition: &ast::IfCondition<'_>, + condition: &ast::IfCondition<'_, E>, if_body_state: &Rc>, label_if_begin: &LabelName, label_if_else: &LabelName, @@ -898,9 +907,9 @@ impl State { /// `label_loop` is must be set, it's special case for the Loop, /// when `label_loop` should always be set. If it doesn't set, it's /// unexpected behavior and program algorithm error - pub fn if_condition( + pub fn if_condition( &mut self, - data: &ast::IfStatement<'_>, + data: &ast::IfStatement<'_, E>, function_body_state: &Rc>, label_end: &Option, label_loop: Option<(&LabelName, &LabelName)>, @@ -1046,9 +1055,9 @@ impl State { /// - loop body /// - end of loop /// - return, break, continue - pub fn loop_statement( + pub fn loop_statement( &mut self, - data: &[ast::LoopBodyStatement<'_>], + data: &[ast::LoopBodyStatement<'_, E>], function_body_state: &Rc>, ) { // Create state for loop-body, from parent func state because @@ -1186,9 +1195,9 @@ impl State { /// - Value -> tmp2 = load -> tmp3 = OP tmp1, tmp2 -> TmpRegister /// - FuncCall -> tmp2 = call -> tmp3 = OP tmp1, tmp2 -> TmpRegister /// 4.3. Operations -> recursively invoke 4.2. - pub fn expression( + pub fn expression( &mut self, - data: &ast::Expression<'_>, + data: &ast::Expression<'_, E>, body_state: &Rc>, ) -> Option { // Fold expression operations priority @@ -1207,10 +1216,10 @@ impl State { /// Left-value contains optional Expression result for left side /// of expression. #[allow(clippy::too_many_lines)] - pub fn expression_operation( + pub fn expression_operation( &mut self, left_value: Option<&ExpressionResult>, - right_expression: &ast::Expression<'_>, + right_expression: &ast::Expression<'_, E>, op: Option<&ast::ExpressionOperations>, body_state: &Rc>, ) -> Option { @@ -1348,6 +1357,7 @@ impl State { // Subexpression should be analyzed independently self.expression(expr, body_state)? } + ast::ExpressionValue::ExtendedExpression(expr) => expr.expression(self, body_state), }; // Check left expression side and generate expression operation code let expression_result = if let (Some(left_value), Some(op)) = (left_value, op) { @@ -1399,7 +1409,9 @@ impl State { /// /// ## Return /// New folded expressions tree. - fn expression_operations_priority(data: ast::Expression<'_>) -> ast::Expression<'_> { + fn expression_operations_priority( + data: ast::Expression<'_, E>, + ) -> ast::Expression<'_, E> { let mut data = data; for priority in (0..=MAX_PRIORITY_LEVEL_FOR_EXPRESSIONS).rev() { data = Self::fetch_op_priority(data, priority); @@ -1421,7 +1433,10 @@ impl State { /// expression tree from left to right. /// If priority level not equal, we just return income expression, or /// if it has subbranch - launch fetching subbranch - fn fetch_op_priority(data: ast::Expression<'_>, priority_level: u8) -> ast::Expression<'_> { + fn fetch_op_priority( + data: ast::Expression<'_, E>, + priority_level: u8, + ) -> ast::Expression<'_, E> { // Check is expression contains right side with operation if let Some((op, expr)) = data.clone().operation { // Check is right expression contain subbranch (sub operation) diff --git a/src/types/condition.rs b/src/types/condition.rs index 5050283..03a3113 100644 --- a/src/types/condition.rs +++ b/src/types/condition.rs @@ -4,6 +4,7 @@ use super::expression::Expression; use super::{Binding, FunctionCall, LetBinding}; use crate::ast; +use crate::types::semantic::ExtendedExpression; #[cfg(feature = "codec")] use serde::{Deserialize, Serialize}; @@ -70,8 +71,8 @@ pub struct ExpressionCondition { pub right: Expression, } -impl From> for ExpressionCondition { - fn from(value: ast::ExpressionCondition<'_>) -> Self { +impl From> for ExpressionCondition { + fn from(value: ast::ExpressionCondition<'_, E>) -> Self { Self { left: value.left.into(), condition: value.condition.into(), @@ -92,8 +93,10 @@ pub struct ExpressionLogicCondition { pub right: Option<(LogicCondition, Box)>, } -impl From> for ExpressionLogicCondition { - fn from(value: ast::ExpressionLogicCondition<'_>) -> Self { +impl From> + for ExpressionLogicCondition +{ + fn from(value: ast::ExpressionLogicCondition<'_, E>) -> Self { Self { left: value.left.into(), right: value @@ -117,8 +120,8 @@ pub enum IfCondition { Logic(ExpressionLogicCondition), } -impl From> for IfCondition { - fn from(value: ast::IfCondition<'_>) -> Self { +impl From> for IfCondition { + fn from(value: ast::IfCondition<'_, E>) -> Self { match value { ast::IfCondition::Single(v) => Self::Single(v.into()), ast::IfCondition::Logic(v) => Self::Logic(v.into()), @@ -141,8 +144,8 @@ pub struct IfStatement { pub else_if_statement: Option>, } -impl From> for IfStatement { - fn from(value: ast::IfStatement<'_>) -> Self { +impl From> for IfStatement { + fn from(value: ast::IfStatement<'_, E>) -> Self { Self { condition: value.condition.into(), body: value.body.into(), @@ -168,8 +171,8 @@ pub enum IfBodyStatements { Loop(Vec), } -impl From> for IfBodyStatements { - fn from(value: ast::IfBodyStatements<'_>) -> Self { +impl From> for IfBodyStatements { + fn from(value: ast::IfBodyStatements<'_, E>) -> Self { match value { ast::IfBodyStatements::If(v) => Self::If(v.iter().map(|v| v.clone().into()).collect()), ast::IfBodyStatements::Loop(v) => { @@ -197,8 +200,8 @@ pub enum LoopBodyStatement { Continue, } -impl From> for LoopBodyStatement { - fn from(value: ast::LoopBodyStatement<'_>) -> Self { +impl From> for LoopBodyStatement { + fn from(value: ast::LoopBodyStatement<'_, E>) -> Self { match value { ast::LoopBodyStatement::LetBinding(v) => Self::LetBinding(v.into()), ast::LoopBodyStatement::Binding(v) => Self::Binding(v.into()), @@ -230,8 +233,8 @@ pub enum IfBodyStatement { Return(Expression), } -impl From> for IfBodyStatement { - fn from(value: ast::IfBodyStatement<'_>) -> Self { +impl From> for IfBodyStatement { + fn from(value: ast::IfBodyStatement<'_, E>) -> Self { match value { ast::IfBodyStatement::LetBinding(v) => Self::LetBinding(v.into()), ast::IfBodyStatement::Binding(v) => Self::Binding(v.into()), @@ -264,8 +267,8 @@ pub enum IfLoopBodyStatement { Continue, } -impl From> for IfLoopBodyStatement { - fn from(value: ast::IfLoopBodyStatement<'_>) -> Self { +impl From> for IfLoopBodyStatement { + fn from(value: ast::IfLoopBodyStatement<'_, E>) -> Self { match value { ast::IfLoopBodyStatement::LetBinding(v) => Self::LetBinding(v.into()), ast::IfLoopBodyStatement::Binding(v) => Self::Binding(v.into()), diff --git a/src/types/expression.rs b/src/types/expression.rs index 0c93a54..56a6747 100644 --- a/src/types/expression.rs +++ b/src/types/expression.rs @@ -4,6 +4,7 @@ use super::types::Type; use super::{FunctionCall, PrimitiveValue, ValueName}; use crate::ast; +use crate::types::semantic::ExtendedExpression; #[cfg(feature = "codec")] use serde::{Deserialize, Serialize}; @@ -68,8 +69,8 @@ impl ToString for ExpressionValue { } } -impl From> for ExpressionValue { - fn from(value: ast::ExpressionValue<'_>) -> Self { +impl From> for ExpressionValue { + fn from(value: ast::ExpressionValue<'_, E>) -> Self { match value { ast::ExpressionValue::ValueName(v) => Self::ValueName(v.into()), ast::ExpressionValue::PrimitiveValue(v) => Self::PrimitiveValue(v.into()), @@ -78,6 +79,7 @@ impl From> for ExpressionValue { ast::ExpressionValue::Expression(v) => { Self::Expression(Box::new(v.as_ref().clone().into())) } + ast::ExpressionValue::ExtendedExpression(..) => todo!(), } } } @@ -175,8 +177,8 @@ impl ToString for Expression { } } -impl From> for Expression { - fn from(value: ast::Expression<'_>) -> Self { +impl From> for Expression { + fn from(value: ast::Expression<'_, E>) -> Self { Self { expression_value: value.expression_value.into(), operation: value diff --git a/src/types/mod.rs b/src/types/mod.rs index ae8f805..0cff633 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -25,6 +25,7 @@ use self::expression::{Expression, ExpressionOperations}; use self::types::Type; use crate::ast; use crate::ast::GetName; +use crate::types::semantic::ExtendedExpression; #[cfg(feature = "codec")] use serde::{Deserialize, Serialize}; @@ -309,8 +310,8 @@ pub struct FunctionStatement { pub body: Vec, } -impl From> for FunctionStatement { - fn from(value: ast::FunctionStatement<'_>) -> Self { +impl From> for FunctionStatement { + fn from(value: ast::FunctionStatement<'_, E>) -> Self { Self { name: value.name.into(), parameters: value.parameters.iter().map(|v| v.clone().into()).collect(), @@ -339,8 +340,8 @@ pub enum BodyStatement { Return(Expression), } -impl From> for BodyStatement { - fn from(value: ast::BodyStatement<'_>) -> Self { +impl From> for BodyStatement { + fn from(value: ast::BodyStatement<'_, E>) -> Self { match value { ast::BodyStatement::LetBinding(v) => Self::LetBinding(v.into()), ast::BodyStatement::Binding(v) => Self::Binding(v.into()), @@ -374,8 +375,8 @@ impl ToString for LetBinding { } } -impl From> for LetBinding { - fn from(value: ast::LetBinding<'_>) -> Self { +impl From> for LetBinding { + fn from(value: ast::LetBinding<'_, E>) -> Self { Self { name: value.name.into(), mutable: value.mutable, @@ -472,8 +473,8 @@ impl ToString for FunctionCall { } } -impl From> for FunctionCall { - fn from(value: ast::FunctionCall<'_>) -> Self { +impl From> for FunctionCall { + fn from(value: ast::FunctionCall<'_, E>) -> Self { Self { name: value.name.into(), parameters: value.parameters.iter().map(|v| v.clone().into()).collect(), @@ -497,8 +498,8 @@ impl ToString for Binding { } } -impl From> for Binding { - fn from(value: ast::Binding<'_>) -> Self { +impl From> for Binding { + fn from(value: ast::Binding<'_, E>) -> Self { Self { name: value.name.into(), value: Box::new(value.value.as_ref().clone().into()), diff --git a/src/types/semantic.rs b/src/types/semantic.rs index efba050..73d1450 100644 --- a/src/types/semantic.rs +++ b/src/types/semantic.rs @@ -6,8 +6,13 @@ use super::condition::{Condition, LogicCondition}; use super::expression::{ExpressionOperations, ExpressionResult}; use super::types::StructTypes; use super::{Constant, Function, FunctionParameter, FunctionStatement, LabelName, Value}; +use crate::semantic::State; +use crate::types::block_state::BlockState; #[cfg(feature = "codec")] use serde::{Deserialize, Serialize}; +use std::cell::RefCell; +use std::fmt::Debug; +use std::rc::Rc; /// Semantic Context trait contain instructions set functions /// for Global Stack context. It includes: @@ -70,6 +75,30 @@ pub trait SemanticContext { fn function_arg(&mut self, value: Value, func_arg: FunctionParameter); } +/// Trait describe AST input receiving +pub trait GetAst { + type Ast; + fn get_ast(&self) -> Self::Ast; +} + +/// Semantic Context trait contains custom instruction implementation +/// to flexibly extend context instructions. +pub trait SemanticContextInstruction: GetAst { + /// Custom instruction implementation. + /// Ast should be received from `GetAst` trait. + fn instruction(&self) -> Box; +} + +/// Extended Expression for semantic analyzer. +pub trait ExtendedExpression: GetAst + Debug + Clone + PartialEq { + // Custom expression. Ast should be received from `GetAst` trait. + fn expression( + &self, + state: &mut State, + block_state: &Rc>, + ) -> ExpressionResult; +} + /// # Semantic stack /// Semantic stack represent stack of Semantic Context results #[derive(Debug, Default, Clone, PartialEq)]