Struct semantic_analyzer::semantic::State
source · pub struct State<E, I>where
E: ExtendedExpression,
I: SemanticContextInstruction,{
pub global: GlobalState<I>,
pub context: Vec<Rc<RefCell<BlockState<I>>>>,
pub errors: Vec<StateErrorResult>,
/* private fields */
}Expand description
State
Basic entity that contains:
Global State- types, constants, functions declaration and most important - context results of Semantic State stack, that can be used for post-verification and/or Codegen.Contextstack forBlock stateof each functions body stateError Statecontains errors stack as result of Semantic analyzer
Fields§
§global: GlobalState<I>Global State for current State
context: Vec<Rc<RefCell<BlockState<I>>>>Context for all Block State stack that related to concrete functions body.
errors: Vec<StateErrorResult>Error state results stack
Implementations§
source§impl<E, I> State<E, I>where
E: ExtendedExpression,
I: SemanticContextInstruction,
impl<E, I> State<E, I>where
E: ExtendedExpression,
I: SemanticContextInstruction,
sourcepub fn run(&mut self, data: &Main<'_, E>)
pub fn run(&mut self, data: &Main<'_, E>)
Run semantic analyzer that covers all flow for AST.
It’s do not return any results, but fill results fir the Semantic State.
sourcepub fn import(&self, data: &ImportPath<'_>)
pub fn import(&self, data: &ImportPath<'_>)
Import analyzer (TBD)
sourcepub fn types(&mut self, data: &StructTypes<'_>)
pub fn types(&mut self, data: &StructTypes<'_>)
Types declaration analyzer. Add types to Global State.
Currently only one type kind: Structs. And types can’t be part of
the Block State.
sourcepub fn check_constant_value_expression(
&mut self,
data: &Option<(ExpressionOperations, Box<ConstantExpression<'_>>)>
) -> bool
pub fn check_constant_value_expression( &mut self, data: &Option<(ExpressionOperations, Box<ConstantExpression<'_>>)> ) -> bool
Check constant value expression.
If expression contains Constant check is constant exists.
Values doesn’t check as it’s just Primitive Values.
Also check all expression tree branches.
If ConstantValue doesn’t exist add error to Error State and return false result.
sourcepub fn constant(&mut self, data: &Constant<'_>)
pub fn constant(&mut self, data: &Constant<'_>)
Constant analyzer. Add it to Global State, because constants
can be only global for Semantic state, not for Block state.
sourcepub fn function_declaration(&mut self, data: &FunctionStatement<'_, E>)
pub fn function_declaration(&mut self, data: &FunctionStatement<'_, E>)
Function declaration analyze. Add it to Global State/M
sourcepub fn function_body(&mut self, data: &FunctionStatement<'_, E>)
pub fn function_body(&mut self, data: &FunctionStatement<'_, E>)
Function body analyze. 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.
sourcepub fn let_binding(
&mut self,
data: &LetBinding<'_, E>,
function_state: &Rc<RefCell<BlockState<I>>>
)
pub fn let_binding( &mut self, data: &LetBinding<'_, E>, function_state: &Rc<RefCell<BlockState<I>>> )
Let-binding statement
Analyze let-binding statement:
- Let value bind from expression. First should be analysed
expressionfor binding value. - Generate value for current state. Special field
inner_namethat used as name forCodegenshould be unique in current state and for all parent states. For thatinner_namethe inner value name counter incremented. - Set
Valueparameters:inner_name, type and allocation status - Insert value to current values state map: value
name->Data - Store
inner_namein current and parent states - Codegen
sourcepub fn binding(
&mut self,
data: &Binding<'_, E>,
function_state: &Rc<RefCell<BlockState<I>>>
)
pub fn binding( &mut self, data: &Binding<'_, E>, function_state: &Rc<RefCell<BlockState<I>>> )
Binding statement
Analyze binding statement for mutable variables:
- Bind from expression. First should be analysed
expressionfor binding value. - Read value for current state.
- Update value to current values state map: value
name->Data - Codegen with Store action
sourcepub fn function_call(
&mut self,
data: &FunctionCall<'_, E>,
body_state: &Rc<RefCell<BlockState<I>>>
) -> Option<Type>
pub fn function_call( &mut self, data: &FunctionCall<'_, E>, body_state: &Rc<RefCell<BlockState<I>>> ) -> Option<Type>
Function-call
Call function with function parameters arguments. Arguments is expressions.
- Check is current function name exists in global state of functions name.
- Analyse expressions for function parameters
- Inc register
- Generate codegen Codegen store always result to register even for void result.
Errors
Return error if function name doesn’t exist in global state
sourcepub fn condition_expression(
&mut self,
data: &ExpressionLogicCondition<'_, E>,
function_body_state: &Rc<RefCell<BlockState<I>>>
) -> u64
pub fn condition_expression( &mut self, data: &ExpressionLogicCondition<'_, E>, function_body_state: &Rc<RefCell<BlockState<I>>> ) -> u64
condition-expression
Analyse condition operations.
Return
Return result register of condition-expression calculation.
sourcepub fn if_condition_body(
&mut self,
body: &[IfBodyStatement<'_, E>],
if_body_state: &Rc<RefCell<BlockState<I>>>,
label_end: &LabelName,
label_loop: Option<(&LabelName, &LabelName)>
) -> bool
pub fn if_condition_body( &mut self, body: &[IfBodyStatement<'_, E>], if_body_state: &Rc<RefCell<BlockState<I>>>, label_end: &LabelName, label_loop: Option<(&LabelName, &LabelName)> ) -> bool
If-condition body
Analyze body for ant if condition:
- if, else, if-else
NOTE:
label_end- is always already exists
Return
Return body statement “return” status
sourcepub fn if_condition_loop_body(
&mut self,
body: &[IfLoopBodyStatement<'_, E>],
if_body_state: &Rc<RefCell<BlockState<I>>>,
label_if_end: &LabelName,
label_loop_start: &LabelName,
label_loop_end: &LabelName
) -> bool
pub fn if_condition_loop_body( &mut self, body: &[IfLoopBodyStatement<'_, E>], if_body_state: &Rc<RefCell<BlockState<I>>>, label_if_end: &LabelName, label_loop_start: &LabelName, label_loop_end: &LabelName ) -> bool
If-condition loop body
Analyze body for ant if condition:
- if, else, if-else
Return
Return body statement “return” status
sourcepub fn if_condition_calculation(
&mut self,
condition: &IfCondition<'_, E>,
if_body_state: &Rc<RefCell<BlockState<I>>>,
label_if_begin: &LabelName,
label_if_else: &LabelName,
label_if_end: &LabelName,
is_else: bool
)
pub fn if_condition_calculation( &mut self, condition: &IfCondition<'_, E>, if_body_state: &Rc<RefCell<BlockState<I>>>, label_if_begin: &LabelName, label_if_else: &LabelName, label_if_end: &LabelName, is_else: bool )
If conditions calculations
Calculate conditions for if-condition. It can contain simple and logic conditions.
sourcepub fn if_condition(
&mut self,
data: &IfStatement<'_, E>,
function_body_state: &Rc<RefCell<BlockState<I>>>,
label_end: &Option<LabelName>,
label_loop: Option<(&LabelName, &LabelName)>
)
pub fn if_condition( &mut self, data: &IfStatement<'_, E>, function_body_state: &Rc<RefCell<BlockState<I>>>, label_end: &Option<LabelName>, label_loop: Option<(&LabelName, &LabelName)> )
If-condition
Analyzing includes all variants for if statements:
- if
- if-else
- if-else-if
It creates own state, with parent function-state. in that case
if-state independent from parent state, but csn get access to
parent state.
If condition can’t contain
elseandif-elseon the same time.
Special case for label_end - it should be set from previous
context, and main goal is to end all of if-condition nodes in
the same flow with same if-end label. It’s especially important
for else-if condition.
Panics
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
sourcepub fn loop_statement(
&mut self,
data: &[LoopBodyStatement<'_, E>],
function_body_state: &Rc<RefCell<BlockState<I>>>
)
pub fn loop_statement( &mut self, data: &[LoopBodyStatement<'_, E>], function_body_state: &Rc<RefCell<BlockState<I>>> )
sourcepub fn expression(
&mut self,
data: &Expression<'_, E>,
body_state: &Rc<RefCell<BlockState<I>>>
) -> Option<ExpressionResult>
pub fn expression( &mut self, data: &Expression<'_, E>, body_state: &Rc<RefCell<BlockState<I>>> ) -> Option<ExpressionResult>
Expression
Is basic entity for state operation and state usage. State correctness verified by expressions call. Expressions folded by operations priority. For that expressions tree folded each leaf of tree by priority operation level. The most striking image is bracketing an expression with a higher priority, and build tree based on that.
Return
PrimitiveValue | TmpRegister
Possible algorithm conditions: 1. PrimitiveValue -> PrimitiveValue 2. Value -> load -> TmpRegister 3. FuncCall -> call -> TmpRegister 4. Operations 4.1. PrimitiveValue - PrimitiveValue -> tmp = OP val1, val2 -> TmpRegister - Value -> tmp1 = load -> OP val1, tmp1 -> TmpRegister - FuncCAll -> tmp1 = call -> OP val1, tmp1 -> TmpRegister 4.2. TmpRegister (with name tmp1) - PrimitiveValue -> tmp2 = OP tmp1, val1 -> TmpRegister - Value -> tmp2 = load -> tmp3 = OP tmp1, tmp2 -> TmpRegister - FuncCall -> tmp2 = call -> tmp3 = OP tmp1, tmp2 -> TmpRegister 4.3. Operations -> recursively invoke 4.2.
sourcepub fn expression_operation(
&mut self,
left_value: Option<&ExpressionResult>,
right_expression: &Expression<'_, E>,
op: Option<&ExpressionOperations>,
body_state: &Rc<RefCell<BlockState<I>>>
) -> Option<ExpressionResult>
pub fn expression_operation( &mut self, left_value: Option<&ExpressionResult>, right_expression: &Expression<'_, E>, op: Option<&ExpressionOperations>, body_state: &Rc<RefCell<BlockState<I>>> ) -> Option<ExpressionResult>
Expression operation semantic logic:
OP(lhs, rhs)
Left-value contains optional Expression result for left side
of expression.