From e245fdee73bf97153940c9762e93a7888a9ed80c Mon Sep 17 00:00:00 2001 From: afonya Date: Wed, 18 Jun 2025 16:36:15 +0200 Subject: [PATCH] finished coroutine --- src/enviroment.rs | 121 ++++++++++++++++++++++++++++++++++++++++++++-- test.asl | 5 +- 2 files changed, 120 insertions(+), 6 deletions(-) diff --git a/src/enviroment.rs b/src/enviroment.rs index 29af7e2..b0db0d6 100644 --- a/src/enviroment.rs +++ b/src/enviroment.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, fs, io::{stdin, BufReader, Read, Write}, net::{self, TcpListener, TcpStream}, process, thread::sleep, time::{Duration, UNIX_EPOCH}, vec}; -use crate::{decompiler::{DecompiledFunction, DecompiledOperation}, errors::{create_error, print_error, ErrorSubType, ErrorType}, virtualmachine::{Machine, TableValue, VMMemory, VMMemoryBoolean, VMMemoryNativeFunction, VMMemoryNull, VMMemoryNumber, VMMemoryString, VMMemoryTable, VMState}, Context}; +use crate::{decompiler::{DecompiledFunction, DecompiledOperation}, errors::{convert_subtypes_to_string, convert_types_to_string, create_error, print_error, ErrorSubType, ErrorType}, virtualmachine::{Machine, TableValue, VMMemory, VMMemoryBoolean, VMMemoryNativeFunction, VMMemoryNull, VMMemoryNumber, VMMemoryString, VMMemoryTable, VMState}, Context}; fn get_string_from_vmmem(mem: &VMMemory) -> String { let mut out = String::new(); @@ -975,12 +975,13 @@ fn add_func(n_funcs: &mut Vec, n_ctx: &mut Vec, mac let mut exe_func = machine.functions[func].clone(); let func_clone = machine.functions.clone(); n_ctx.push(machine.ctx[func].clone()); + let start = n_funcs.len(); for (fid, fpos) in &func_clone[func].functions { *pos += 1; add_func(n_funcs, n_ctx, machine, *fpos as usize, pos); exe_func.functions.insert(*fid, *pos as u32); } - n_funcs.push(exe_func); + n_funcs.insert(start, exe_func); } fn krumpli_letrehoz(machine: &mut Machine, op: &DecompiledOperation, args: Vec) -> VMMemory { arg_expect(&args, 0, "function", machine, op); @@ -994,15 +995,117 @@ fn krumpli_letrehoz(machine: &mut Machine, op: &DecompiledOperation, args: Vec = vec![]; let mut n_ctx: Vec = vec![]; add_func(&mut n_funcs, &mut n_ctx, machine, func.id, &mut 0); - println!("{:?}", n_funcs); - println!("{:?}", n_ctx); let mut vm = Machine::new(n_ctx); vm.load_functions(n_funcs); - vm.memory = machine.memory.clone(); let cor_id = machine.storage.len(); machine.storage.push(Box::new(vm)); return VMMemory::Number(VMMemoryNumber { value: cor_id as f64, variable_id: 0 }); } +fn krumpli_folytat(machine: &mut Machine, op: &DecompiledOperation, args: Vec) -> VMMemory { + arg_expect(&args, 0, "number", machine, op); + let num = match &args[0] { + VMMemory::Number(n) => n.value as usize, + _ => { + error(String::from("Expected a number"), machine, op); + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } + }; + let vm = machine.storage.get_mut(num); + if vm.is_none() { + error(String::from("Coroutine not found"), machine, op); + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } + let boxed_vm = vm.unwrap(); + let vm = boxed_vm.downcast_mut::(); + if vm.is_none() { + error(String::from("Coroutine is not a VM"), machine, op); + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } + let vm = vm.unwrap(); + println!("{:?}", vm.functions); + match vm.state { + VMState::Paused => { + vm.memory = machine.memory.clone(); + vm.registers = machine.registers.clone(); + vm.resume(); + machine.memory = vm.memory.clone(); + machine.registers = vm.registers.clone(); + }, + _ => { + error(String::from("Coroutine is not paused"), machine, op); + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } + } + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); +} +fn krumpli_status(machine: &mut Machine, op: &DecompiledOperation, args: Vec) -> VMMemory { + arg_expect(&args, 0, "number", machine, op); + let num = match &args[0] { + VMMemory::Number(n) => n.value as usize, + _ => { + error(String::from("Expected a number"), machine, op); + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } + }; + let vm = machine.storage.get_mut(num); + if vm.is_none() { + error(String::from("Coroutine not found"), machine, op); + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } + let boxed_vm = vm.unwrap(); + let vm = boxed_vm.downcast_ref::(); + if vm.is_none() { + error(String::from("Coroutine is not a VM"), machine, op); + return VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } + let vm = vm.unwrap(); + + let mut to_tbl: HashMap = HashMap::new(); + let stat = match vm.state { + VMState::Running => String::from("running"), + VMState::Paused => String::from("paused"), + VMState::Finished => String::from("finished"), + VMState::Error(_) => String::from("error"), + }; + let err = match &vm.state { + VMState::Error(e) => Some(e.clone()), + _ => None + }; + if let Some(e) = err { + let err_tbl: Vec = vec![ + TableValue { + key: VMMemory::String(VMMemoryString { value: String::from("message"), variable_id: 0 }), + value: VMMemory::String(VMMemoryString { value: e.message, variable_id: 0 }) + }, + TableValue { + key: VMMemory::String(VMMemoryString { value: String::from("position"), variable_id: 0 }), + value: VMMemory::Number(VMMemoryNumber { value: e.position as f64, variable_id: 0 }) + }, + TableValue { + key: VMMemory::String(VMMemoryString { value: String::from("type"), variable_id: 0 }), + value: VMMemory::String(VMMemoryString { value: convert_types_to_string(&e.typ), variable_id: 0 }) + }, + TableValue { + key: VMMemory::String(VMMemoryString { value: String::from("subtype"), variable_id: 0 }), + value: VMMemory::String(VMMemoryString { value: convert_subtypes_to_string(&e.subtype), variable_id: 0 }) + }, + TableValue { + key: VMMemory::String(VMMemoryString { value: String::from("code"), variable_id: 0 }), + value: VMMemory::String(VMMemoryString { value: e.code, variable_id: 0 }) + }, + ]; + to_tbl.insert(String::from("error"), VMMemory::Table(VMMemoryTable { values: err_tbl, variable_id: 0 })); + } + to_tbl.insert(String::from("status"), VMMemory::String(VMMemoryString { value: stat, variable_id: 0 })); + let mut res_tbl = VMMemoryTable { + values: vec![], + variable_id: 0, + }; + for (k, v) in to_tbl { + set_mem_tbl_val(&mut res_tbl, VMMemory::String(VMMemoryString { value: k, variable_id: 0 }), v); + } + return VMMemory::Table(res_tbl); +} pub fn generate() -> HashMap { let mut mem: HashMap = HashMap::new(); @@ -1180,6 +1283,14 @@ pub fn generate() -> HashMap { key: VMMemory::String(VMMemoryString { value: String::from("létrehoz"), variable_id: 0 }), value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: krumpli_letrehoz, variable_id: 0 }), }, + TableValue { + key: VMMemory::String(VMMemoryString { value: String::from("folytat"), variable_id: 0 }), + value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: krumpli_folytat, variable_id: 0 }), + }, + TableValue { + key: VMMemory::String(VMMemoryString { value: String::from("státusz"), variable_id: 0 }), + value: VMMemory::NativeFunction(VMMemoryNativeFunction { func: krumpli_status, variable_id: 0 }), + }, ]; mem.insert(String::from("krumpli"), VMMemory::Table(VMMemoryTable { values: krumpli, variable_id: 0 })); diff --git a/test.asl b/test.asl index 8dfd253..5b5aa9a 100644 --- a/test.asl +++ b/test.asl @@ -5,4 +5,7 @@ lőcsve test() { toast() ugass(1) } -krumpli.létrehoz(test) \ No newline at end of file +gethelj k = krumpli.létrehoz(test) +ugass(krumpli.státusz(k)) +krumpli.folytat(k) +ugass(krumpli.státusz(k)) \ No newline at end of file