Skip to content

Commit

Permalink
Merge pull request #50 from Ph0enixKM/A59
Browse files Browse the repository at this point in the history
A59 Add range
  • Loading branch information
Ph0enixKM committed Dec 22, 2022
2 parents d28a628 + 50d1659 commit 1cc5654
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/modules/expression/binop/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl SyntaxModule<ParserMetadata> for Add {
syntax(meta, &mut *self.right)?;
let l_type = self.left.get_type();
let r_type = self.right.get_type();
let message = format!("Cannot add value of type '{}' with value of type '{}'", self.left.get_type(), self.right.get_type());
let message = format!("Cannot add value of type '{l_type}' with value of type '{r_type}'");
let predicate = |kind| matches!(kind, Type::Num | Type::Text | Type::Array(_));
self.kind = expression_arms_of_type(meta, &l_type, &r_type, predicate, tok, &message)?;
Ok(())
Expand Down
1 change: 0 additions & 1 deletion src/modules/expression/binop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pub fn parse_left_expr(meta: &mut ParserMetadata, module: &mut Expr, op: &str) -
meta.binop_border = Some(new_border);
// Parse the left expression
if let Err(err) = syntax(meta, module) {
dbg!("ERR");
// Revert border back to the original
meta.binop_border = old_border;
return Err(err)
Expand Down
8 changes: 5 additions & 3 deletions src/modules/expression/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use super::literal::{
bool::Bool,
number::Number,
text::Text,
array::Array
array::Array,
range::Range
};
use super::binop::{
add::Add,
Expand Down Expand Up @@ -57,7 +58,8 @@ pub enum ExprType {
Not(Not),
Ternary(Ternary),
FunctionInvocation(FunctionInvocation),
Array(Array)
Array(Array),
Range(Range)
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -99,7 +101,7 @@ impl Expr {
// Arithmetic operators
Add, Sub, Mul, Div, Modulo,
// Literals
Parenthesis, CommandExpr, Bool, Number, Text, Array,
Range, Parenthesis, CommandExpr, Bool, Number, Text, Array,
// Function invocation
FunctionInvocation,
// Variable access
Expand Down
1 change: 1 addition & 0 deletions src/modules/expression/literal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod number;
pub mod text;
pub mod null;
pub mod array;
pub mod range;

pub fn parse_interpolated_region(meta: &mut ParserMetadata, letter: char) -> Result<(Vec<String>, Vec<Expr>), Failure> {
let mut strings = vec![];
Expand Down
56 changes: 56 additions & 0 deletions src/modules/expression/literal/range.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use heraclitus_compiler::prelude::*;
use crate::{utils::metadata::ParserMetadata, modules::{types::{Type, Typed}, expression::{expr::Expr, binop::{parse_left_expr, expression_arms_of_type}}}, translate::compute::{translate_computation, ArithOp}};
use crate::translate::module::TranslateModule;
use crate::utils::TranslateMetadata;

#[derive(Debug, Clone)]
pub struct Range {
from: Box<Expr>,
to: Box<Expr>,
neq: bool
}

impl Typed for Range {
fn get_type(&self) -> Type {
Type::Array(Box::new(Type::Num))
}
}

impl SyntaxModule<ParserMetadata> for Range {
syntax_name!("Range");

fn new() -> Self {
Range {
from: Box::new(Expr::new()),
to: Box::new(Expr::new()),
neq: false
}
}

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
parse_left_expr(meta, self.from.as_mut(), "..")?;
let tok = meta.get_current_token();
token(meta, "..")?;
token(meta, "=").is_err().then(|| self.neq = true);
syntax(meta, self.to.as_mut())?;
let l_type = self.from.get_type();
let r_type = self.to.get_type();
let message = format!("Cannot create a range starting from value of type '{l_type}' up until value of type '{r_type}'");
let predicate = |kind| matches!(kind, Type::Num);
expression_arms_of_type(meta, &l_type, &r_type, predicate, tok, &message)?;
Ok(())
}
}

impl TranslateModule for Range {
fn translate(&self, meta: &mut TranslateMetadata) -> String {
let from = self.from.translate(meta);
let to = self.to.translate(meta);
if self.neq {
let to_neq = translate_computation(meta, ArithOp::Sub, Some(to), Some("1".to_string()));
format!("$(seq {} {})", from, to_neq)
} else {
format!("$(seq {} {})", from, to)
}
}
}
5 changes: 4 additions & 1 deletion src/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@ use heraclitus_compiler::prelude::*;
pub fn get_rules() -> Rules {
let symbols = vec![
'+', '-', '*', '/', '%', '\n', ';', ':',
'(', ')', '[', ']', '{', '}', ','
'(', ')', '[', ']', '{', '}', ',', '.',
'<', '>', '='
];
let compounds = vec![
('<', '='),
('>', '='),
('=', '>'),
('!', '='),
('=', '='),
('+', '='),
('-', '='),
('*', '='),
('/', '='),
('%', '='),
('.', '.')
];
let region = reg![
reg!(string as "string literal" => {
Expand Down
20 changes: 20 additions & 0 deletions src/tests/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,3 +608,23 @@ fn loop_in_index_value() {
";
test_amber!(code, "0\n1\n1\n2\n2\n3\n3\n4\n4\n5");
}

#[test]
fn range_loop() {
let code = "
loop i in 0..5 {
echo i
}
";
test_amber!(code, "0\n1\n2\n3\n4");
}

#[test]
fn range_loop_inclusive() {
let code = "
loop i in 0..=5 {
echo i
}
";
test_amber!(code, "0\n1\n2\n3\n4\n5");
}

0 comments on commit 1cc5654

Please sign in to comment.