Skip to content

Commit

Permalink
Added variables support
Browse files Browse the repository at this point in the history
  • Loading branch information
mauro-balades committed Apr 28, 2023
1 parent e3acea3 commit 80e04db
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 15 deletions.
3 changes: 2 additions & 1 deletion src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ impl AST {
pub enum Node {
Task(String, Vec<Node>),
DefaultTask(String),
Command(Expr)
Command(Expr),
VariableDecl(String, Expr),
}

#[derive(Debug, Clone)]
Expand Down
10 changes: 8 additions & 2 deletions src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::project::ProjectInfo;
grammar;

RootNodes: Node = {
Task, DefaultTask
Task, DefaultTask, VariableDecl
}

RootHeader: ProjectInfo = {
Expand All @@ -21,6 +21,10 @@ Statement: Node = {
Command,
}

VariableDecl: Node = {
"set" <name:variable> <e:Expr> => Node::VariableDecl(name, e)
}

Block: Vec<Node> = {
Statement*
}
Expand Down Expand Up @@ -53,4 +57,6 @@ string: String = r#"".*""# => {
chars.next_back();
chars.as_str().to_string()
};
pub ident: String = r"[a-zA-Z][a-zA-Z0-9_-]*" => <>.to_string();

pub ident: String = r"[a-zA-Z][a-zA-Z0-9_-]*" => <>.to_string();
pub variable: String = r"\$[a-zA-Z][a-zA-Z0-9_-]*" => <>.to_string();
51 changes: 39 additions & 12 deletions src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ impl Runner {
}
}

pub fn execute_ast(&mut self) {
let nodes = &self.ast.nodes;
pub fn execute_ast(&mut self) -> Result<(), &'static str> {

let mut defaultTask: String = "".to_string();
for node in nodes {
let mut clone = self.clone();
for node in &mut self.ast.nodes {
match node {
Node::Task(ref name, _) => {
if self.tasks.contains_key(name) {
Expand All @@ -59,6 +59,11 @@ impl Runner {

defaultTask = name.to_string();
},

Node::VariableDecl(ref n, ref e) => {
let expr = clone.execute_expr(e).unwrap();
clone.generate_variable(n.to_string(), &expr);
},

_ => panic!("what")
}
Expand All @@ -77,26 +82,41 @@ impl Runner {
}

let executed_task = self.tasks.get(&self.method).unwrap();
self.clone().execute_task(executed_task);
clone.execute_task(executed_task);

Ok(())
}

fn generate_variable(&mut self, n: String, e: &String) {
let mut scope = &mut self.scopes[0];
let mut name = n.clone().to_string();
name.remove(0);

if scope.contains_key(&n) {
Self::throw_error(format!("Variable with name '{}' has already been defined on the same scope!", n));
}

scope.insert(name, e.to_string());
println!("{:?}", self.scopes);
}

fn get_variable(&self, var: String) -> String {
let mut value: Option<String> = Option::None;
for scope in &self.scopes {
if (scope.contains_key(&var)) {
if scope.contains_key(&var) {
value = scope.get(&var).cloned();
}
}


if value.is_none() {
println!("{:?}", self.scopes);
Self::throw_error(format!("No variable with name '{}' has been found!", var));
}

value.unwrap()
}

fn execute_expr(&self, expr: &Expr) -> String {
fn execute_expr(&mut self, expr: &Expr) -> Result<String, &'static str> {
match expr {
Expr::String(s) => {
// STRING_IDENTIFIER_REGEX.
Expand All @@ -112,15 +132,14 @@ impl Runner {
self.get_variable(matched_word.to_string())
});

println!("s: {}", output);
output.to_string()
Ok(output.to_string())
},

_ => panic!("Invalid expression given!")
}
}

fn execute_block(&mut self, block: &Vec<Node>) {
fn execute_block(&mut self, block: &Vec<Node>) -> Result<(), &'static str> {
self.scopes.insert(0, HashMap::new());

for node in block {
Expand All @@ -129,22 +148,30 @@ impl Runner {
let val = self.execute_expr(expr);
},

Node::VariableDecl(ref n, ref e) => {
let expr = self.execute_expr(e).unwrap();
self.generate_variable(n.to_string(), &expr);
},

_ => panic!("Invalid node parsed!")
}
}

self.scopes.remove(0);
Ok(())
}

fn execute_task(mut self, executed_task: &Node) {
fn execute_task(mut self, executed_task: &Node) -> Result<(), &'static str> {
match executed_task {
// It should only be this task
Node::Task(ref name, ref nodes) => {
self.execute_block(nodes)
self.execute_block(nodes).unwrap()
},

_ => panic!("Invalid task given!")
}

Ok(())
}

}
1 change: 1 addition & 0 deletions test/project.breeze
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
project test version "0.0.1";

set $balls "hello"
task build {
exec "awdd ${balls}"
}
Expand Down

0 comments on commit 80e04db

Please sign in to comment.