added more enviroment functions and fixed some argument bugs
This commit is contained in:
parent
12d3250bc4
commit
cca26d9fc3
5 changed files with 107 additions and 25 deletions
|
@ -249,7 +249,10 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
|||
for arg in call.args {
|
||||
let arg_reg = do_ast_op(arg, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||
ops.push(Operation { opcode: 28, arg1: Some(arg_reg), arg2: None, arg3: None, pos: call.pos as u32 });
|
||||
set_register(registers, RegisterState { id: arg_reg, used: false, variable: 0, last_used: 0 });
|
||||
let reg = get_register_by_id(registers, arg_reg);
|
||||
if reg.variable == 0 {
|
||||
set_register(registers, RegisterState { id: arg_reg, used: false, variable: 0, last_used: 0 });
|
||||
}
|
||||
}
|
||||
let ret_reg = allocate_register(registers);
|
||||
if ret_reg.unbind_before {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, process, thread::sleep, time::Duration};
|
||||
|
||||
use crate::virtualmachine::{Machine, VMMemory, VMMemoryNativeFunction, VMMemoryNull};
|
||||
use crate::{errors::{create_error, print_error, ErrorSubType, ErrorType}, virtualmachine::{DecompiledOperation, Machine, VMMemory, VMMemoryNativeFunction, VMMemoryNull, VMMemoryString}};
|
||||
|
||||
fn get_string_from_vmmem(mem: VMMemory) -> String {
|
||||
fn get_string_from_vmmem(mem: &VMMemory) -> String {
|
||||
let mut out = String::new();
|
||||
match mem {
|
||||
VMMemory::String(s) => out.push_str(&s.value),
|
||||
|
@ -12,9 +12,9 @@ fn get_string_from_vmmem(mem: VMMemory) -> String {
|
|||
VMMemory::Table(tbl) => {
|
||||
out.push_str("{");
|
||||
for val in &tbl.values {
|
||||
out.push_str(&get_string_from_vmmem(val.key.clone()));
|
||||
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(&get_string_from_vmmem(&val.value.clone()));
|
||||
out.push_str(", ");
|
||||
}
|
||||
out.pop();
|
||||
|
@ -32,21 +32,83 @@ fn get_string_from_vmmem(mem: VMMemory) -> String {
|
|||
}
|
||||
return out;
|
||||
}
|
||||
fn get_type_str(mem: &VMMemory) -> String {
|
||||
match mem {
|
||||
VMMemory::String(_) => "string".to_string(),
|
||||
VMMemory::Number(_) => "number".to_string(),
|
||||
VMMemory::Boolean(_) => "boolean".to_string(),
|
||||
VMMemory::Null(_) => "null".to_string(),
|
||||
VMMemory::Table(_) => "table".to_string(),
|
||||
VMMemory::Function(_) => "function".to_string(),
|
||||
VMMemory::NativeFunction(_) => "native_function".to_string(),
|
||||
}
|
||||
}
|
||||
fn expect(mem: &VMMemory, expected_type: &str) -> bool {
|
||||
let actual_type = get_type_str(&mem);
|
||||
if actual_type == expected_type {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fn error(msg: String, machine: &Machine, op: &DecompiledOperation) {
|
||||
let err = create_error(&msg, op.pos, ErrorType::MachineError, ErrorSubType::RuntimeError);
|
||||
let curr = machine.call_stack.len()-1;
|
||||
let func = machine.call_stack[curr].func;
|
||||
print_error(&err, &machine.ctx[func]);
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
fn ugass(_machine: &mut Machine, args: Vec<VMMemory>) -> VMMemory {
|
||||
fn ugass(_machine: &mut Machine, _op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
|
||||
let mut out = String::new();
|
||||
for arg in args {
|
||||
out.push_str(&get_string_from_vmmem(arg));
|
||||
out.push_str(&get_string_from_vmmem(&arg));
|
||||
out.push_str(" ");
|
||||
}
|
||||
println!("{}", out.trim_end());
|
||||
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
|
||||
}
|
||||
|
||||
fn bimba(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
|
||||
if args.len() < 1 || !expect(&args[0], "number") {
|
||||
error(format!("#1 number expected got {}", get_type_str(&args[0])), machine, op);
|
||||
}
|
||||
match &args[0] {
|
||||
VMMemory::Number(n) => {
|
||||
sleep(Duration::from_millis(n.value as u64));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
|
||||
}
|
||||
|
||||
fn csomor(machine: &mut Machine, op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
|
||||
if args.len() < 1 || !expect(&args[0], "string") {
|
||||
error(format!("#1 string expected got {}", get_type_str(&args[0])), machine, op);
|
||||
}
|
||||
match &args[0] {
|
||||
VMMemory::String(s) => {
|
||||
error(s.value.clone(), machine, op);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
return VMMemory::Null(VMMemoryNull { variable_id: 0 });
|
||||
}
|
||||
|
||||
fn tarh(_machine: &mut Machine, _op: &DecompiledOperation, args: Vec<VMMemory>) -> VMMemory {
|
||||
if args.len() < 1 {
|
||||
return VMMemory::String(VMMemoryString { value: String::from("null"), variable_id: 0 });
|
||||
}
|
||||
return VMMemory::String(VMMemoryString { value: get_type_str(&args[0]), 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 }));
|
||||
mem.insert(String::from("bimba"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: bimba, variable_id: 0 }));
|
||||
mem.insert(String::from("csömör"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: csomor, variable_id: 0 }));
|
||||
mem.insert(String::from("tarh"), VMMemory::NativeFunction(VMMemoryNativeFunction { func: tarh, variable_id: 0 }));
|
||||
|
||||
return mem;
|
||||
}
|
|
@ -33,6 +33,7 @@ pub enum ErrorSubType {
|
|||
UnknownString,
|
||||
UnknownMemoryLocation,
|
||||
NonFunctionCall,
|
||||
RuntimeError,
|
||||
//Math errors
|
||||
DivisionByZero,
|
||||
//Type errors
|
||||
|
@ -94,6 +95,7 @@ fn convert_subtypes_to_string(stype: &ErrorSubType) -> String {
|
|||
ErrorSubType::WrongType => String::from("Wrong type"),
|
||||
ErrorSubType::TooManyArguments => String::from("Too many arguments"),
|
||||
ErrorSubType::FileError => String::from("File error"),
|
||||
ErrorSubType::RuntimeError => String::from("Runtime error"),
|
||||
}
|
||||
}
|
||||
fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
|
||||
|
@ -121,6 +123,7 @@ fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
|
|||
ErrorSubType::WrongType => String::from("WT:"),
|
||||
ErrorSubType::TooManyArguments => String::from("TA:"),
|
||||
ErrorSubType::FileError => String::from("FE:"),
|
||||
ErrorSubType::RuntimeError => String::from("RE:"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ pub struct TableValue {
|
|||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VMMemoryNativeFunction {
|
||||
pub func: fn(&mut Machine, Vec<VMMemory>) -> VMMemory,
|
||||
pub func: fn(&mut Machine, &DecompiledOperation, Vec<VMMemory>) -> VMMemory,
|
||||
pub variable_id: u32,
|
||||
}
|
||||
|
||||
|
@ -62,12 +62,12 @@ struct DecompiledFunction {
|
|||
functions: HashMap<u32, u32>
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
struct DecompiledOperation {
|
||||
opcode: u8,
|
||||
arg1: u8,
|
||||
arg2: i64,
|
||||
arg3: u8,
|
||||
pos: usize,
|
||||
pub struct DecompiledOperation {
|
||||
pub opcode: u8,
|
||||
pub arg1: u8,
|
||||
pub arg2: i64,
|
||||
pub arg3: u8,
|
||||
pub pos: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -85,9 +85,9 @@ struct Variable {
|
|||
}
|
||||
|
||||
pub struct CallStack {
|
||||
func: usize,
|
||||
return_reg: usize,
|
||||
pc: usize,
|
||||
pub func: usize,
|
||||
pub return_reg: usize,
|
||||
pub pc: usize,
|
||||
}
|
||||
|
||||
pub struct Machine {
|
||||
|
@ -110,11 +110,7 @@ fn read_be_num(input: &[u8]) -> usize {
|
|||
}
|
||||
|
||||
fn read_str(input: &[u8]) -> String {
|
||||
let mut result = String::new();
|
||||
for &byte in input {
|
||||
result.push(byte as char);
|
||||
}
|
||||
return result;
|
||||
String::from_utf8(input.to_vec()).expect("Invalid UTF-8 sequence")
|
||||
}
|
||||
|
||||
fn read_bin(input: &[u8]) -> String {
|
||||
|
@ -802,7 +798,23 @@ impl Machine {
|
|||
executed_stack = self.call_stack.len() - 1;
|
||||
},
|
||||
VMMemory::NativeFunction(nfunc) => {
|
||||
(nfunc.func)(self, self.stack.clone());
|
||||
let mut result = (nfunc.func)(self, &operation, self.stack.clone());
|
||||
let ret_reg = get_register_by_id(&self.registers, operation.arg2 as u8);
|
||||
if ret_reg.is_none() {
|
||||
let err = create_error(&format!("Register `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound);
|
||||
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
|
||||
process::exit(1);
|
||||
}
|
||||
let mut ret_pointer = ret_reg.unwrap().pointer;
|
||||
if ret_pointer >= self.memory.len() || ret_pointer < 1 {
|
||||
self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
||||
ret_pointer = self.memory.len() - 1;
|
||||
set_register(&mut self.registers, Register { id: operation.arg2 as u8, pointer: ret_pointer });
|
||||
}
|
||||
let var_id = get_var_id(&self.memory[ret_pointer]);
|
||||
set_var_id(&mut result, var_id);
|
||||
self.memory[ret_pointer] = result;
|
||||
|
||||
self.stack.clear();
|
||||
},
|
||||
_ => {
|
||||
|
|
4
test.asl
4
test.asl
|
@ -2,4 +2,6 @@ gethelj a = {
|
|||
[szaft"test"szaft] = szaft"test"szaft,
|
||||
[szaft"teher"szaft] = szaft"teher"szaft
|
||||
}
|
||||
ugass(a)
|
||||
ugass(a)
|
||||
//csömör(szaft"háh, appja hám"szaft)
|
||||
ugass(tarh(a))
|
Loading…
Add table
Add a link
Reference in a new issue