Skip to content

Commit

Permalink
Added add-error results
Browse files Browse the repository at this point in the history
  • Loading branch information
mrLSD committed Jul 20, 2023
1 parent a4981b0 commit 3b57984
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 66 deletions.
32 changes: 16 additions & 16 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,23 +214,23 @@ pub enum PrimitiveValue {
}

impl PrimitiveValue {
pub const fn get_type(&self) -> PrimitiveTypes {
pub const fn get_type(&self) -> Type<'a> {
match self {
Self::U8(_) => PrimitiveTypes::U8,
Self::U16(_) => PrimitiveTypes::U16,
Self::U32(_) => PrimitiveTypes::U32,
Self::U64(_) => PrimitiveTypes::U64,
Self::I8(_) => PrimitiveTypes::I8,
Self::I16(_) => PrimitiveTypes::I16,
Self::I32(_) => PrimitiveTypes::I32,
Self::I64(_) => PrimitiveTypes::I64,
Self::F32(_) => PrimitiveTypes::F32,
Self::F64(_) => PrimitiveTypes::F64,
Self::Char(_) => PrimitiveTypes::Char,
Self::Bool(_) => PrimitiveTypes::Bool,
Self::String(_) => PrimitiveTypes::String,
Self::Ptr => PrimitiveTypes::Ptr,
Self::None => PrimitiveTypes::None,
Self::U8(_) => Type::Primitive(PrimitiveTypes::U8),
Self::U16(_) => Type::Primitive(PrimitiveTypes::U16),
Self::U32(_) => Type::Primitive(PrimitiveTypes::U32),
Self::U64(_) => Type::Primitive(PrimitiveTypes::U64),
Self::I8(_) => Type::Primitive(PrimitiveTypes::I8),
Self::I16(_) => Type::Primitive(PrimitiveTypes::I16),
Self::I32(_) => Type::Primitive(PrimitiveTypes::I32),
Self::I64(_) => Type::Primitive(PrimitiveTypes::I64),
Self::F32(_) => Type::Primitive(PrimitiveTypes::F32),
Self::F64(_) => Type::Primitive(PrimitiveTypes::F64),
Self::Char(_) => Type::Primitive(PrimitiveTypes::Char),
Self::Bool(_) => Type::Primitive(PrimitiveTypes::Bool),
Self::String(_) => Type::Primitive(PrimitiveTypes::String),
Self::Ptr => Type::Primitive(PrimitiveTypes::Ptr),
Self::None => Type::Primitive(PrimitiveTypes::None),
}
}
}
Expand Down
22 changes: 11 additions & 11 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,17 @@ impl<'a, 'ctx> Codegen for Compiler<'a, 'ctx> {
todo!()
}

fn let_binding(&mut self, _let_decl: &Value, _expr_result: &ExpressionResult) {
fn let_binding(&mut self, _let_decl: &Value, _expr_result: &ExpressionResult<'a>) {
todo!()
}
fn binding(&mut self, _val: &Value, _expr_result: &ExpressionResult) {
fn binding(&mut self, _val: &Value, _expr_result: &ExpressionResult<'a>) {
todo!()
}

fn call(
&self,
_call: &ast::FunctionCall<'_>,
_params: Vec<ExpressionResult>,
_params: Vec<ExpressionResult<'a>>,
_register_number: u64,
) {
todo!()
Expand All @@ -172,25 +172,25 @@ impl<'a, 'ctx> Codegen for Compiler<'a, 'ctx> {
fn expression_operation(
&self,
_operation: &ast::ExpressionOperations,
_left_value: &ExpressionResult,
_right_value: &ExpressionResult,
_left_value: &ExpressionResult<'a>,
_right_value: &ExpressionResult<'a>,
_register_number: u64,
) {
todo!()
}

fn expression_function_return(&self, _expr_result: &ExpressionResult) {
fn expression_function_return(&self, _expr_result: &ExpressionResult<'a>) {
todo!()
}
fn jump_function_return(&self, _expr_result: &ExpressionResult) {
fn jump_function_return(&self, _expr_result: &ExpressionResult<'a>) {
todo!()
}
fn expression_function_return_with_label(&self, _expr_result: &ExpressionResult) {
fn expression_function_return_with_label(&self, _expr_result: &ExpressionResult<'a>) {
todo!()
}
fn if_condition_expression(
&mut self,
_expr_result: &ExpressionResult,
_expr_result: &ExpressionResult<'a>,
_label_if_begin: &LabelName,
_label_if_end: &LabelName,
) {
Expand All @@ -212,8 +212,8 @@ impl<'a, 'ctx> Codegen for Compiler<'a, 'ctx> {
}
fn condition_expression(
&mut self,
_left_result: &ExpressionResult,
_right_result: &ExpressionResult,
_left_result: &ExpressionResult<'a>,
_right_result: &ExpressionResult<'a>,
_condition: &Condition,
_register_number: u64,
) {
Expand Down
22 changes: 11 additions & 11 deletions src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@ pub trait Codegen {
fn constant(&self, const_decl: &ast::Constant<'_>);
fn types(&self, type_decl: &ast::StructTypes<'_>);
fn function_statement(&mut self, fn_decl: &ast::FunctionStatement<'_>);
fn let_binding(&mut self, let_decl: &Value, expr_result: &ExpressionResult);
fn binding(&mut self, val: &Value, expr_result: &ExpressionResult);
fn let_binding(&mut self, let_decl: &Value, expr_result: &ExpressionResult<'_>);
fn binding(&mut self, val: &Value, expr_result: &ExpressionResult<'_>);
fn call(
&self,
call: &ast::FunctionCall<'_>,
params: Vec<ExpressionResult>,
params: Vec<ExpressionResult<'_>>,
register_number: u64,
);
fn expression_value(&mut self, expression: &Value, register_number: u64);
fn expression_const(&self, expression: &semantic::Constant, register_number: u64);
fn expression_operation(
&self,
operation: &ast::ExpressionOperations,
left_value: &ExpressionResult,
right_value: &ExpressionResult,
left_value: &ExpressionResult<'_>,
right_value: &ExpressionResult<'_>,
register_number: u64,
);
fn expression_function_return(&self, expr_result: &ExpressionResult);
fn jump_function_return(&self, expr_result: &ExpressionResult);
fn expression_function_return(&self, expr_result: &ExpressionResult<'_>);
fn jump_function_return(&self, expr_result: &ExpressionResult<'_>);
fn set_label(&self, label: &LabelName);
fn expression_function_return_with_label(&self, expr_result: &ExpressionResult);
fn expression_function_return_with_label(&self, expr_result: &ExpressionResult<'_>);
fn condition_expression(
&mut self,
left_result: &ExpressionResult,
right_result: &ExpressionResult,
left_result: &ExpressionResult<'_>,
right_result: &ExpressionResult<'_>,
condition: &Condition,
register_number: u64,
);
Expand All @@ -45,7 +45,7 @@ pub trait Codegen {
);
fn if_condition_expression(
&mut self,
expr_result: &ExpressionResult,
expr_result: &ExpressionResult<'_>,
label_if_begin: &LabelName,
label_if_end: &LabelName,
);
Expand Down
97 changes: 69 additions & 28 deletions src/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
//!
//! Codegen is result of Semantic analyzer and contains prepared data tree
//! of generated code for next step - compilation generated raw program code.
use crate::ast::{self, ExpressionOperations, GetName, PrimitiveValue};
use crate::ast::{self, GetName};
use crate::codegen::Codegen;
use crate::semantic::error::StateErrorResult;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
Expand Down Expand Up @@ -344,20 +345,32 @@ pub struct GlobalState {
/// # State
/// Basic entity that contains `Global State`
/// and `Codegen` tree.
/// - errors - State analyzing errors
#[derive(Debug)]
pub struct State<T: Codegen> {
pub global: GlobalState,
pub codegen: T,
pub errors: Vec<StateErrorResult>,
}

/// # Expression Result
/// Result of expression analyze has to kind:
/// # Expression result
/// Contains analyzing results of expression:
/// - expr_type - result type of expression
/// - expr_value - result value of expression
#[derive(Debug, Clone)]
pub struct ExpressionResult<'a> {
pub expr_type: ast::Type<'a>,
pub expr_value: ExpressionResultValue,
}

/// # Expression Result Value
/// Result value of expression analyze has to kind:
/// - Primitive value
/// - Register that contain result of expression
/// evaluation or call.
#[derive(Debug)]
pub enum ExpressionResult {
PrimitiveValue(PrimitiveValue),
#[derive(Debug, Clone)]
pub enum ExpressionResultValue {
PrimitiveValue(ast::PrimitiveValue),
Register(u64),
}

Expand All @@ -371,9 +384,14 @@ impl<T: Codegen<Backend = T>> State<T> {
constants: HashMap::new(),
},
codegen,
errors: Vec::new(),
}
}

fn add_error(&mut self, err: StateErrorResult) {
self.errors.push(err);
}

/// Run semantic analyzer that covers all flow
pub fn run(&mut self, data: &ast::Main<'_>) -> StateResults<()> {
// Execute each kind of analyzing and return errors data.
Expand Down Expand Up @@ -696,7 +714,7 @@ impl<T: Codegen<Backend = T>> State<T> {
));
}
// Analyse function parameters expressions and set result to array
let mut params: Vec<ExpressionResult> = vec![];
let mut params: Vec<ExpressionResult<'_>> = vec![];
for expr in &data.parameters {
params.push(self.expression(expr, body_state)?);
}
Expand Down Expand Up @@ -1187,7 +1205,7 @@ impl<T: Codegen<Backend = T>> State<T> {
&mut self,
data: &ast::Expression<'_>,
body_state: &Rc<RefCell<BlockState>>,
) -> StateResult<ExpressionResult> {
) -> ExpressionResult<'_> {
// To analyze expression first time, we set:
// left_value - as None
// operation - as None
Expand All @@ -1199,14 +1217,18 @@ impl<T: Codegen<Backend = T>> State<T> {

/// Expression operation semantic logic:
/// `OP(lhs, rhs)`
/// Left-value contains optional Exrpression result for left side
/// of expression.
pub fn expression_operation(
&mut self,
left_value: Option<&ExpressionResult>,
left_value: Option<&ExpressionResult<'_>>,
right_expression: &ast::Expression<'_>,
op: Option<&ExpressionOperations>,
op: Option<&ast::ExpressionOperations>,
body_state: &Rc<RefCell<BlockState>>,
) -> StateResult<ExpressionResult> {
// Get right value from expression.
) -> ExpressionResult<'_> {
let y = x;
let z = y + 1;
// Get right side value from expression.
// If expression return error immediately return error
// because next analyzer should use success result.
let right_value = match &right_expression.expression_value {
Expand All @@ -1221,34 +1243,43 @@ impl<T: Codegen<Backend = T>> State<T> {
// Increase register counter before loading value
body_state.borrow_mut().inc_register();
// First check value in body state
if let Some(val) = value_from_state {
let ty = if let Some(val) = value_from_state {
// If it's value then Load it to register
self.codegen
.expression_value(&val, body_state.borrow().last_register_number);
&val.inner_type
} else if let Some(const_val) = self.global.constants.get(&value.name().into())
{
// If value is constant load it to register
self.codegen
.expression_const(const_val, body_state.borrow().last_register_number);
}
&const_val.inner_type
};
// Return result as register
Ok(ExpressionResult::Register(
body_state.borrow().last_register_number,
))
ExpressionResult {
expr_type: val_ty,
expr_value: ExpressionResultValue::Register(
body_state.borrow().last_register_number,
),
}
} else {
// If value doesn't exist
Err(error::StateErrorResult::new(
self.add_error(StateErrorResult::new(
error::StateErrorKind::ValueNotFound,
value.name(),
0,
0,
))
));
return;
}
}
// Check is expression primitive value
ast::ExpressionValue::PrimitiveValue(value) => {
// Just return primitive value itself
Ok(ExpressionResult::PrimitiveValue(value.clone()))
ExpressionResult {
expr_type: value.get_type(),
expr_value: ExpressionResult::PrimitiveValue(value.clone()),
}
}
// Check is expression Function call entity
ast::ExpressionValue::FunctionCall(fn_call) => {
Expand All @@ -1257,8 +1288,12 @@ impl<T: Codegen<Backend = T>> State<T> {
// And result of function always stored in register.
let call_result = self.function_call(fn_call, body_state);
// Return result as register
call_result
.map(|_| ExpressionResult::Register(body_state.borrow().last_register_number))
ExpressionResult {
expr_type: 1,
expr_value: ExpressionResultValue::Register(
body_state.borrow().last_register_number,
),
}
}
ast::ExpressionValue::StructValue(_value) => {
todo!()
Expand All @@ -1267,27 +1302,33 @@ impl<T: Codegen<Backend = T>> State<T> {
// It's special case for "pure" expression - without operation.
// For that check also left side of expression shouldn't exist
if left_value.is_none() || op.is_none() {
return Ok(right_value);
return right_value;
}
let left_value = left_value.unwrap();
if left_value.expr_type != right_value.expr_type {
self.add_error()
}
// Call expression operation for: OP(left_value, right_value)
// and return result of that call as register
body_state.borrow_mut().inc_register();
self.codegen.expression_operation(
op.unwrap(),
left_value.unwrap(),
left_value,
&right_value,
body_state.borrow().last_register_number,
);
let expression_result =
ExpressionResult::Register(body_state.borrow().last_register_number);
let expression_result = ExpressionResult {
expr_type: right_value.expr_type,
expr_value: ExpressionResultValue::Register(body_state.borrow().last_register_number),
};

// Check is for right value exist next operation
// Check is for right value contain next operation
if let Some((operation, expr)) = &right_expression.operation {
// Recursively call, where current Execution result set as left
// side expression
self.expression_operation(Some(&expression_result), expr, Some(operation), body_state)
} else {
Ok(expression_result)
expression_result
}
}
}
Expand Down

0 comments on commit 3b57984

Please sign in to comment.