Skip to content

Commit

Permalink
Merge pull request #13 from Ph0enixKM/A14
Browse files Browse the repository at this point in the history
A14 Feature: Add Command
  • Loading branch information
Ph0enixKM committed Aug 8, 2022
2 parents e8d7079 + c29bc8f commit dd7a742
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 50 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![
"'interpolate {'this {1} this'} and {'that'} :)'"
"$echo test$"
].join("\n");
let rules = rules::get_rules();
let mut cc = Compiler::new("Amber", rules);
Expand Down
6 changes: 5 additions & 1 deletion src/modules/expression/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::utils::metadata::ParserMetadata;
use super::literal::{
bool::Bool,
number::Number,
text::Text
text::Text,
command::Command
};
use super::binop::{
add::Add,
Expand All @@ -31,6 +32,7 @@ pub enum ExprType {
Bool(Bool),
Number(Number),
Text(Text),
Command(Command),
Parenthesis(Parenthesis),
VariableGet(VariableGet),
Add(Add),
Expand Down Expand Up @@ -82,6 +84,7 @@ impl Expr {
// Literals
ExprType::VariableGet(VariableGet::new()),
ExprType::Parenthesis(Parenthesis::new()),
ExprType::Command(Command::new()),
ExprType::Bool(Bool::new()),
ExprType::Number(Number::new()),
ExprType::Text(Text::new())
Expand All @@ -108,6 +111,7 @@ impl Expr {
ExprType::Div(ex) => self.get(meta, ex, ExprType::Div),
// Literals
ExprType::Parenthesis(ex) => self.get(meta, ex, ExprType::Parenthesis),
ExprType::Command(ex) => self.get(meta, ex, ExprType::Command),
ExprType::Bool(ex) => self.get(meta, ex, ExprType::Bool),
ExprType::Number(ex) => self.get(meta, ex, ExprType::Number),
ExprType::Text(ex) => self.get(meta, ex, ExprType::Text),
Expand Down
33 changes: 33 additions & 0 deletions src/modules/expression/literal/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use heraclitus_compiler::prelude::*;
use crate::{utils::metadata::ParserMetadata, modules::{Type, Typed}};
use crate::modules::expression::expr::Expr;

use super::parse_interpolated_region;

#[derive(Debug)]
pub struct Command {
strings: Vec<String>,
interps: Vec<Expr>
}

impl Typed for Command {
fn get_type(&self) -> Type {
Type::Text
}
}

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

fn new() -> Self {
Command {
strings: vec![],
interps: vec![]
}
}

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
(self.strings, self.interps) = parse_interpolated_region(meta, '$')?;
Ok(())
}
}
51 changes: 50 additions & 1 deletion src/modules/expression/literal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,53 @@
use std::vec;

use heraclitus_compiler::prelude::*;
use crate::utils::metadata::ParserMetadata;
use crate::modules::expression::expr::Expr;

pub mod bool;
pub mod number;
pub mod text;
pub mod void;
pub mod void;
pub mod command;

pub fn parse_interpolated_region(meta: &mut ParserMetadata, letter: char) -> Result<(Vec<String>, Vec<Expr>), ErrorDetails> {
let mut strings = vec![];
let mut interps = vec![];
// Handle full string
if let Ok(word) = token_by(meta, |word| word.starts_with(letter) && word.ends_with(letter) && word.len() > 1) {
let stripped = word.chars().take(word.len() - 1).skip(1).collect::<String>();
strings.push(stripped);
Ok((strings, interps))
}
else {
let mut is_interp = false;
// Initialize string
strings.push(token_by(meta, |word| word.starts_with(letter))?);
// Factor rest of the interpolation
while let Some(token) = meta.get_current_token() {
// Track interpolations
match token.word.as_str() {
"{" => is_interp = true,
"}" => is_interp = false,
// Manage inserting strings and intrpolations
_ => if is_interp {
let mut expr = Expr::new();
syntax(meta, &mut expr)?;
interps.push(expr);
// TODO: [H50] In the next release of Heraclitus
// Change this line to `meta.offset_index(-1)`
meta.set_index(meta.get_index() - 1);
}
else {
strings.push(token.word.clone());
if token.word.ends_with(letter) {
meta.increment_index();
return Ok((strings, interps))
}
}
}
meta.increment_index();
}
Err(ErrorDetails::from_metadata(meta))
}
}
50 changes: 3 additions & 47 deletions src/modules/expression/literal/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,14 @@ use heraclitus_compiler::prelude::*;
use crate::{utils::metadata::ParserMetadata, modules::{Type, Typed}};
use crate::modules::expression::expr::Expr;

use super::parse_interpolated_region;

#[derive(Debug)]
pub struct Text {
strings: Vec<String>,
interps: Vec<Expr>
}

impl Text {
fn closure_full_string(word: &String) -> bool {
word.starts_with('\'') && word.ends_with('\'') && word.len() > 1
}

fn parse_text(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
// Handle full string
if let Ok(word) = token_by(meta, Text::closure_full_string) {
let stripped = word.chars().take(word.len() - 1).skip(1).collect::<String>();
self.strings.push(stripped);
Ok(())
}
else {
let mut is_interp = false;
// Initialize string
self.strings.push(token_by(meta, |word| word.starts_with('\''))?);
// Factor rest of the interpolation
while let Some(token) = meta.get_current_token() {
// Track interpolations
match token.word.as_str() {
"{" => is_interp = true,
"}" => is_interp = false,
// Manage inserting strings and intrpolations
_ => if is_interp {
let mut expr = Expr::new();
syntax(meta, &mut expr)?;
self.interps.push(expr);
// TODO: [H50] In the next release of Heraclitus
// Change this line to `meta.offset_index(-1)`
meta.set_index(meta.get_index() - 1);
}
else {
self.strings.push(token.word.clone());
if token.word.ends_with('\'') {
meta.increment_index();
return Ok(())
}
}
}
meta.increment_index();
}
Err(ErrorDetails::from_metadata(meta))
}
}
}

impl Typed for Text {
fn get_type(&self) -> Type {
Type::Text
Expand All @@ -71,7 +27,7 @@ impl SyntaxModule<ParserMetadata> for Text {
}

fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult {
self.parse_text(meta)?;
(self.strings, self.interps) = parse_interpolated_region(meta, '\'')?;
Ok(())
}
}

0 comments on commit dd7a742

Please sign in to comment.