Skip to content

Commit

Permalink
feat: scopes of visibility, delete variable
Browse files Browse the repository at this point in the history
now, after exiting the scope (loop, if), all the variables that were in it are deleted
  • Loading branch information
artegoser committed Aug 8, 2022
1 parent fdd7e2a commit 9da82cd
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 20 deletions.
1 change: 0 additions & 1 deletion examples/example.json5
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@
body: ["break"],
},
},

{
assign: {
num: { calc: [{ var: "num" }, "+", 1] },
Expand Down
91 changes: 72 additions & 19 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::types::*;
use colored::*;
use json5;
use serde_json::{json, Map, Value};
Expand All @@ -6,8 +7,9 @@ use std::io::{self, Write};
use std::{thread, time};
pub struct Interpreter {
input: String,
vars: HashMap<String, Value>,
vars: HashMap<String, Var>,
pos: usize,
scope: usize,
}

impl Interpreter {
Expand All @@ -16,6 +18,7 @@ impl Interpreter {
input,
vars: HashMap::new(),
pos: 1,
scope: 0,
}
}

Expand Down Expand Up @@ -112,6 +115,14 @@ impl Interpreter {
self.error("Unsupported data type for the `var` argument, must be a string");
}
},
"delete" => match value {
Value::String(value) => {
self.delete(value);
}
_ => {
self.error("Unsupported data type for the `delete` argument, must be a string");
}
},
"input" => match value {
Value::String(value) => {
return self.input(value);
Expand Down Expand Up @@ -273,26 +284,46 @@ impl Interpreter {
}

fn run_nodes(&mut self, arr: &Vec<Value>) -> String {
self.scope += 1;
for command in arr {
let to_do = self.eval_node(command);
match to_do {
Value::String(name) => return name,
_ => {}
}
}
self.delete_last_scope();
self.scope -= 1;
"end".to_string()
}

fn delete_last_scope(&mut self) {
let vars = self.vars.clone().into_iter();
for (k, v) in vars {
if v.scope == self.scope {
self.delete(&k);
}
}
}

fn define(&mut self, vars: &Map<String, Value>) {
for (name, value) in vars {
if !self.var_exists(&name) {
match value {
Value::Object(_) => {
let value = self.eval_node(value);
self.vars.insert(name.to_string(), value);
self.vars.insert(
name.to_string(),
Var {
scope: self.scope,
body: value,
},
);
}
_ => {
self.vars.insert(name.to_string(), value.clone());
self.vars.insert(
name.to_string(),
Var {
}
}
} else {
Expand All @@ -302,14 +333,33 @@ impl Interpreter {
}
}

fn delete(&mut self, var_name: &String) {}
fn delete(&mut self, var_name: &String) {
if self.var_exists(var_name) {
self.vars.remove(var_name);
} else {
self.error(&format!(
"The variable {} does not exist and cannot be deleted",
var_name
));
panic!();
}
}

fn get_var(&mut self, var_name: &String) {
fn get_var(&mut self, var_name: &String) -> Value {
let var = self.vars.get(var_name);
match var {
Some(var) => {
var.clone();
Some(var) => var.body.clone(),
None => {
self.error(&format!("The variable {} does not exist", var_name));
panic!();
}
}
}

fn get_var_scope(&mut self, var_name: &String) -> usize {
let var = self.vars.get(var_name);
match var {
Some(var) => var.scope,
None => {
self.error(&format!("The variable {} does not exist", var_name));
panic!();
Expand All @@ -319,19 +369,22 @@ impl Interpreter {

fn assign(&mut self, vars: &Map<String, Value>) {
for (name, value) in vars {
if self.var_exists(&name) {
match value {
Value::Object(_) => {
let value = self.eval_node(value);
self.vars.insert(name.to_string(), value);
}
_ => {
self.vars.insert(name.to_string(), value.clone());
}
let scope = self.get_var_scope(name);
match value {
Value::Object(_) => {
let value = self.eval_node(value);
self.vars
.insert(name.to_string(), Var { scope, body: value });
}
_ => {
self.vars.insert(
name.to_string(),
Var {
scope,
body: value.clone(),
},
);
}
} else {
self.error(&format!("The variable {} does not exist, use define", name));
panic!();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use clap::Parser;
use std::fs;
use std::time::Instant;
mod types;
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
Expand Down
7 changes: 7 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Var {
pub scope: usize,
pub body: serde_json::Value,
}

0 comments on commit 9da82cd

Please sign in to comment.