mirror of
https://github.com/artegoser/ONLang
synced 2024-11-06 04:53:57 +03:00
feat: if cond, loop cycle
This commit is contained in:
parent
4a9332e34a
commit
86e46e9695
2 changed files with 145 additions and 6 deletions
|
@ -102,6 +102,22 @@ impl Interpreter {
|
|||
self.error("Unsupported data type for the let argument");
|
||||
}
|
||||
},
|
||||
"if" => match value {
|
||||
Value::Object(value) => {
|
||||
return self.if_node(value);
|
||||
}
|
||||
_ => {
|
||||
self.error("Unsupported data type for the if argument");
|
||||
}
|
||||
},
|
||||
"loop" => match value {
|
||||
Value::Array(value) => {
|
||||
return self.loop_cycle(value);
|
||||
}
|
||||
_ => {
|
||||
self.error("Unsupported data type for the loop cycle argument");
|
||||
}
|
||||
},
|
||||
name => {
|
||||
self.unk_token(&name);
|
||||
}
|
||||
|
@ -115,12 +131,14 @@ impl Interpreter {
|
|||
"ErrExit" => {
|
||||
self.err_exit();
|
||||
}
|
||||
"break" => return Value::String("break".to_string()),
|
||||
"continue" => return Value::String("continue".to_string()),
|
||||
value => {
|
||||
self.print(&vec![Value::String(value.to_string())], false);
|
||||
self.print(&vec![Value::String(value.to_string())], true);
|
||||
}
|
||||
},
|
||||
Value::Array(command) => {
|
||||
self.print(command, false);
|
||||
self.print(command, true);
|
||||
}
|
||||
_ => {
|
||||
self.error("Unsupported data type for the command");
|
||||
|
@ -129,6 +147,96 @@ impl Interpreter {
|
|||
return Value::Null;
|
||||
}
|
||||
|
||||
fn if_node(&mut self, value: &Map<String, Value>) -> Value {
|
||||
let condition = self.eval_node(&value["condition"]);
|
||||
let nodes = &value.get("body");
|
||||
let else_nodes = &value.get("else");
|
||||
|
||||
match nodes {
|
||||
Some(nodes) => match nodes {
|
||||
Value::Array(nodes) => match else_nodes {
|
||||
Some(else_nodes) => match else_nodes {
|
||||
Value::Array(else_nodes) => {
|
||||
if condition == true {
|
||||
let name = self.run_nodes(nodes);
|
||||
if name == "break" {
|
||||
return Value::String("break".to_string());
|
||||
}
|
||||
if name == "continue" {
|
||||
return Value::String("continue".to_string());
|
||||
}
|
||||
return Value::Null;
|
||||
} else {
|
||||
let name = self.run_nodes(else_nodes);
|
||||
if name == "break" {
|
||||
return Value::String("break".to_string());
|
||||
}
|
||||
if name == "continue" {
|
||||
return Value::String("continue".to_string());
|
||||
}
|
||||
return Value::Null;
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
if condition == true {
|
||||
let name = self.run_nodes(nodes);
|
||||
if name == "break" {
|
||||
return Value::String("break".to_string());
|
||||
}
|
||||
if name == "continue" {
|
||||
return Value::String("continue".to_string());
|
||||
}
|
||||
return Value::Null;
|
||||
}
|
||||
return Value::Null;
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if condition == true {
|
||||
let name = self.run_nodes(nodes);
|
||||
if name == "break" {
|
||||
return Value::String("break".to_string());
|
||||
}
|
||||
if name == "continue" {
|
||||
return Value::String("continue".to_string());
|
||||
}
|
||||
return Value::Null;
|
||||
}
|
||||
return Value::Null;
|
||||
}
|
||||
},
|
||||
_ => return Value::Null,
|
||||
},
|
||||
None => {
|
||||
self.error("if must have a body");
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn loop_cycle(&mut self, value: &Vec<Value>) -> Value {
|
||||
loop {
|
||||
let name = self.run_nodes(value);
|
||||
if name == "break" {
|
||||
break Value::Null;
|
||||
}
|
||||
if name == "continue" {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_nodes(&mut self, arr: &Vec<Value>) -> String {
|
||||
for command in arr {
|
||||
let to_do = self.eval_node(command);
|
||||
match to_do {
|
||||
Value::String(name) => return name,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
"end".to_string()
|
||||
}
|
||||
|
||||
fn define(&mut self, vars: &Map<String, Value>) -> Value {
|
||||
for (name, value) in vars {
|
||||
match value {
|
||||
|
@ -358,14 +466,11 @@ impl Interpreter {
|
|||
fn print(&mut self, args: &Vec<Value>, ln: bool) {
|
||||
for arg in args {
|
||||
self.print_one(arg);
|
||||
}
|
||||
if ln == true {
|
||||
println!();
|
||||
}
|
||||
}
|
||||
if ln == false {
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
fn print_one(&mut self, arg: &Value) {
|
||||
match arg {
|
||||
|
|
34
test.json5
34
test.json5
|
@ -162,6 +162,40 @@
|
|||
|
||||
["After executing calculated = ", { var: "calculated" }],
|
||||
|
||||
"\nRun loop",
|
||||
{
|
||||
loop: [
|
||||
{
|
||||
assign: {
|
||||
calculated: { calc: [{ var: "calculated" }, "+", 1] },
|
||||
},
|
||||
},
|
||||
{ print: ["\rcalculated = ", { var: "calculated" }] },
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "calculated" }, ">=", 200000] },
|
||||
body: ["\n", "break"],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "calculated" }, ">=", 199999] },
|
||||
body: [["Calculated is >= ", 199999]],
|
||||
else: [["Calculated is < ", 199999]],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "calculated" }, ">", 200000] },
|
||||
body: [["Calculated is > ", 200000]],
|
||||
else: [["Calculated is <= ", 200000]],
|
||||
},
|
||||
},
|
||||
|
||||
// {
|
||||
// print: [
|
||||
// {
|
||||
|
|
Loading…
Reference in a new issue