mirror of
https://github.com/artegoser/ONLang
synced 2024-12-23 01:23:46 +03:00
feat: scopes of visibility, delete variable
now, after exiting the scope (loop, if), all the variables that were in it are deleted
This commit is contained in:
parent
fdd7e2abc8
commit
9da82cde2a
4 changed files with 80 additions and 20 deletions
|
@ -179,7 +179,6 @@
|
|||
body: ["break"],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
assign: {
|
||||
num: { calc: [{ var: "num" }, "+", 1] },
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::types::*;
|
||||
use colored::*;
|
||||
use json5;
|
||||
use serde_json::{json, Map, Value};
|
||||
|
@ -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 {
|
||||
|
@ -16,6 +18,7 @@ impl Interpreter {
|
|||
input,
|
||||
vars: HashMap::new(),
|
||||
pos: 1,
|
||||
scope: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -273,6 +284,7 @@ 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 {
|
||||
|
@ -280,19 +292,38 @@ impl Interpreter {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
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 {
|
||||
|
@ -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!();
|
||||
|
@ -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!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
7
src/types.rs
Normal file
7
src/types.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Var {
|
||||
pub scope: usize,
|
||||
pub body: serde_json::Value,
|
||||
}
|
Loading…
Add table
Reference in a new issue