added native functions, enviroment
This commit is contained in:
parent
9a915cd274
commit
32c2a20697
4 changed files with 195 additions and 25 deletions
|
@ -183,7 +183,17 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
||||||
},
|
},
|
||||||
ASTPart::VarRead(var_read) => {
|
ASTPart::VarRead(var_read) => {
|
||||||
if get_variable_by_name(variables, &var_read.variable, ops.len()).is_none() {
|
if get_variable_by_name(variables, &var_read.variable, ops.len()).is_none() {
|
||||||
panic!("Variable {} does not exist", var_read.variable);
|
let reg = allocate_register(registers);
|
||||||
|
if reg.unbind_before {
|
||||||
|
ops.push(Operation { opcode: 8, arg1: Some(reg.register), arg2: None, arg3: None });
|
||||||
|
}
|
||||||
|
let str_id = *next_string_id;
|
||||||
|
strings.insert(str_id, var_read.variable.clone());
|
||||||
|
*next_string_id += 1;
|
||||||
|
ops.push(Operation { opcode: 1, arg1: Some(reg.register), arg2: Some(str_id as i64), arg3: None });
|
||||||
|
ops.push(Operation { opcode: 30, arg1: Some(0), arg2: Some(reg.register as i64), arg3: Some(reg.register) });
|
||||||
|
set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count });
|
||||||
|
return reg.register;
|
||||||
}
|
}
|
||||||
let reg = get_register_by_variable(registers, get_variable_by_name(variables, &var_read.variable, ops.len()).expect("Variable should exist"));
|
let reg = get_register_by_variable(registers, get_variable_by_name(variables, &var_read.variable, ops.len()).expect("Variable should exist"));
|
||||||
if reg.id == 0 {
|
if reg.id == 0 {
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::virtualmachine::{Machine, VMMemory, VMMemoryNativeFunction, VMMemoryNull};
|
||||||
|
|
||||||
|
fn get_string_from_vmmem(mem: VMMemory) -> String {
|
||||||
|
let mut out = String::new();
|
||||||
|
match mem {
|
||||||
|
VMMemory::String(s) => out.push_str(&s.value),
|
||||||
|
VMMemory::Number(n) => out.push_str(&n.value.to_string()),
|
||||||
|
VMMemory::Boolean(b) => out.push_str(if b.value { "true" } else { "false" }),
|
||||||
|
VMMemory::Null(_) => out.push_str("null"),
|
||||||
|
VMMemory::Table(tbl) => {
|
||||||
|
out.push_str("{ ");
|
||||||
|
for val in &tbl.values {
|
||||||
|
out.push_str(&get_string_from_vmmem(val.key.clone()));
|
||||||
|
out.push_str("=");
|
||||||
|
out.push_str(&get_string_from_vmmem(val.value.clone()));
|
||||||
|
out.push_str(", ");
|
||||||
|
}
|
||||||
|
out.pop();
|
||||||
|
out.pop();
|
||||||
|
out.push_str("}");
|
||||||
|
},
|
||||||
|
VMMemory::Function(func) => {
|
||||||
|
out.push_str("|function: ");
|
||||||
|
out.push_str(&func.id.to_string());
|
||||||
|
out.push_str("|");
|
||||||
|
},
|
||||||
|
VMMemory::NativeFunction(_) => {
|
||||||
|
out.push_str("|native function|");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ugass(_machine: &mut Machine, args: Vec<VMMemory>) -> VMMemory {
|
||||||
|
let mut out = String::new();
|
||||||
|
for arg in args {
|
||||||
|
out.push_str(&get_string_from_vmmem(arg));
|
||||||
|
out.push_str(" ");
|
||||||
|
}
|
||||||
|
println!("{}", out.trim_end());
|
||||||
|
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate() -> HashMap<String, VMMemory> {
|
||||||
|
let mut mem: HashMap<String, VMMemory> = HashMap::new();
|
||||||
|
|
||||||
|
mem.insert(String::from("ugass"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: ugass, variable_id: 0 }));
|
||||||
|
|
||||||
|
return mem;
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::enviroment;
|
||||||
|
|
||||||
const ASXVERSION: [u8; 3] = [0,1,0];
|
const ASXVERSION: [u8; 3] = [0,1,0];
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -10,6 +12,7 @@ pub enum VMMemory {
|
||||||
Function(VMMemoryFunction),
|
Function(VMMemoryFunction),
|
||||||
Null(VMMemoryNull),
|
Null(VMMemoryNull),
|
||||||
Table(VMMemoryTable),
|
Table(VMMemoryTable),
|
||||||
|
NativeFunction(VMMemoryNativeFunction),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -46,6 +49,11 @@ pub struct TableValue {
|
||||||
pub key: VMMemory,
|
pub key: VMMemory,
|
||||||
pub value: VMMemory
|
pub value: VMMemory
|
||||||
}
|
}
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct VMMemoryNativeFunction {
|
||||||
|
pub func: fn(&mut Machine, Vec<VMMemory>) -> VMMemory,
|
||||||
|
pub variable_id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct DecompiledFunction {
|
struct DecompiledFunction {
|
||||||
|
@ -88,6 +96,7 @@ pub struct Machine {
|
||||||
pub stack: Vec<VMMemory>,
|
pub stack: Vec<VMMemory>,
|
||||||
pub registers: Vec<Register>,
|
pub registers: Vec<Register>,
|
||||||
pub call_stack: Vec<CallStack>,
|
pub call_stack: Vec<CallStack>,
|
||||||
|
pub env: HashMap<String, VMMemory>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_be_num(input: &[u8]) -> usize {
|
fn read_be_num(input: &[u8]) -> usize {
|
||||||
|
@ -173,6 +182,7 @@ fn get_mem_pos_by_var_id(memory: &Vec<VMMemory>, var_id: u32) -> Option<usize> {
|
||||||
VMMemory::Null(null) if null.variable_id == var_id => return Some(i),
|
VMMemory::Null(null) if null.variable_id == var_id => return Some(i),
|
||||||
VMMemory::Function(func) if func.variable_id == var_id => return Some(i),
|
VMMemory::Function(func) if func.variable_id == var_id => return Some(i),
|
||||||
VMMemory::Table(tbl) if tbl.variable_id == var_id => return Some(i),
|
VMMemory::Table(tbl) if tbl.variable_id == var_id => return Some(i),
|
||||||
|
VMMemory::NativeFunction(func) if func.variable_id == var_id => return Some(i),
|
||||||
_ => continue
|
_ => continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,6 +198,7 @@ fn set_mem_tbl_val(tbl: &mut VMMemoryTable, key: VMMemory, value: VMMemory) {
|
||||||
(VMMemory::Null(_), VMMemory::Null(_)) => true,
|
(VMMemory::Null(_), VMMemory::Null(_)) => true,
|
||||||
(VMMemory::Function(_), VMMemory::Function(_)) => false,
|
(VMMemory::Function(_), VMMemory::Function(_)) => false,
|
||||||
(VMMemory::Table(_), VMMemory::Table(_)) => false,
|
(VMMemory::Table(_), VMMemory::Table(_)) => false,
|
||||||
|
(VMMemory::NativeFunction(_), VMMemory::NativeFunction(_)) => false,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if found {
|
if found {
|
||||||
|
@ -207,6 +218,7 @@ fn get_mem_tbl_val(tbl: &VMMemoryTable, key: VMMemory) -> Option<&VMMemory> {
|
||||||
(VMMemory::Null(_), VMMemory::Null(_)) => true,
|
(VMMemory::Null(_), VMMemory::Null(_)) => true,
|
||||||
(VMMemory::Function(_), VMMemory::Function(_)) => false,
|
(VMMemory::Function(_), VMMemory::Function(_)) => false,
|
||||||
(VMMemory::Table(_), VMMemory::Table(_)) => false,
|
(VMMemory::Table(_), VMMemory::Table(_)) => false,
|
||||||
|
(VMMemory::NativeFunction(_), VMMemory::NativeFunction(_)) => false,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if found {
|
if found {
|
||||||
|
@ -342,6 +354,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
|
||||||
VMMemory::Null(null) => null.variable_id,
|
VMMemory::Null(null) => null.variable_id,
|
||||||
VMMemory::Function(func) => func.variable_id,
|
VMMemory::Function(func) => func.variable_id,
|
||||||
VMMemory::Table(tbl) => tbl.variable_id,
|
VMMemory::Table(tbl) => tbl.variable_id,
|
||||||
|
VMMemory::NativeFunction(func) => func.variable_id,
|
||||||
};
|
};
|
||||||
match &mut result {
|
match &mut result {
|
||||||
VMMemory::String(str) => {
|
VMMemory::String(str) => {
|
||||||
|
@ -362,6 +375,9 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
|
||||||
VMMemory::Table(tbl) => {
|
VMMemory::Table(tbl) => {
|
||||||
tbl.variable_id = var_id;
|
tbl.variable_id = var_id;
|
||||||
},
|
},
|
||||||
|
VMMemory::NativeFunction(func) => {
|
||||||
|
func.variable_id = var_id;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
memory[reg3_pointer] = result;
|
memory[reg3_pointer] = result;
|
||||||
}
|
}
|
||||||
|
@ -423,6 +439,8 @@ fn load_func(data: Vec<u8>, offset: &mut usize) -> DecompiledFunction {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
println!("Variables: {:?}", variables);
|
println!("Variables: {:?}", variables);
|
||||||
|
println!("Strings: {:?}", strings);
|
||||||
|
println!("Functions: {:?}", functions);
|
||||||
return DecompiledFunction {
|
return DecompiledFunction {
|
||||||
body: body,
|
body: body,
|
||||||
variables: variables,
|
variables: variables,
|
||||||
|
@ -451,7 +469,8 @@ impl Machine {
|
||||||
func: 0,
|
func: 0,
|
||||||
return_reg: 0,
|
return_reg: 0,
|
||||||
pc: 0,
|
pc: 0,
|
||||||
}]
|
}],
|
||||||
|
env: enviroment::generate()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,16 +492,16 @@ impl Machine {
|
||||||
if self.call_stack.len() == 0 {
|
if self.call_stack.len() == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let executed_func = self.functions.get(self.call_stack[self.call_stack.len()-1].func);
|
let func_clone = self.functions.clone();
|
||||||
|
let executed_func = func_clone.get(self.call_stack[self.call_stack.len()-1].func);
|
||||||
if executed_func.is_none() {
|
if executed_func.is_none() {
|
||||||
panic!("Current function not found!");
|
panic!("Current function not found!");
|
||||||
}
|
}
|
||||||
let mut executed_func = executed_func.unwrap();
|
let mut executed_func = executed_func.unwrap();
|
||||||
let last_stack = self.call_stack.len()-1;
|
let mut executed_stack = self.call_stack.len()-1;
|
||||||
let mut executed_stack = &mut self.call_stack[last_stack];
|
while self.call_stack[executed_stack].pc < executed_func.body.len() {
|
||||||
while executed_stack.pc < executed_func.body.len() {
|
let operation = &executed_func.body[self.call_stack[executed_stack].pc];
|
||||||
let operation = &executed_func.body[executed_stack.pc];
|
self.call_stack[executed_stack].pc += 1;
|
||||||
executed_stack.pc += 1;
|
|
||||||
match operation.opcode {
|
match operation.opcode {
|
||||||
0 => {
|
0 => {
|
||||||
//HLT
|
//HLT
|
||||||
|
@ -527,7 +546,10 @@ impl Machine {
|
||||||
},
|
},
|
||||||
VMMemory::Table(tbl) => {
|
VMMemory::Table(tbl) => {
|
||||||
tbl.variable_id = 0;
|
tbl.variable_id = 0;
|
||||||
}
|
},
|
||||||
|
VMMemory::NativeFunction(func) => {
|
||||||
|
func.variable_id = 0;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
self.memory.push(nmem);
|
self.memory.push(nmem);
|
||||||
set_register(&mut self.registers, Register { id: operation.arg1, pointer: self.memory.len() - 1 });
|
set_register(&mut self.registers, Register { id: operation.arg1, pointer: self.memory.len() - 1 });
|
||||||
|
@ -600,6 +622,9 @@ impl Machine {
|
||||||
VMMemory::Table(tbl) => {
|
VMMemory::Table(tbl) => {
|
||||||
tbl.variable_id = 0;
|
tbl.variable_id = 0;
|
||||||
},
|
},
|
||||||
|
VMMemory::NativeFunction(func) => {
|
||||||
|
func.variable_id = 0;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match &mut self.memory[reg.pointer] {
|
match &mut self.memory[reg.pointer] {
|
||||||
|
@ -621,6 +646,9 @@ impl Machine {
|
||||||
VMMemory::Table(tbl) => {
|
VMMemory::Table(tbl) => {
|
||||||
tbl.variable_id = operation.arg2 as u32;
|
tbl.variable_id = operation.arg2 as u32;
|
||||||
},
|
},
|
||||||
|
VMMemory::NativeFunction(func) => {
|
||||||
|
func.variable_id = operation.arg2 as u32;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
8 => {
|
8 => {
|
||||||
|
@ -674,6 +702,7 @@ impl Machine {
|
||||||
VMMemory::Null(null) => null.variable_id,
|
VMMemory::Null(null) => null.variable_id,
|
||||||
VMMemory::Function(func) => func.variable_id,
|
VMMemory::Function(func) => func.variable_id,
|
||||||
VMMemory::Table(tbl) => tbl.variable_id,
|
VMMemory::Table(tbl) => tbl.variable_id,
|
||||||
|
VMMemory::NativeFunction(func) => func.variable_id,
|
||||||
};
|
};
|
||||||
match &mut result {
|
match &mut result {
|
||||||
VMMemory::String(str) => {
|
VMMemory::String(str) => {
|
||||||
|
@ -694,12 +723,15 @@ impl Machine {
|
||||||
VMMemory::Table(tbl) => {
|
VMMemory::Table(tbl) => {
|
||||||
tbl.variable_id = var_id;
|
tbl.variable_id = var_id;
|
||||||
},
|
},
|
||||||
|
VMMemory::NativeFunction(func) => {
|
||||||
|
func.variable_id = var_id;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
self.memory[reg2.unwrap().pointer] = result;
|
self.memory[reg2.unwrap().pointer] = result;
|
||||||
},
|
},
|
||||||
25 => {
|
25 => {
|
||||||
//JMP
|
//JMP
|
||||||
executed_stack.pc = operation.arg2 as usize;
|
self.call_stack[executed_stack].pc = operation.arg2 as usize;
|
||||||
},
|
},
|
||||||
26 => {
|
26 => {
|
||||||
//CJP
|
//CJP
|
||||||
|
@ -716,7 +748,7 @@ impl Machine {
|
||||||
match &mem {
|
match &mem {
|
||||||
VMMemory::Boolean(bool) => {
|
VMMemory::Boolean(bool) => {
|
||||||
if bool.value {
|
if bool.value {
|
||||||
executed_stack.pc = operation.arg2 as usize;
|
self.call_stack[executed_stack].pc = operation.arg2 as usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => panic!("Invalid memory type for CJP operation"),
|
_ => panic!("Invalid memory type for CJP operation"),
|
||||||
|
@ -755,20 +787,27 @@ impl Machine {
|
||||||
VMMemory::Null(null) => {
|
VMMemory::Null(null) => {
|
||||||
null.variable_id = self.functions[func.id].variables[arg].id;
|
null.variable_id = self.functions[func.id].variables[arg].id;
|
||||||
},
|
},
|
||||||
VMMemory::Function(func) => {
|
VMMemory::Function(vfunc) => {
|
||||||
func.variable_id = self.functions[func.id].variables[arg].id;
|
vfunc.variable_id = self.functions[func.id].variables[arg].id;
|
||||||
},
|
},
|
||||||
VMMemory::Table(tbl) => {
|
VMMemory::Table(tbl) => {
|
||||||
tbl.variable_id = self.functions[func.id].variables[arg].id;
|
tbl.variable_id = self.functions[func.id].variables[arg].id;
|
||||||
},
|
},
|
||||||
|
VMMemory::NativeFunction(nfunc) => {
|
||||||
|
nfunc.variable_id = self.functions[func.id].variables[arg].id;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
self.memory.push(new_mem);
|
self.memory.push(new_mem);
|
||||||
}
|
}
|
||||||
|
self.stack.clear();
|
||||||
|
|
||||||
self.call_stack.push(CallStack { func: func.id, return_reg: operation.arg2 as usize, pc: 0 });
|
self.call_stack.push(CallStack { func: func.id, return_reg: operation.arg2 as usize, pc: 0 });
|
||||||
executed_func = &self.functions[func.id];
|
executed_func = &func_clone[func.id];
|
||||||
let last_stack = self.call_stack.len() - 1;
|
executed_stack = self.call_stack.len() - 1;
|
||||||
executed_stack = &mut self.call_stack[last_stack];
|
},
|
||||||
|
VMMemory::NativeFunction(nfunc) => {
|
||||||
|
(nfunc.func)(self, self.stack.clone());
|
||||||
|
self.stack.clear();
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Unable to call non-function memory type");
|
panic!("Unable to call non-function memory type");
|
||||||
|
@ -791,7 +830,7 @@ impl Machine {
|
||||||
},
|
},
|
||||||
29 => {
|
29 => {
|
||||||
//RET
|
//RET
|
||||||
let target_reg = get_register_by_id(&self.registers, executed_stack.return_reg as u8);
|
let target_reg = get_register_by_id(&self.registers, self.call_stack[executed_stack].return_reg as u8);
|
||||||
let ret_reg = get_register_by_id(&self.registers, operation.arg1);
|
let ret_reg = get_register_by_id(&self.registers, operation.arg1);
|
||||||
if target_reg.is_none() || ret_reg.is_none() {
|
if target_reg.is_none() || ret_reg.is_none() {
|
||||||
panic!("Return register or target register not found");
|
panic!("Return register or target register not found");
|
||||||
|
@ -803,19 +842,85 @@ impl Machine {
|
||||||
let return_value = ret_mem.unwrap().clone();
|
let return_value = ret_mem.unwrap().clone();
|
||||||
let target_reg_pointer = self.memory.len();
|
let target_reg_pointer = self.memory.len();
|
||||||
self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
||||||
set_register(&mut self.registers, Register { id: executed_stack.return_reg as u8, pointer: target_reg_pointer });
|
set_register(&mut self.registers, Register { id: self.call_stack[executed_stack].return_reg as u8, pointer: target_reg_pointer });
|
||||||
self.memory[target_reg_pointer] = return_value;
|
self.memory[target_reg_pointer] = return_value;
|
||||||
self.call_stack.pop();
|
self.call_stack.pop();
|
||||||
if self.call_stack.len() < 1 {
|
if self.call_stack.len() < 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let last_stack = self.call_stack.len() - 1;
|
executed_stack = self.call_stack.len() - 1;
|
||||||
executed_func = &self.functions[self.call_stack[last_stack].func];
|
executed_func = &func_clone[self.call_stack[executed_stack].func];
|
||||||
executed_stack = &mut self.call_stack[last_stack];
|
|
||||||
},
|
},
|
||||||
30 => {
|
30 => {
|
||||||
//GET
|
//GET
|
||||||
let reg_clone = self.registers.clone();
|
let reg_clone = self.registers.clone();
|
||||||
|
if operation.arg1 == 0 {
|
||||||
|
//We use the enviroment instead of a table
|
||||||
|
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||||
|
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
||||||
|
if reg2.is_none() || reg3.is_none() {
|
||||||
|
panic!("One or more registers not found for GET operation");
|
||||||
|
}
|
||||||
|
let mem2 = self.memory.get(reg2.unwrap().pointer);
|
||||||
|
if mem2.is_none() {
|
||||||
|
panic!("Memory location not found for register {}", operation.arg2);
|
||||||
|
}
|
||||||
|
let mem2 = mem2.unwrap().clone();
|
||||||
|
let mut result: VMMemory;
|
||||||
|
match mem2 {
|
||||||
|
VMMemory::String(str) => {
|
||||||
|
let ret = self.env.get(&str.value);
|
||||||
|
if ret.is_none() {
|
||||||
|
result = VMMemory::Null(VMMemoryNull { variable_id: 0 });
|
||||||
|
} else {
|
||||||
|
result = ret.unwrap().clone();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
panic!("Unable to get non-string key from enviroment");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut reg3_pointer = reg3.unwrap().pointer;
|
||||||
|
if reg3_pointer >= self.memory.len() || reg3_pointer < 1 {
|
||||||
|
reg3_pointer = self.memory.len();
|
||||||
|
self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
||||||
|
set_register(&mut self.registers, Register { id: operation.arg3, pointer: reg3_pointer });
|
||||||
|
}
|
||||||
|
let var_id = match &self.memory[reg3.unwrap().pointer] {
|
||||||
|
VMMemory::String(str) => str.variable_id,
|
||||||
|
VMMemory::Number(num) => num.variable_id,
|
||||||
|
VMMemory::Boolean(bool) => bool.variable_id,
|
||||||
|
VMMemory::Null(null) => null.variable_id,
|
||||||
|
VMMemory::Function(func) => func.variable_id,
|
||||||
|
VMMemory::Table(tbl) => tbl.variable_id,
|
||||||
|
VMMemory::NativeFunction(func) => func.variable_id,
|
||||||
|
};
|
||||||
|
match &mut result {
|
||||||
|
VMMemory::String(str) => {
|
||||||
|
str.variable_id = var_id;
|
||||||
|
},
|
||||||
|
VMMemory::Number(num) => {
|
||||||
|
num.variable_id = var_id;
|
||||||
|
},
|
||||||
|
VMMemory::Boolean(bool) => {
|
||||||
|
bool.variable_id = var_id;
|
||||||
|
},
|
||||||
|
VMMemory::Null(null) => {
|
||||||
|
null.variable_id = var_id;
|
||||||
|
},
|
||||||
|
VMMemory::Function(func) => {
|
||||||
|
func.variable_id = var_id;
|
||||||
|
},
|
||||||
|
VMMemory::Table(tbl) => {
|
||||||
|
tbl.variable_id = var_id;
|
||||||
|
},
|
||||||
|
VMMemory::NativeFunction(func) => {
|
||||||
|
func.variable_id = var_id;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
self.memory[reg3_pointer] = result;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let reg = get_register_by_id(®_clone, operation.arg1);
|
let reg = get_register_by_id(®_clone, operation.arg1);
|
||||||
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||||
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
||||||
|
@ -840,14 +945,14 @@ impl Machine {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Invalid memory type for SET operation");
|
panic!("Invalid memory type for GET operation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut reg3_pointer = reg3.unwrap().pointer;
|
let mut reg3_pointer = reg3.unwrap().pointer;
|
||||||
if reg3_pointer >= self.memory.len() || reg3_pointer < 1 {
|
if reg3_pointer >= self.memory.len() || reg3_pointer < 1 {
|
||||||
reg3_pointer = self.memory.len();
|
reg3_pointer = self.memory.len();
|
||||||
self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
||||||
set_register(&mut self.registers, Register { id: operation.arg2 as u8, pointer: reg3_pointer });
|
set_register(&mut self.registers, Register { id: operation.arg3 as u8, pointer: reg3_pointer });
|
||||||
}
|
}
|
||||||
let var_id = match &self.memory[reg3.unwrap().pointer] {
|
let var_id = match &self.memory[reg3.unwrap().pointer] {
|
||||||
VMMemory::String(str) => str.variable_id,
|
VMMemory::String(str) => str.variable_id,
|
||||||
|
@ -856,6 +961,7 @@ impl Machine {
|
||||||
VMMemory::Null(null) => null.variable_id,
|
VMMemory::Null(null) => null.variable_id,
|
||||||
VMMemory::Function(func) => func.variable_id,
|
VMMemory::Function(func) => func.variable_id,
|
||||||
VMMemory::Table(tbl) => tbl.variable_id,
|
VMMemory::Table(tbl) => tbl.variable_id,
|
||||||
|
VMMemory::NativeFunction(func) => func.variable_id,
|
||||||
};
|
};
|
||||||
match &mut value {
|
match &mut value {
|
||||||
VMMemory::String(str) => {
|
VMMemory::String(str) => {
|
||||||
|
@ -876,6 +982,9 @@ impl Machine {
|
||||||
VMMemory::Table(tbl) => {
|
VMMemory::Table(tbl) => {
|
||||||
tbl.variable_id = var_id;
|
tbl.variable_id = var_id;
|
||||||
},
|
},
|
||||||
|
VMMemory::NativeFunction(func) => {
|
||||||
|
func.variable_id = var_id;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
self.memory[reg3.unwrap().pointer] = value;
|
self.memory[reg3.unwrap().pointer] = value;
|
||||||
},
|
},
|
||||||
|
|
3
test.as
3
test.as
|
@ -1,2 +1 @@
|
||||||
gethelj a = {1,2,3}
|
ugass(szaft"test"szaft, ugass)
|
||||||
a[0] = 4
|
|
Loading…
Add table
Add a link
Reference in a new issue