mirror of
https://github.com/artegoser/ONLang
synced 2024-12-23 09:33:44 +03:00
feat: import
This commit is contained in:
parent
27ee5334da
commit
0676d8691f
1 changed files with 107 additions and 81 deletions
|
@ -29,87 +29,13 @@ impl Interpreter {
|
||||||
self.exit_from_scope();
|
self.exit_from_scope();
|
||||||
}
|
}
|
||||||
pub fn new(file_path: String) -> Self {
|
pub fn new(file_path: String) -> Self {
|
||||||
match Path::new(&file_path)
|
Self {
|
||||||
.extension()
|
commands: Interpreter::get_commands(file_path),
|
||||||
.and_then(OsStr::to_str)
|
vars: HashMap::new(),
|
||||||
.expect("The file must have the extension (.yaml, .json, .json5, .onla or .conla)")
|
pos: 1,
|
||||||
{
|
scope: 0,
|
||||||
"yaml" => {
|
scopes: Vec::new(),
|
||||||
let file_input = fs::read_to_string(&file_path).expect("File reading error");
|
named_scopes: Vec::new(),
|
||||||
let obj: serde_json::Value =
|
|
||||||
serde_yaml::from_str(&file_input).unwrap_or_else(|x| {
|
|
||||||
match x.location() {
|
|
||||||
Some(location) => {
|
|
||||||
eprintln!(
|
|
||||||
"{file_path}:{}:{} --> {x}",
|
|
||||||
location.column(),
|
|
||||||
location.line()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
eprintln!("{}", x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::process::exit(1);
|
|
||||||
});
|
|
||||||
let commands = obj.as_array().unwrap_or_else(|| {
|
|
||||||
obj.get("main")
|
|
||||||
.expect("Each program must contain a `{main: [..commands]}` object or be a command array ([..commands])")
|
|
||||||
.as_array()
|
|
||||||
.expect("The program must be an array of commands")
|
|
||||||
});
|
|
||||||
Self {
|
|
||||||
commands: commands.clone(),
|
|
||||||
vars: HashMap::new(),
|
|
||||||
pos: 1,
|
|
||||||
scope: 0,
|
|
||||||
scopes: Vec::new(),
|
|
||||||
named_scopes: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"conla" => {
|
|
||||||
let file_input = File::open(file_path).expect("File reading error");
|
|
||||||
let obj: serde_json::Value = rmp_serde::from_read(file_input)
|
|
||||||
.expect(".conla file (MessagePack) is invalid! ");
|
|
||||||
let commands = obj.as_array().unwrap_or_else(|| {
|
|
||||||
obj.get("main")
|
|
||||||
.expect("Each program must contain a `{main: [..commands]}` object or be a command array ([..commands])")
|
|
||||||
.as_array()
|
|
||||||
.expect("The program must be an array of commands")
|
|
||||||
});
|
|
||||||
Self {
|
|
||||||
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 obj: serde_json::Value =
|
|
||||||
json5::from_str::<Value>(&file_input).unwrap_or_else(|x| {
|
|
||||||
eprintln!("{file_path}{x}");
|
|
||||||
std::process::exit(1);
|
|
||||||
});
|
|
||||||
let commands = obj.as_array().unwrap_or_else(|| {
|
|
||||||
obj.get("main")
|
|
||||||
.expect("Each program must contain a `{main: [..commands]}` object or be a command array ([..commands])")
|
|
||||||
.as_array()
|
|
||||||
.expect("The program must be an array of commands")
|
|
||||||
});
|
|
||||||
|
|
||||||
Self {
|
|
||||||
commands: commands.clone(),
|
|
||||||
vars: HashMap::new(),
|
|
||||||
pos: 1,
|
|
||||||
scope: 0,
|
|
||||||
scopes: Vec::new(),
|
|
||||||
named_scopes: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +67,70 @@ impl Interpreter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_commands(file_path: String) -> Vec<Value> {
|
||||||
|
match Path::new(&file_path)
|
||||||
|
.extension()
|
||||||
|
.and_then(OsStr::to_str)
|
||||||
|
.expect("The file must have the extension (.yaml, .json, .json5, .onla or .conla)")
|
||||||
|
{
|
||||||
|
"yaml" => {
|
||||||
|
let file_input = fs::read_to_string(&file_path).expect("File reading error");
|
||||||
|
let obj: serde_json::Value =
|
||||||
|
serde_yaml::from_str(&file_input).unwrap_or_else(|x| {
|
||||||
|
match x.location() {
|
||||||
|
Some(location) => {
|
||||||
|
eprintln!(
|
||||||
|
"{file_path}:{}:{} --> {x}",
|
||||||
|
location.column(),
|
||||||
|
location.line()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
eprintln!("{}", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::process::exit(1);
|
||||||
|
});
|
||||||
|
let commands = obj.as_array().unwrap_or_else(|| {
|
||||||
|
obj.get("main")
|
||||||
|
.expect("Each program must contain a `{main: [..commands]}` object or be a command array ([..commands])")
|
||||||
|
.as_array()
|
||||||
|
.expect("The program must be an array of commands")
|
||||||
|
});
|
||||||
|
commands.clone()
|
||||||
|
}
|
||||||
|
"conla" => {
|
||||||
|
let file_input = File::open(file_path).expect("File reading error");
|
||||||
|
let obj: serde_json::Value = rmp_serde::from_read(file_input)
|
||||||
|
.expect(".conla file (MessagePack) is invalid! ");
|
||||||
|
let commands = obj.as_array().unwrap_or_else(|| {
|
||||||
|
obj.get("main")
|
||||||
|
.expect("Each program must contain a `{main: [..commands]}` object or be a command array ([..commands])")
|
||||||
|
.as_array()
|
||||||
|
.expect("The program must be an array of commands")
|
||||||
|
});
|
||||||
|
commands.clone()
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let file_input = fs::read_to_string(&file_path).expect("File reading error");
|
||||||
|
let obj: serde_json::Value =
|
||||||
|
json5::from_str::<Value>(&file_input).unwrap_or_else(|x| {
|
||||||
|
eprintln!("{file_path}{x}");
|
||||||
|
std::process::exit(1);
|
||||||
|
});
|
||||||
|
let commands = obj.as_array().unwrap_or_else(|| {
|
||||||
|
obj.get("main")
|
||||||
|
.expect("Each program must contain a `{main: [..commands]}` object or be a command array ([..commands])")
|
||||||
|
.as_array()
|
||||||
|
.expect("The program must be an array of commands")
|
||||||
|
});
|
||||||
|
|
||||||
|
commands.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn convert_to_yaml(&self, output_path: String) {
|
fn convert_to_yaml(&self, output_path: String) {
|
||||||
let mut output = File::create(output_path).expect("Failed to create output file");
|
let mut output = File::create(output_path).expect("Failed to create output file");
|
||||||
write!(
|
write!(
|
||||||
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue