add operations

This commit is contained in:
afonya2 2025-05-24 18:17:32 +02:00
parent c880366eb0
commit 581c301165
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
2 changed files with 88 additions and 42 deletions

View file

@ -44,11 +44,6 @@ pub struct Executor {
pub max_oppr: usize
}
struct Processed {
ret: ASTPart,
yld: bool,
}
impl Executor {
pub fn new(code: Vec<ASTPart>, max_oppr: usize) -> Executor {
return Executor {
@ -64,8 +59,7 @@ impl Executor {
}
fn read_memory(&mut self, key: String, check_mode: bool) -> ASTPart {
let current_scope = self.memory.len() - 1;
for scope in current_scope..0 {
for scope in (0..self.memory.len()).rev() {
for data in &self.memory[scope] {
match data {
MemoryData::Number(num) => {
@ -168,47 +162,100 @@ impl Executor {
}
}
fn process_code(&mut self, code: &ASTPart, op_count: &mut usize) -> Processed {
fn process_code(&mut self, code: &ASTPart, op_count: &mut usize) -> ASTPart {
println!("Processing code: {:?}", code);
if *op_count >= self.max_oppr {
return Processed {
ret: ASTPart::NOOP,
yld: false,
};
}
*op_count += 1;
match code {
ASTPart::String(_) => {
return Processed {
ret: code.clone(),
yld: false,
};
return code.clone();
},
ASTPart::Number(_) => {
return Processed {
ret: code.clone(),
yld: false,
};
return code.clone();
},
ASTPart::Boolean(_) => {
return Processed {
ret: code.clone(),
yld: false,
};
return code.clone();
},
ASTPart::Assigment(assign) => {
let value = self.process_code(&assign.value, op_count);
self.write_memory(assign.variable.clone(), value.ret, false);
return Processed {
ret: ASTPart::NOOP,
yld: false,
};
}
self.write_memory(assign.variable.clone(), value, false);
return ASTPart::NOOP;
},
ASTPart::Operation(op) => {
let left = self.process_code(&op.left, op_count);
let right = self.process_code(&op.right, op_count);
if op.operator == "+" {
match (&left, &right) {
(ASTPart::Number(left_num), ASTPart::Number(right_num)) => {
return ASTPart::Number(AstNumber { value: left_num.value + right_num.value, pos: 0 });
},
(ASTPart::String(left_str), ASTPart::String(right_str)) => {
return ASTPart::String(AstString { value: left_str.value.clone() + &right_str.value, pos: 0 });
},
_ => {
panic!("Unable to do operation '+' on {:?} with {:?} at {}", left, right, op.pos);
}
}
} else if op.operator == "-" {
match (&left, &right) {
(ASTPart::Number(left_num), ASTPart::Number(right_num)) => {
return ASTPart::Number(AstNumber { value: left_num.value - right_num.value, pos: 0 });
},
_ => {
panic!("Unable to do operation '-' on {:?} with {:?} at {}", left, right, op.pos);
}
}
} else if op.operator == "*" {
match (&left, &right) {
(ASTPart::Number(left_num), ASTPart::Number(right_num)) => {
return ASTPart::Number(AstNumber { value: left_num.value * right_num.value, pos: 0 });
},
_ => {
panic!("Unable to do operation '*' on {:?} with {:?} at {}", left, right, op.pos);
}
}
} else if op.operator == "/" {
match (&left, &right) {
(ASTPart::Number(left_num), ASTPart::Number(right_num)) => {
if right_num.value == 0 {
panic!("Unable to divide by zero at {}!", op.pos);
}
return ASTPart::Number(AstNumber { value: left_num.value / right_num.value, pos: 0 });
},
_ => {
panic!("Unable to do operation '/' on {:?} with {:?} at {}", left, right, op.pos);
}
}
} else if op.operator == "^" {
match (&left, &right) {
(ASTPart::Number(left_num), ASTPart::Number(right_num)) => {
return ASTPart::Number(AstNumber { value: left_num.value.pow(right_num.value as u32), pos: 0 });
},
_ => {
panic!("Unable to do operation '^' on {:?} with {:?} at {}", left, right, op.pos);
}
}
} else if op.operator == "%" {
match (&left, &right) {
(ASTPart::Number(left_num), ASTPart::Number(right_num)) => {
if right_num.value == 0 {
panic!("Unable to divide by zero at {}!", op.pos);
}
return ASTPart::Number(AstNumber { value: left_num.value % right_num.value, pos: 0 });
},
_ => {
panic!("Unable to do operation '%' on {:?} with {:?} at {}", left, right, op.pos);
}
}
} else {
panic!("Unknown operator: {} at {}", op.operator, op.pos);
}
},
ASTPart::VarRead(var) => {
let data = self.read_memory(var.variable.clone(), false);
return data;
},
_ => {
return Processed {
ret: ASTPart::NOOP,
yld: true,
};
return ASTPart::NOOP;
}
}
}
@ -225,15 +272,14 @@ impl Executor {
self.breakpoints.remove(0);
break;
}
let proc = self.process_code(&self.code[self.pos].clone(), &mut op_count);
if proc.yld {
self.state = State::Paused;
break;
}
self.process_code(&self.code[self.pos].clone(), &mut op_count);
if op_count >= self.max_oppr {
self.state = State::Error(String::from("Too long without yielding!"));
break;
}
if self.state != State::Running {
break;
}
self.pos += 1;
}
if self.pos >= self.code.len() {