Skip to content

Commit

Permalink
Merge pull request #14 from Ph0enixKM/A11
Browse files Browse the repository at this point in the history
A11 Feature: Create type constraints to the operators
  • Loading branch information
Ph0enixKM committed Aug 8, 2022
2 parents dd7a742 + d409105 commit fa2b195
Show file tree
Hide file tree
Showing 21 changed files with 85 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::utils::metadata::ParserMetadata;

fn main() {
let code = vec![
"$echo test$"
"12 + 1"
].join("\n");
let rules = rules::get_rules();
let mut cc = Compiler::new("Amber", rules);
Expand Down
10 changes: 7 additions & 3 deletions src/modules/expression/binop/add.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use crate::utils::{metadata::ParserMetadata, error::get_error_logger};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -23,14 +23,18 @@ impl SyntaxModule<ParserMetadata> for Add {
Add {
left: Box::new(Expr::new()),
right: Box::new(Expr::new()),
kind: Type::Void
kind: Type::Num
}
}

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "+")?;
let tok = meta.get_current_token();
token(meta, "+")?;
syntax(meta, &mut *self.right)?;
// If left and right are not of type Number
let error = "Add operation can only add numbers";
expression_arms_of_type(meta, &self.left, &self.right, Type::Num, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/and.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};


Expand Down Expand Up @@ -28,8 +28,11 @@ impl SyntaxModule<ParserMetadata> for And {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "and")?;
let tok = meta.get_current_token();
token(meta, "and")?;
syntax(meta, &mut *self.right)?;
let error = "Logical and operation can only be used on arguments of the same type";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/div.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type, expression_arms_of_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand Down Expand Up @@ -29,8 +29,11 @@ impl SyntaxModule<ParserMetadata> for Div {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "/")?;
let tok = meta.get_current_token();
token(meta, "/")?;
syntax(meta, &mut *self.right)?;
let error = "Divide operation can only divide numbers";
expression_arms_of_type(meta, &self.left, &self.right, Type::Num, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/eq.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -27,8 +27,11 @@ impl SyntaxModule<ParserMetadata> for Eq {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "==")?;
let tok = meta.get_current_token();
token(meta, "==")?;
syntax(meta, &mut *self.right)?;
let error = "Cannot compare two values of different types";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/ge.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -27,8 +27,11 @@ impl SyntaxModule<ParserMetadata> for Ge {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, ">=")?;
let tok = meta.get_current_token();
token(meta, ">=")?;
syntax(meta, &mut *self.right)?;
let error = "Cannot compare two values of different types";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/gt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -27,8 +27,11 @@ impl SyntaxModule<ParserMetadata> for Gt {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, ">")?;
let tok = meta.get_current_token();
token(meta, ">")?;
syntax(meta, &mut *self.right)?;
let error = "Cannot compare two values of different types";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/le.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -27,8 +27,11 @@ impl SyntaxModule<ParserMetadata> for Le {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "<=")?;
let tok = meta.get_current_token();
token(meta, "<=")?;
syntax(meta, &mut *self.right)?;
let error = "Cannot compare two values of different types";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/lt.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -27,8 +27,11 @@ impl SyntaxModule<ParserMetadata> for Lt {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "<")?;
let tok = meta.get_current_token();
token(meta, "<")?;
syntax(meta, &mut *self.right)?;
let error = "Cannot compare two values of different types";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
20 changes: 19 additions & 1 deletion src/modules/expression/binop/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use crate::{utils::{metadata::ParserMetadata, error::get_error_logger}, modules::{Type, Typed}};
use super::super::expression::expr::Expr;

pub mod add;
Expand All @@ -16,6 +16,24 @@ pub mod eq;
pub mod neq;


pub fn expression_arms_of_type(meta: &mut ParserMetadata, left: &Box<Expr>, right: &Box<Expr>, kind: Type, tok_pos: Option<Token>, message: &str) {
if ![left.get_type(), right.get_type()].iter().all(|item| *item == kind) {
get_error_logger(meta, ErrorDetails::from_token_option(tok_pos))
.attach_message(message)
.show()
.exit()
}
}

pub fn expression_arms_of_same_type(meta: &mut ParserMetadata, left: &Box<Expr>, right: &Box<Expr>, tok_pos: Option<Token>, message: &str) {
if left.get_type() != right.get_type() {
get_error_logger(meta, ErrorDetails::from_token_option(tok_pos))
.attach_message(message)
.show()
.exit()
}
}

pub fn parse_left_expr(meta: &mut ParserMetadata, module: &mut Expr, op: impl AsRef<str>) -> Result<usize, ErrorDetails> {
// Save left border and run binop left cut border check
let old_border = meta.binop_border;
Expand Down
5 changes: 4 additions & 1 deletion src/modules/expression/binop/mul.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand Down Expand Up @@ -29,8 +29,11 @@ impl SyntaxModule<ParserMetadata> for Mul {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "*")?;
let tok = meta.get_current_token();
token(meta, "*")?;
syntax(meta, &mut *self.right)?;
let error = "Multiply operation can only multiply numbers";
expression_arms_of_type(meta, &self.left, &self.right, Type::Num, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/neq.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -27,8 +27,11 @@ impl SyntaxModule<ParserMetadata> for Neq {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "!=")?;
let tok = meta.get_current_token();
token(meta, "!=")?;
syntax(meta, &mut *self.right)?;
let error = "Cannot compare two values of different types";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/or.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_same_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand All @@ -27,8 +27,11 @@ impl SyntaxModule<ParserMetadata> for Or {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "or")?;
let tok = meta.get_current_token();
token(meta, "or")?;
syntax(meta, &mut *self.right)?;
let error = "Logical or operation can only be used on arguments of the same type";
expression_arms_of_same_type(meta, &self.left, &self.right, tok, error);
Ok(())
}
}
5 changes: 4 additions & 1 deletion src/modules/expression/binop/sub.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use super::{super::expr::Expr, parse_left_expr};
use super::{super::expr::Expr, parse_left_expr, expression_arms_of_type};
use crate::modules::{Type, Typed};

#[derive(Debug)]
Expand Down Expand Up @@ -29,8 +29,11 @@ impl SyntaxModule<ParserMetadata> for Sub {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, &mut *self.left, "-")?;
let tok = meta.get_current_token();
token(meta, "-")?;
syntax(meta, &mut *self.right)?;
let error = "Substract operation can only substract numbers";
expression_arms_of_type(meta, &self.left, &self.right, Type::Num, tok, error);
Ok(())
}
}
3 changes: 2 additions & 1 deletion src/modules/expression/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,9 @@ impl Expr {
// Match syntax
match syntax(meta, &mut module) {
Ok(()) => {
self.kind = module.get_type();
self.value = Some(cb(module));
Ok(())
Ok(())
}
Err(details) => Err(details)
}
Expand Down
18 changes: 2 additions & 16 deletions src/modules/variable/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,6 @@ pub struct VariableInit {
expr: Box<Expr>
}

impl VariableInit {
fn handle_memory(&mut self, meta: &mut ParserMetadata, token: Option<Token>, kind: Type) {
if !meta.var_mem.add_variable(self.name.clone(), kind) {
let message = format!("Cannot overwrite existing variable '{}'", self.name);
let details = ErrorDetails::from_token_option(token);
get_error_logger(meta, details)
.attach_message(message)
.show()
.exit()
}
}
}

impl SyntaxModule<ParserMetadata> for VariableInit {
syntax_name!("Variable Initialize");

Expand All @@ -37,13 +24,12 @@ impl SyntaxModule<ParserMetadata> for VariableInit {

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
token(meta, "let")?;
// Save current token
let tok = meta.get_current_token();
// Get the variable name
self.name = variable(meta, variable_name_extensions())?;
token(meta, "=")?;
syntax(meta, &mut *self.expr)?;
self.handle_memory(meta, tok, self.expr.get_type());
// Add a variable to the memory
meta.var_mem.add_variable(self.name.clone(), self.expr.get_type());
Ok(())
}
}
3 changes: 3 additions & 0 deletions src/translate-module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub trait TranslateModule {

}
2 changes: 2 additions & 0 deletions src/utils/metadata/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod parser;
pub use parser::*;
2 changes: 1 addition & 1 deletion src/utils/metadata.rs → src/utils/metadata/parser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use heraclitus_compiler::prelude::*;
use super::variable_memory::VariableMemory;
use crate::utils::variable_memory::VariableMemory;

pub struct ParserMetadata {
pub expr: Vec<Token>,
Expand Down
2 changes: 2 additions & 0 deletions src/utils/metadata/translate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
struct TranslateMetadata {}

3 changes: 2 additions & 1 deletion src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod metadata;
pub mod variable_memory;
pub mod error;
pub mod error;
pub use metadata::*;

0 comments on commit fa2b195

Please sign in to comment.