Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A11 Feature: Create type constraints to the operators #14

Merged
merged 1 commit into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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::*;