feat: import

This commit is contained in:
Artemy 2022-08-18 17:45:27 +03:00
parent 27ee5334da
commit 0676d8691f

View file

@ -29,6 +29,45 @@ impl Interpreter {
self.exit_from_scope(); self.exit_from_scope();
} }
pub fn new(file_path: String) -> Self { pub fn new(file_path: String) -> Self {
Self {
commands: Interpreter::get_commands(file_path),
vars: HashMap::new(),
pos: 1,
scope: 0,
scopes: Vec::new(),
named_scopes: Vec::new(),
}
}
pub fn compress(&mut self, output_path: String) {
let mut output = File::create(output_path).expect("Failed to create output file");
output
.write_all(
&rmp_serde::encode::to_vec(&self.commands)
.expect("Error when compressing onlang to .conla"),
)
.expect("Error when writing to file");
println!("Compressed");
}
pub fn convert(&self, format: String, output_path: String) {
match format.as_str() {
"yaml" => {
self.convert_to_yaml(output_path);
}
"json" => {
self.convert_to_json(output_path);
}
"json5" => {
self.convert_to_json5(output_path);
}
_ => {
self.error("The conversion format is not supported");
}
}
}
fn get_commands(file_path: String) -> Vec<Value> {
match Path::new(&file_path) match Path::new(&file_path)
.extension() .extension()
.and_then(OsStr::to_str) .and_then(OsStr::to_str)
@ -59,14 +98,7 @@ impl Interpreter {
.as_array() .as_array()
.expect("The program must be an array of commands") .expect("The program must be an array of commands")
}); });
Self { commands.clone()
commands: commands.clone(),
vars: HashMap::new(),
pos: 1,
scope: 0,
scopes: Vec::new(),
named_scopes: Vec::new(),
}
} }
"conla" => { "conla" => {
let file_input = File::open(file_path).expect("File reading error"); let file_input = File::open(file_path).expect("File reading error");
@ -78,14 +110,7 @@ impl Interpreter {
.as_array() .as_array()
.expect("The program must be an array of commands") .expect("The program must be an array of commands")
}); });
Self { commands.clone()
commands: commands.clone(),
vars: HashMap::new(),
pos: 1,
scope: 0,
scopes: Vec::new(),
named_scopes: Vec::new(),
}
} }
_ => { _ => {
let file_input = fs::read_to_string(&file_path).expect("File reading error"); let file_input = fs::read_to_string(&file_path).expect("File reading error");
@ -101,42 +126,7 @@ impl Interpreter {
.expect("The program must be an array of commands") .expect("The program must be an array of commands")
}); });
Self { commands.clone()
commands: commands.clone(),
vars: HashMap::new(),
pos: 1,
scope: 0,
scopes: Vec::new(),
named_scopes: Vec::new(),
}
}
}
}
pub fn compress(&mut self, output_path: String) {
let mut output = File::create(output_path).expect("Failed to create output file");
output
.write_all(
&rmp_serde::encode::to_vec(&self.commands)
.expect("Error when compressing onlang to .conla"),
)
.expect("Error when writing to file");
println!("Compressed");
}
pub fn convert(&self, format: String, output_path: String) {
match format.as_str() {
"yaml" => {
self.convert_to_yaml(output_path);
}
"json" => {
self.convert_to_json(output_path);
}
"json5" => {
self.convert_to_json5(output_path);
}
_ => {
self.error("The conversion format is not supported");
} }
} }
} }
@ -352,6 +342,14 @@ impl Interpreter {
}, },
"return" => return json!({ "return": value }), "return" => return json!({ "return": value }),
"import" => match value {
Value::Object(value) => {
self.import(value);
}
_ => {
self.error("Unsupported data type for the `obj` argument, must be an array");
}
},
name => match value { name => match value {
Value::Array(value) => { Value::Array(value) => {
return self.run_fn(name.to_string(), value); return self.run_fn(name.to_string(), value);
@ -390,6 +388,34 @@ impl Interpreter {
return Value::Null; return Value::Null;
} }
fn import(&mut self, value: &Map<String, Value>) {
let path = value
.get("path")
.expect("The import must contain the `path` argument");
let as_name = value
.get("as")
.expect("The import must contain the `as` argument");
if let Value::String(path) = path.clone() {
if let Value::String(as_name) = as_name.clone() {
let commands = Interpreter::get_commands(path);
let length = commands.len();
self.named_scopes.push(as_name);
for i in 0..length {
let command = &commands[i];
self.eval_node(command);
self.pos = i;
}
self.named_scopes.pop();
} else {
self.error("`as` argument must be a string");
}
} else {
self.error("`path` argument must be a string");
}
}
fn calc_arr(&mut self, value: &Vec<Value>) -> Value { fn calc_arr(&mut self, value: &Vec<Value>) -> Value {
Value::Array( Value::Array(
value value