Skip to content

Commit

Permalink
Functiond declaration type checking. let-binding, binding
Browse files Browse the repository at this point in the history
  • Loading branch information
mrLSD committed Aug 7, 2023
1 parent a7fb351 commit 0a55272
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 19 deletions.
60 changes: 41 additions & 19 deletions src/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use crate::ast::{self, GetLocation, GetName, MAX_PRIORITY_LEVEL_FOR_EXPRESSIONS}
use crate::codegen::Codegen;
use crate::types::error::{self, EmptyError};
use crate::types::{
Constant, ConstantName, Expression, ExpressionResult, ExpressionResultValue, Function,
FunctionName, FunctionStatement, InnerValueName, LabelName, StateResult, Type, TypeName, Value,
ValueName,
Binding, Constant, ConstantName, Expression, ExpressionResult, ExpressionResultValue, Function,
FunctionCall, FunctionName, FunctionStatement, InnerValueName, LabelName, LetBinding,
StateResult, Type, TypeName, Value, ValueName,
};
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
Expand Down Expand Up @@ -422,7 +422,13 @@ impl<T: Codegen> State<T> {
// Check expression type
let _ = self.check_type_exists(&res.expr_type, &expr, &expression.clone());
let fn_ty: Type = data.result_type.clone().into();
if fn_ty != res.expr_type {}
if fn_ty != res.expr_type {
self.add_error(error::StateErrorResult::new(
error::StateErrorKind::WrongReturnType,
expr.to_string(),
expression.location(),
));
}

return_is_called = true;
// Check is state contain flag of manual
Expand All @@ -441,8 +447,19 @@ impl<T: Codegen> State<T> {
});
}
ast::BodyStatement::Return(expression) => {
let expr_result = self.expression(expression, &body_state);
let _ = expr_result.map(|res| {
let _ = self.expression(expression, &body_state).map(|res| {
let expr: Expression = expression.clone().into();
// Check expression type
let _ = self.check_type_exists(&res.expr_type, &expr, &expression.clone());
let fn_ty: Type = data.result_type.clone().into();
if fn_ty != res.expr_type {
self.add_error(error::StateErrorResult::new(
error::StateErrorKind::WrongReturnType,
expr.to_string(),
expression.location(),
));
}

return_is_called = true;
// Check is state contain flag of manual
// return from other states, for example:
Expand Down Expand Up @@ -490,27 +507,30 @@ impl<T: Codegen> State<T> {
) -> Result<(), EmptyError> {
// Call value analytics before putting let-value to state
let expr_result = self.expression(&data.value, state)?;
let let_data: LetBinding = data.clone().into();

if let Some(ty) = data.clone().value_type {
if expr_result.expr_type != ty.into() {
if let Some(ty) = &let_data.value_type {
if &expr_result.expr_type != ty {
self.add_error(error::StateErrorResult::new(
error::StateErrorKind::WrongLetType,
data.name(),
let_data.to_string(),
data.location(),
));
return Err(EmptyError);
}
}
let let_ty = expr_result.clone().expr_type;
let let_ty = expr_result.expr_type.clone();

// Find value in current state and parent states
let value = state.borrow().get_value_name(&data.name().into());
let value = state.borrow().get_value_name(&let_data.name);
// Calculate `inner_name` as unique for current and all parent states
let inner_name = value.map_or_else(
|| {
// if value not found in all states check and set
// `inner_value` from value name
state.borrow().get_next_inner_name(&data.name().into())
state
.borrow()
.get_next_inner_name(&let_data.name.clone().into())
},
|val| {
// Increment inner value name counter for shadowed variable
Expand All @@ -522,15 +542,15 @@ impl<T: Codegen> State<T> {
let value = Value {
inner_name: inner_name.clone(),
inner_type: let_ty,
mutable: data.mutable,
mutable: let_data.mutable,
alloca: false,
malloc: false,
};
// Value inserted only to current state by Value name and Value data
state
.borrow_mut()
.values
.insert(data.name().into(), value.clone());
.insert(let_data.name, value.clone());
// Set `inner_name` to current state and all parent states
state.borrow_mut().set_inner_value_name(&inner_name);

Expand All @@ -552,15 +572,16 @@ impl<T: Codegen> State<T> {
) -> Result<(), EmptyError> {
// Call value analytics before putting let-value to state
let expr_result = self.expression(&data.value, state)?;
let bind_data: Binding = data.clone().into();

// Find value in current state and parent states
let value = state
.borrow()
.get_value_name(&data.name().into())
.get_value_name(&bind_data.name)
.ok_or_else(|| {
self.add_error(error::StateErrorResult::new(
error::StateErrorKind::ValueNotFound,
data.name(),
bind_data.to_string(),
data.location(),
));
EmptyError
Expand All @@ -569,7 +590,7 @@ impl<T: Codegen> State<T> {
if !value.mutable {
self.add_error(error::StateErrorResult::new(
error::StateErrorKind::ValueIsNotMutable,
data.name(),
bind_data.to_string(),
data.location(),
));
return Err(EmptyError);
Expand All @@ -596,11 +617,12 @@ impl<T: Codegen> State<T> {
data: &ast::FunctionCall<'_>,
body_state: &Rc<RefCell<BlockState>>,
) -> Result<Type, EmptyError> {
let func_call_data: FunctionCall = data.clone().into();
// Check is function exists in global functions stat
let Some(func_data) = self.global.functions.get(&data.name().into()).cloned() else {
let Some(func_data) = self.global.functions.get(&func_call_data.name).cloned() else {
self.add_error(error::StateErrorResult::new(
error::StateErrorKind::FunctionNotFound,
data.name(),
func_call_data.to_string(),
data.location()
));
return Err(EmptyError);
Expand Down
19 changes: 19 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ impl ToString for ValueName {
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub struct InnerValueName(String);

impl From<ValueName> for InnerValueName {
fn from(value: ValueName) -> Self {
Self(value.0)
}
}

impl From<String> for InnerValueName {
fn from(value: String) -> Self {
Self(value)
Expand Down Expand Up @@ -624,6 +630,12 @@ pub struct LetBinding {
pub value: Box<Expression>,
}

impl ToString for LetBinding {
fn to_string(&self) -> String {
self.name.to_string()
}
}

impl From<ast::LetBinding<'_>> for LetBinding {
fn from(value: ast::LetBinding<'_>) -> Self {
Self {
Expand Down Expand Up @@ -807,6 +819,12 @@ pub struct Binding {
pub value: Box<Expression>,
}

impl ToString for Binding {
fn to_string(&self) -> String {
self.name.to_string()
}
}

impl From<ast::Binding<'_>> for Binding {
fn from(value: ast::Binding<'_>) -> Self {
Self {
Expand Down Expand Up @@ -995,6 +1013,7 @@ pub mod error {
ReturnNotFound,
IfElseDuplicated,
TypeNotFound,
WrongReturnType,
}

#[derive(Debug, Clone)]
Expand Down

0 comments on commit 0a55272

Please sign in to comment.