prepare the error system for try/catch

This commit is contained in:
afonya 2025-06-18 13:14:58 +02:00
parent 1a98959be0
commit 3dd28cedd3
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
7 changed files with 146 additions and 118 deletions

View file

@ -309,7 +309,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
}, },
ASTPart::Else(else_part) => { ASTPart::Else(else_part) => {
if get_variable_by_name(variables, "__LASTIF", ops.len(), traceback).is_none() { if get_variable_by_name(variables, "__LASTIF", ops.len(), traceback).is_none() {
let err = create_error(&format!("Else used without an if statement before it"), else_part.pos, ErrorType::SemanticError, ErrorSubType::ElseWithoutIf); let err = create_error(&format!("Else used without an if statement before it"), else_part.pos, ErrorType::SemanticError, ErrorSubType::ElseWithoutIf, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -357,7 +357,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
}, },
ASTPart::ElseIf(elseif_part) => { ASTPart::ElseIf(elseif_part) => {
if get_variable_by_name(variables, "__LASTIF", ops.len(), traceback).is_none() { if get_variable_by_name(variables, "__LASTIF", ops.len(), traceback).is_none() {
let err = create_error(&format!("Else if used without an if statement before it"), elseif_part.pos, ErrorType::SemanticError, ErrorSubType::ElseWithoutIf); let err = create_error(&format!("Else if used without an if statement before it"), elseif_part.pos, ErrorType::SemanticError, ErrorSubType::ElseWithoutIf, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -471,12 +471,12 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
} }
}, },
ASTPart::Break(brk) => { ASTPart::Break(brk) => {
let err = create_error(&format!("Unexpected break outside of loop"), brk.pos, ErrorType::SemanticError, ErrorSubType::BreakContinueWithoutLoop); let err = create_error(&format!("Unexpected break outside of loop"), brk.pos, ErrorType::SemanticError, ErrorSubType::BreakContinueWithoutLoop, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
ASTPart::Continue(cont) => { ASTPart::Continue(cont) => {
let err = create_error(&format!("Unexpected continue outside of loop"), cont.pos, ErrorType::SemanticError, ErrorSubType::BreakContinueWithoutLoop); let err = create_error(&format!("Unexpected continue outside of loop"), cont.pos, ErrorType::SemanticError, ErrorSubType::BreakContinueWithoutLoop, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
@ -574,7 +574,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
return reg.register; return reg.register;
}, },
_ => { _ => {
let err = create_error(&format!("Unknown operator `{}`", op.operator), op.pos, ErrorType::SyntaxError, ErrorSubType::UnknownOperation); let err = create_error(&format!("Unknown operator `{}`", op.operator), op.pos, ErrorType::SyntaxError, ErrorSubType::UnknownOperation, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
@ -585,7 +585,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
}, },
ASTPart::VarUpdate(upd) => { ASTPart::VarUpdate(upd) => {
if get_variable_by_name(variables, &upd.variable, ops.len(), traceback).is_none() { if get_variable_by_name(variables, &upd.variable, ops.len(), traceback).is_none() {
let err = create_error(&format!("Variable `{}` does not exist", upd.variable), upd.pos, ErrorType::SemanticError, ErrorSubType::VariableNotFound); let err = create_error(&format!("Variable `{}` does not exist", upd.variable), upd.pos, ErrorType::SemanticError, ErrorSubType::VariableNotFound, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -601,7 +601,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
}, },
ASTPart::Assigment(asign) => { ASTPart::Assigment(asign) => {
if get_variable_by_name(variables, &asign.variable, ops.len(), traceback).is_some() { if get_variable_by_name(variables, &asign.variable, ops.len(), traceback).is_some() {
let err = create_error(&format!("Variable `{}` already exists", asign.variable), asign.pos, ErrorType::SemanticError, ErrorSubType::VariableAlreadyExists); let err = create_error(&format!("Variable `{}` already exists", asign.variable), asign.pos, ErrorType::SemanticError, ErrorSubType::VariableAlreadyExists, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -672,7 +672,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
return reg.register; return reg.register;
}, },
Err(e) => { Err(e) => {
let err = create_error(&format!("Failed to read file `{}`: {}", impr.path, e), impr.pos, ErrorType::IOError, ErrorSubType::FileError); let err = create_error(&format!("Failed to read file `{}`: {}", impr.path, e), impr.pos, ErrorType::IOError, ErrorSubType::FileError, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -722,7 +722,7 @@ fn compile_function(ast: Vec<ASTPart>, args: Option<Vec<String>>, registers: &mu
Some(arg_list) => { Some(arg_list) => {
for arg in arg_list { for arg in arg_list {
if get_variable_by_name(&variables, &arg, 0, &empty_tb).is_some() { if get_variable_by_name(&variables, &arg, 0, &empty_tb).is_some() {
let err = create_error(&format!("Argument `{}` already exists", arg), 0, ErrorType::SemanticError, ErrorSubType::ArgumentDuplication); let err = create_error(&format!("Argument `{}` already exists", arg), 0, ErrorType::SemanticError, ErrorSubType::ArgumentDuplication, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }

View file

@ -58,9 +58,9 @@ fn arg_expect(args: &Vec<VMMemory>, pos: usize, expected_type: &str, machine: &M
} }
} }
fn error(msg: String, machine: &Machine, op: &DecompiledOperation) { 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 curr = machine.call_stack.len()-1;
let func = machine.call_stack[curr].func; let func = machine.call_stack[curr].func;
let err = create_error(&msg, op.pos, ErrorType::MachineError, ErrorSubType::RuntimeError, &machine.ctx[func]);
print_error(&err, &machine.ctx[func]); print_error(&err, &machine.ctx[func]);
process::exit(1); process::exit(1);
} }

View file

@ -1,5 +1,6 @@
use crate::Context; use crate::Context;
#[derive(Debug, Clone)]
pub enum ErrorType { pub enum ErrorType {
SyntaxError, SyntaxError,
SemanticError, SemanticError,
@ -9,6 +10,7 @@ pub enum ErrorType {
IOError, IOError,
} }
#[derive(Debug, Clone)]
pub enum ErrorSubType { pub enum ErrorSubType {
//Syntax errors //Syntax errors
UnexpectedEnd, UnexpectedEnd,
@ -43,6 +45,7 @@ pub enum ErrorSubType {
FileError FileError
} }
#[derive(Debug, Clone)]
pub struct ASLError { pub struct ASLError {
pub message: String, pub message: String,
pub position: usize, pub position: usize,
@ -171,9 +174,11 @@ pub fn reverse_subtype_short(str: String) -> ErrorSubType {
} }
} }
pub fn create_error(message: &str, position: usize, typ: ErrorType, stype: ErrorSubType) -> ASLError { pub fn create_error(message: &str, position: usize, typ: ErrorType, stype: ErrorSubType, ctx: &Context) -> ASLError {
let mut code = convert_types_to_short(&typ); let mut code = convert_types_to_short(&typ);
code.push_str(&convert_subtypes_to_short(&stype)); code.push_str(&convert_subtypes_to_short(&stype));
code.push_str(ctx.c_funcid.to_string().as_str());
code.push(':');
code.push_str(&position.to_string()); code.push_str(&position.to_string());
ASLError { ASLError {
message: String::from(message), message: String::from(message),
@ -276,7 +281,5 @@ pub fn print_error(error: &ASLError, ctx: &Context) {
out.push_str("\n"); out.push_str("\n");
out.push_str("Error Code: "); out.push_str("Error Code: ");
out.push_str(&error.code); out.push_str(&error.code);
out.push_str(":");
out.push_str(&ctx.c_funcid.to_string());
println!("{}", out); println!("{}", out);
} }

View file

@ -70,7 +70,7 @@ fn read_string(splitted: &Vec<&str>, pos: &mut usize, out: &mut Vec<Token>, ctx:
str += nchar; str += nchar;
} }
if !success { if !success {
let err = create_error("Unexpected end of string", *pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error("Unexpected end of string", *pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -94,7 +94,7 @@ fn read_comment(splitted: &Vec<&str>, pos: &mut usize, is_multiline: bool, ctx:
str += nchar; str += nchar;
} }
if !success { if !success {
let err = create_error("Unexpected end of comment", *pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error("Unexpected end of comment", *pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }

View file

@ -59,7 +59,7 @@ fn main() {
println!("Build successful. Took: {}ms", ntime.as_millis()); println!("Build successful. Took: {}ms", ntime.as_millis());
let mut vm = Machine::new(contexts); let mut vm = Machine::new(contexts);
vm.load(&compiled); vm.load(&compiled);
vm.run(); vm.resume();
}, },
Result::Err(err) => { Result::Err(err) => {
panic!("Can't read file: {}", err); panic!("Can't read file: {}", err);
@ -76,7 +76,7 @@ fn main() {
} }
let mut vm = Machine::new(contexts); let mut vm = Machine::new(contexts);
vm.load(&data); vm.load(&data);
vm.run(); vm.resume();
}, },
Result::Err(err) => { Result::Err(err) => {
panic!("Can't read file: {}", err); panic!("Can't read file: {}", err);
@ -147,8 +147,8 @@ fn main() {
println!("Error code {} is invalid for this file.", args[3]); println!("Error code {} is invalid for this file.", args[3]);
return; return;
} }
let error = create_error("", errcode_data[2].parse().unwrap(), reverse_type_short(errcode_data[0].to_string()), reverse_subtype_short(errcode_data[1].to_string()));
let func_ctx = contexts[errcode_data[3].parse::<usize>().unwrap()].clone(); let func_ctx = contexts[errcode_data[3].parse::<usize>().unwrap()].clone();
let error = create_error("", errcode_data[3].parse().unwrap(), reverse_type_short(errcode_data[0].to_string()), reverse_subtype_short(errcode_data[1].to_string()), &func_ctx);
print_error(&error, &func_ctx); print_error(&error, &func_ctx);
return; return;
}, },

View file

@ -277,7 +277,7 @@ fn shunt(input: Vec<ASTPart>, ctx: &Context) -> ASTPart {
if op.operator == "!" { if op.operator == "!" {
println!("{:?}", output); println!("{:?}", output);
if i < 1 { if i < 1 {
let err = create_error(&format!("Unexpected operation `{}`", op.operator), op.pos, ErrorType::SemanticError, ErrorSubType::UnexpectedOperation); let err = create_error(&format!("Unexpected operation `{}`", op.operator), op.pos, ErrorType::SemanticError, ErrorSubType::UnexpectedOperation, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -291,7 +291,7 @@ fn shunt(input: Vec<ASTPart>, ctx: &Context) -> ASTPart {
output.remove(i-1); output.remove(i-1);
} else { } else {
if i < 2 { if i < 2 {
let err = create_error(&format!("Unexpected operation `{}`", op.operator), op.pos, ErrorType::SemanticError, ErrorSubType::UnexpectedOperation); let err = create_error(&format!("Unexpected operation `{}`", op.operator), op.pos, ErrorType::SemanticError, ErrorSubType::UnexpectedOperation, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -314,7 +314,7 @@ fn shunt(input: Vec<ASTPart>, ctx: &Context) -> ASTPart {
} }
} }
if output.len() == 0 { if output.len() == 0 {
let err = create_error(&format!("No expressions found after applying order of operations"), 0, ErrorType::SemanticError, ErrorSubType::NoExpression); let err = create_error(&format!("No expressions found after applying order of operations"), 0, ErrorType::SemanticError, ErrorSubType::NoExpression, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -325,7 +325,7 @@ fn read_function(input: &Vec<Token>, pos: &mut usize, with_args: bool, ctx: &Con
let start_pos = input[*pos].pos; let start_pos = input[*pos].pos;
if with_args { if with_args {
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "(" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "(" {
let err = create_error(&format!("Expected `(`"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `(`"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -342,20 +342,20 @@ fn read_function(input: &Vec<Token>, pos: &mut usize, with_args: bool, ctx: &Con
if token.typ == TokenType::IDENTIFIER { if token.typ == TokenType::IDENTIFIER {
args.push(token.value.clone()); args.push(token.value.clone());
} else { } else {
let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
} }
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" {
let err = create_error(&format!("Unexpected end of arguments"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of arguments"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
*pos += 1; *pos += 1;
} }
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "{" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "{" {
let err = create_error(&format!("Expected {{"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected {{"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -370,7 +370,7 @@ fn read_function(input: &Vec<Token>, pos: &mut usize, with_args: bool, ctx: &Con
]; ];
let body = parse_internal(input, &op_ends, &parse_ends, pos, ctx); let body = parse_internal(input, &op_ends, &parse_ends, pos, ctx);
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "}" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "}" {
let err = create_error(&format!("Unexpected end of function"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of function"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -403,25 +403,25 @@ fn read_table(input: &Vec<Token>, pos: &mut usize, ctx: &Context) -> ASTPart {
let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx); let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx);
match keyy { match keyy {
ASTPart::Table(_) => { ASTPart::Table(_) => {
let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
ASTPart::Function(_) => { ASTPart::Function(_) => {
let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
_ => {} _ => {}
} }
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" {
let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
*pos += 1; *pos += 1;
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "=" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "=" {
let err = create_error(&format!("Expected `=` after key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `=` after key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -443,7 +443,7 @@ fn read_table(input: &Vec<Token>, pos: &mut usize, ctx: &Context) -> ASTPart {
*pos += 1; *pos += 1;
continue; continue;
} else { } else {
let err = create_error(&format!("Unexpected end of table"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of table"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -503,7 +503,7 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
let func = read_function(input, pos, true, ctx); let func = read_function(input, pos, true, ctx);
expressions.push(func); expressions.push(func);
} else { } else {
let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -521,19 +521,19 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx); let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx);
match keyy { match keyy {
ASTPart::Table(_) => { ASTPart::Table(_) => {
let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
ASTPart::Function(_) => { ASTPart::Function(_) => {
let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
_ => {} _ => {}
} }
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" {
let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -545,7 +545,7 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
*pos += 1; *pos += 1;
let keyy = &input[*pos]; let keyy = &input[*pos];
if keyy.typ != TokenType::IDENTIFIER { if keyy.typ != TokenType::IDENTIFIER {
let err = create_error(&format!("Expected identifier after `.`"), keyy.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected identifier after `.`"), keyy.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -567,7 +567,7 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
if input[*pos].typ == TokenType::SEPARATOR && input[*pos].value == ")" { if input[*pos].typ == TokenType::SEPARATOR && input[*pos].value == ")" {
*pos += 1; *pos += 1;
} else { } else {
let err = create_error(&format!("Unclosed parenthesis"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Unclosed); let err = create_error(&format!("Unclosed parenthesis"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Unclosed, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -576,12 +576,12 @@ fn read_exp(pos: &mut usize, input: &Vec<Token>, ends: &Vec<Token>, parse_ends:
let tbl = read_table(input, pos, ctx); let tbl = read_table(input, pos, ctx);
expressions.push(tbl); expressions.push(tbl);
} else { } else {
let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
} else { } else {
let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -611,19 +611,19 @@ fn check_continue(pos: &mut usize, input: &Vec<Token>, prev: ASTPart, op_ends: &
let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx); let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx);
match keyy { match keyy {
ASTPart::Table(_) => { ASTPart::Table(_) => {
let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
ASTPart::Function(_) => { ASTPart::Function(_) => {
let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
_ => {} _ => {}
} }
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" {
let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -635,7 +635,7 @@ fn check_continue(pos: &mut usize, input: &Vec<Token>, prev: ASTPart, op_ends: &
*pos += 1; *pos += 1;
let keyy = &input[*pos]; let keyy = &input[*pos];
if keyy.typ != TokenType::IDENTIFIER { if keyy.typ != TokenType::IDENTIFIER {
let err = create_error(&format!("Expected identifier after `.`"), keyy.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected identifier after `.`"), keyy.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -668,7 +668,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let variable = &input[*pos]; let variable = &input[*pos];
*pos += 1; *pos += 1;
if variable.typ != TokenType::IDENTIFIER { if variable.typ != TokenType::IDENTIFIER {
let err = create_error(&format!("Unexpected `{:?}`", variable.typ,), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}`", variable.typ,), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -680,7 +680,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
return ASTPart::Assigment(AstAssigment { variable: variable.value.clone(), value: Box::new(value), pos: token.pos }); return ASTPart::Assigment(AstAssigment { variable: variable.value.clone(), value: Box::new(value), pos: token.pos });
} else if token.value == "ha geny" { } else if token.value == "ha geny" {
if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" { if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" {
let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -690,7 +690,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
]; ];
let condition = read_exp(pos, input, &condition_end, &condition_end, ctx); let condition = read_exp(pos, input, &condition_end, &condition_end, ctx);
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" {
let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -699,7 +699,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let real_body = match body { let real_body = match body {
ASTPart::Function(func) => func.body, ASTPart::Function(func) => func.body,
_ => { _ => {
let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -707,7 +707,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
return ASTPart::If(AstIf { condition: Box::new(condition), body: real_body, pos: token.pos }); return ASTPart::If(AstIf { condition: Box::new(condition), body: real_body, pos: token.pos });
} else if token.value == "amíg geny" { } else if token.value == "amíg geny" {
if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" { if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" {
let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -717,7 +717,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
]; ];
let condition = read_exp(pos, input, &condition_end, &condition_end, ctx); let condition = read_exp(pos, input, &condition_end, &condition_end, ctx);
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" {
let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -726,7 +726,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let real_body = match body { let real_body = match body {
ASTPart::Function(func) => func.body, ASTPart::Function(func) => func.body,
_ => { _ => {
let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -736,7 +736,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
return ASTPart::Break(AstBreak { pos: token.pos }); return ASTPart::Break(AstBreak { pos: token.pos });
} else if token.value == "kopva" { } else if token.value == "kopva" {
if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" { if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" {
let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -747,31 +747,31 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
]; ];
let init = parse_internal(input, &ends, &ends, pos, ctx); let init = parse_internal(input, &ends, &ends, pos, ctx);
if init.len() != 1 { if init.len() != 1 {
let err = create_error(&format!("Only one expression is expected for init"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Only one expression is expected for init"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
if input[*pos].typ != TokenType::OPEND || input[*pos].value != ";" { if input[*pos].typ != TokenType::OPEND || input[*pos].value != ";" {
let err = create_error(&format!("Unexpected end of init"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of init"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
*pos += 1; *pos += 1;
let condition = read_exp(pos, input, &ends, &ends, ctx); let condition = read_exp(pos, input, &ends, &ends, ctx);
if input[*pos].typ != TokenType::OPEND || input[*pos].value != ";" { if input[*pos].typ != TokenType::OPEND || input[*pos].value != ";" {
let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
*pos += 1; *pos += 1;
let update = parse_internal(input, &ends, &ends, pos, ctx); let update = parse_internal(input, &ends, &ends, pos, ctx);
if update.len() != 1 { if update.len() != 1 {
let err = create_error(&format!("Only one expression is expected for update"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Only one expression is expected for update"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" {
let err = create_error(&format!("Unexpected end of update"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of update"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -780,7 +780,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let real_body = match body { let real_body = match body {
ASTPart::Function(func) => func.body, ASTPart::Function(func) => func.body,
_ => { _ => {
let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -790,7 +790,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
return ASTPart::Continue(AstContinue { pos: token.pos }); return ASTPart::Continue(AstContinue { pos: token.pos });
} else if token.value == "ha nem geny akkor geny" { } else if token.value == "ha nem geny akkor geny" {
if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" { if next_token.typ != TokenType::SEPARATOR || next_token.value != "(" {
let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `(`"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -800,7 +800,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
]; ];
let condition = read_exp(pos, input, &condition_end, &condition_end, ctx); let condition = read_exp(pos, input, &condition_end, &condition_end, ctx);
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != ")" {
let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of condition"), token.pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -809,7 +809,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let real_body = match body { let real_body = match body {
ASTPart::Function(func) => func.body, ASTPart::Function(func) => func.body,
_ => { _ => {
let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -820,7 +820,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let real_body = match body { let real_body = match body {
ASTPart::Function(func) => func.body, ASTPart::Function(func) => func.body,
_ => { _ => {
let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -837,19 +837,19 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let var = &input[*pos]; let var = &input[*pos];
*pos += 1; *pos += 1;
if var.typ != TokenType::IDENTIFIER { if var.typ != TokenType::IDENTIFIER {
let err = create_error(&format!("Expected identifier after hámozd"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected identifier after hámozd"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
if input[*pos].typ != TokenType::KEYWORD || (input[*pos].value != "be" && input[*pos].value != "ba") { if input[*pos].typ != TokenType::KEYWORD || (input[*pos].value != "be" && input[*pos].value != "ba") {
let err = create_error(&format!("Expected `be`/`ba` after hámozd"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `be`/`ba` after hámozd"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
*pos += 1; *pos += 1;
let path = &input[*pos]; let path = &input[*pos];
if path.typ != TokenType::STRING { if path.typ != TokenType::STRING {
let err = create_error(&format!("Expected string for hámozd"), path.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected string for hámozd"), path.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -869,13 +869,13 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let tryp = match func { let tryp = match func {
ASTPart::Function(f) => f, ASTPart::Function(f) => f,
_ => { _ => {
let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
}; };
if input[*pos].typ != TokenType::KEYWORD || input[*pos].value != "csecs" { if input[*pos].typ != TokenType::KEYWORD || input[*pos].value != "csecs" {
let err = create_error(&format!("Expected `csecs` after piszolj"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected `csecs` after piszolj"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -884,14 +884,14 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let catchp = match func2 { let catchp = match func2 {
ASTPart::Function(f) => f, ASTPart::Function(f) => f,
_ => { _ => {
let err = create_error(&format!("Expected function body"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected function body"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
}; };
return ASTPart::TryCatch(AstTryCatch { try_block: tryp, catch_block: catchp, pos: token.pos }); return ASTPart::TryCatch(AstTryCatch { try_block: tryp, catch_block: catchp, pos: token.pos });
} else { } else {
let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -905,7 +905,7 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
*pos += 1; *pos += 1;
let keyy = &input[*pos]; let keyy = &input[*pos];
if keyy.typ != TokenType::IDENTIFIER { if keyy.typ != TokenType::IDENTIFIER {
let err = create_error(&format!("Expected identifier after `.`"), keyy.pos, ErrorType::SyntaxError, ErrorSubType::Expected); let err = create_error(&format!("Expected identifier after `.`"), keyy.pos, ErrorType::SyntaxError, ErrorSubType::Expected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -920,19 +920,19 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx); let keyy = read_exp(pos, input, &key_ends, &key_ends, ctx);
match keyy { match keyy {
ASTPart::Table(_) => { ASTPart::Table(_) => {
let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be tables"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
ASTPart::Function(_) => { ASTPart::Function(_) => {
let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys); let err = create_error(&format!("Table keys cannot be functions"), input[*pos].pos, ErrorType::SemanticError, ErrorSubType::InvalidTableKeys, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
}, },
_ => {} _ => {}
} }
if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" { if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" {
let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd); let err = create_error(&format!("Unexpected end of key"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::UnexpectedEnd, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -950,12 +950,12 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let value = read_exp(pos, input, op_ends, parse_ends, ctx); let value = read_exp(pos, input, op_ends, parse_ends, ctx);
return ASTPart::VarUpdate(AstVarUpdate { variable: token.value.clone(), value: Box::new(value), pos: token.pos }); return ASTPart::VarUpdate(AstVarUpdate { variable: token.value.clone(), value: Box::new(value), pos: token.pos });
} else { } else {
let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
} else { } else {
let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }

View file

@ -1,5 +1,5 @@
use std::{any::Any, collections::HashMap, process, vec}; use std::{any::Any, collections::HashMap, process, vec};
use crate::{decompiler::{operation_to_name, process, DecompiledFunction, DecompiledOperation}, enviroment, errors::{create_error, print_error, ErrorSubType, ErrorType}, Context}; use crate::{decompiler::{operation_to_name, process, DecompiledFunction, DecompiledOperation}, enviroment, errors::{create_error, print_error, ASLError, ErrorSubType, ErrorType}, Context};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum VMMemory { pub enum VMMemory {
@ -64,6 +64,14 @@ pub struct CallStack {
pub pc: usize, pub pc: usize,
} }
#[derive(Debug, Clone)]
enum VMState {
Running,
Paused,
Finished,
Error(ASLError),
}
pub struct Machine { pub struct Machine {
pub memory: Vec<VMMemory>, pub memory: Vec<VMMemory>,
functions: Vec<DecompiledFunction>, functions: Vec<DecompiledFunction>,
@ -73,6 +81,7 @@ pub struct Machine {
pub env: HashMap<String, VMMemory>, pub env: HashMap<String, VMMemory>,
pub ctx: Vec<Context>, pub ctx: Vec<Context>,
pub storage: Vec<Box<dyn Any>>, pub storage: Vec<Box<dyn Any>>,
pub state: VMState,
} }
fn get_register_by_id(registers: &Vec<Register>, id: u8) -> Option<&Register> { fn get_register_by_id(registers: &Vec<Register>, id: u8) -> Option<&Register> {
@ -181,14 +190,14 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8); let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
let reg3 = get_register_by_id(&reg_clone, operation.arg3); let reg3 = get_register_by_id(&reg_clone, operation.arg3);
if reg1.is_none() || reg2.is_none() || reg3.is_none() { if reg1.is_none() || reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("One or more registers not found for operation"), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("One or more registers not found for operation"), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
let mem1 = reg1.unwrap().pointer; let mem1 = reg1.unwrap().pointer;
let mem2 = reg2.unwrap().pointer; let mem2 = reg2.unwrap().pointer;
if mem1 >= memory.len() || mem2 >= memory.len() || mem1 < 1 || mem2 < 1 { if mem1 >= memory.len() || mem2 >= memory.len() || mem1 < 1 || mem2 < 1 {
let err = create_error(&format!("Memory location out of bounds `{}` or `{}`", mem1, mem2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location out of bounds `{}` or `{}`", mem1, mem2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -207,7 +216,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
}, },
13 => { 13 => {
if num2.value == 0.0 { if num2.value == 0.0 {
let err = create_error(&format!("Division by zero"), operation.pos, ErrorType::MathError, ErrorSubType::DivisionByZero); let err = create_error(&format!("Division by zero"), operation.pos, ErrorType::MathError, ErrorSubType::DivisionByZero, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -238,7 +247,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value <= num2.value, variable_id: 0 }); result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value <= num2.value, variable_id: 0 });
}, },
_ => { _ => {
let err = create_error(&format!("Unknown operation code for number operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode); let err = create_error(&format!("Unknown operation code for number operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -256,7 +265,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: str1.value != str2.value, variable_id: 0 }); result = VMMemory::Boolean(VMMemoryBoolean { value: str1.value != str2.value, variable_id: 0 });
}, },
_ => { _ => {
let err = create_error(&format!("Unknown operation code for string operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode); let err = create_error(&format!("Unknown operation code for string operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -277,7 +286,7 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value != bool2.value, variable_id: 0 }); result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value != bool2.value, variable_id: 0 });
}, },
_ => { _ => {
let err = create_error(&format!("Unknown operation code for boolean operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode); let err = create_error(&format!("Unknown operation code for boolean operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -292,14 +301,14 @@ fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemo
result = VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 }); result = VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 });
}, },
_ => { _ => {
let err = create_error(&format!("Unknown operation code for null operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode); let err = create_error(&format!("Unknown operation code for null operation: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
}; };
}, },
_ => { _ => {
let err = create_error(&format!("Wrong memory types for operation: `{}`, position: `{}` and `{}`", operation_to_name(operation.opcode), mem1, mem2), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType); let err = create_error(&format!("Wrong memory types for operation: `{}`, position: `{}` and `{}`", operation_to_name(operation.opcode), mem1, mem2), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, ctx);
print_error(&err, &ctx); print_error(&err, &ctx);
process::exit(1); process::exit(1);
} }
@ -339,15 +348,23 @@ impl Machine {
env: enviroment::generate(), env: enviroment::generate(),
ctx: ctx, ctx: ctx,
storage: Vec::new(), storage: Vec::new(),
state: VMState::Finished
}; };
} }
pub fn load(&mut self, data: &Vec<u8>) { pub fn load(&mut self, data: &Vec<u8>) {
let dec = process(data); let dec = process(data);
self.functions = dec.functions; self.functions = dec.functions;
self.state = VMState::Paused
} }
pub fn run(&mut self) { pub fn resume(&mut self) {
match self.state {
VMState::Paused => {},
_ => {
panic!("Unable to resume VM, current state is not paused");
}
};
if self.call_stack.len() == 0 { if self.call_stack.len() == 0 {
return; return;
} }
@ -355,12 +372,19 @@ impl Machine {
let executed_func = func_clone.get(self.call_stack[self.call_stack.len()-1].func); let executed_func = func_clone.get(self.call_stack[self.call_stack.len()-1].func);
let mut executed_stack = self.call_stack.len()-1; let mut executed_stack = self.call_stack.len()-1;
if executed_func.is_none() { if executed_func.is_none() {
let err = create_error(&format!("Current function not found"), 1, ErrorType::MachineError, ErrorSubType::UnknownFunction); let err = create_error(&format!("Current function not found"), 1, ErrorType::MachineError, ErrorSubType::UnknownFunction, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let mut executed_func = executed_func.unwrap(); let mut executed_func = executed_func.unwrap();
self.state = VMState::Running;
while self.call_stack[executed_stack].pc < executed_func.body.len() { while self.call_stack[executed_stack].pc < executed_func.body.len() {
match self.state {
VMState::Running => {},
_ => {
return;
}
};
let operation = &executed_func.body[self.call_stack[executed_stack].pc]; let operation = &executed_func.body[self.call_stack[executed_stack].pc];
self.call_stack[executed_stack].pc += 1; self.call_stack[executed_stack].pc += 1;
match operation.opcode { match operation.opcode {
@ -372,7 +396,7 @@ impl Machine {
//LDS //LDS
let str = executed_func.strings.get(&(operation.arg2 as u32)); let str = executed_func.strings.get(&(operation.arg2 as u32));
if str.is_none() { if str.is_none() {
let err = create_error(&format!("String with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownString); let err = create_error(&format!("String with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownString, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -384,13 +408,13 @@ impl Machine {
//LDM //LDM
let mem = get_mem_pos_by_var_id(&self.memory, operation.arg2 as u32); let mem = get_mem_pos_by_var_id(&self.memory, operation.arg2 as u32);
if mem.is_none() { if mem.is_none() {
let err = create_error(&format!("Memory with variable ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation); let err = create_error(&format!("Memory with variable ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let mem = mem.unwrap(); let mem = mem.unwrap();
if mem >= self.memory.len() || mem < 1 { if mem >= self.memory.len() || mem < 1 {
let err = create_error(&format!("Memory location out of bounds for variable ID `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location out of bounds for variable ID `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -435,14 +459,14 @@ impl Machine {
//LDF //LDF
let func_pos = executed_func.functions.get(&(operation.arg2 as u32)); let func_pos = executed_func.functions.get(&(operation.arg2 as u32));
if func_pos.is_none() { if func_pos.is_none() {
let err = create_error(&format!("Function with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction); let err = create_error(&format!("Function with ID `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let func_pos = func_pos.unwrap(); let func_pos = func_pos.unwrap();
let func = self.functions.get(*func_pos as usize); let func = self.functions.get(*func_pos as usize);
if func.is_none() { if func.is_none() {
let err = create_error(&format!("Function with position `{}` not found", func_pos), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction); let err = create_error(&format!("Function with position `{}` not found", func_pos), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownFunction, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -466,13 +490,13 @@ impl Machine {
//ASS //ASS
let reg = get_register_by_id(&self.registers, operation.arg1); let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() { if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let reg = reg.unwrap(); let reg = reg.unwrap();
if reg.pointer >= self.memory.len() || reg.pointer < 1 { if reg.pointer >= self.memory.len() || reg.pointer < 1 {
let err = create_error(&format!("Register `{}` points to an invalid memory location", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Register `{}` points to an invalid memory location", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -491,7 +515,7 @@ impl Machine {
let temp_regs = self.registers.clone(); let temp_regs = self.registers.clone();
let reg1 = get_register_by_id(&temp_regs, operation.arg1); let reg1 = get_register_by_id(&temp_regs, operation.arg1);
if reg1.is_none() { if reg1.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -507,13 +531,13 @@ impl Machine {
let reg1 = get_register_by_id(&reg_clone, operation.arg1); let reg1 = get_register_by_id(&reg_clone, operation.arg1);
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8); let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
if reg1.is_none() || reg2.is_none() { if reg1.is_none() || reg2.is_none() {
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let mem1 = reg1.unwrap().pointer; let mem1 = reg1.unwrap().pointer;
if mem1 >= self.memory.len() || mem1 < 1 { if mem1 >= self.memory.len() || mem1 < 1 {
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -523,7 +547,7 @@ impl Machine {
result = VMMemory::Boolean(VMMemoryBoolean { value: !bool.value, variable_id: 0 }); result = VMMemory::Boolean(VMMemoryBoolean { value: !bool.value, variable_id: 0 });
}, },
_ => { _ => {
let err = create_error(&format!("Wrong memory type for NOT operation, position: `{}`", mem1), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType); let err = create_error(&format!("Wrong memory type for NOT operation, position: `{}`", mem1), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -546,14 +570,14 @@ impl Machine {
//CJP //CJP
let reg = get_register_by_id(&self.registers, operation.arg1); let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() { if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let reg = reg.unwrap(); let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer); let mem = self.memory.get(reg.pointer);
if mem.is_none() { if mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation); let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -565,7 +589,7 @@ impl Machine {
} }
} }
_ => { _ => {
let err = create_error(&format!("Wrong memory type for CJP operation, position: `{}`", reg.pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType); let err = create_error(&format!("Wrong memory type for CJP operation, position: `{}`", reg.pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
}, },
@ -575,14 +599,14 @@ impl Machine {
//CAL //CAL
let reg = get_register_by_id(&self.registers, operation.arg1); let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() { if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let reg = reg.unwrap(); let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer); let mem = self.memory.get(reg.pointer);
if mem.is_none() { if mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation); let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownMemoryLocation, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -593,7 +617,7 @@ impl Machine {
for i in &self.stack { for i in &self.stack {
let mut new_mem = i.clone(); let mut new_mem = i.clone();
if self.functions[func.id].variables.len() <= arg || self.functions[func.id].variables[arg].start != 0 { if self.functions[func.id].variables.len() <= arg || self.functions[func.id].variables[arg].start != 0 {
let err = create_error(&format!("Too many arguments supplied for function: `{}`", func.id), operation.pos, ErrorType::SemanticError, ErrorSubType::TooManyArguments); let err = create_error(&format!("Too many arguments supplied for function: `{}`", func.id), operation.pos, ErrorType::SemanticError, ErrorSubType::TooManyArguments, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -610,7 +634,7 @@ impl Machine {
let mut result = (nfunc.func)(self, &operation, 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); let ret_reg = get_register_by_id(&self.registers, operation.arg2 as u8);
if ret_reg.is_none() { if ret_reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` not found", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -627,7 +651,7 @@ impl Machine {
self.stack.clear(); self.stack.clear();
}, },
_ => { _ => {
let err = create_error(&format!("Unable to call non-function type"), operation.pos, ErrorType::MachineError, ErrorSubType::NonFunctionCall); let err = create_error(&format!("Unable to call non-function type"), operation.pos, ErrorType::MachineError, ErrorSubType::NonFunctionCall, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -637,14 +661,14 @@ impl Machine {
//PSH //PSH
let reg = get_register_by_id(&self.registers, operation.arg1); let reg = get_register_by_id(&self.registers, operation.arg1);
if reg.is_none() { if reg.is_none() {
let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` not found", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let reg = reg.unwrap(); let reg = reg.unwrap();
let mem = self.memory.get(reg.pointer); let mem = self.memory.get(reg.pointer);
if mem.is_none() { if mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -656,13 +680,13 @@ impl Machine {
let target_reg = get_register_by_id(&self.registers, self.call_stack[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() {
let err = create_error(&format!("Register `{}` or `{}` not found", self.call_stack[executed_stack].return_reg, operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` or `{}` not found", self.call_stack[executed_stack].return_reg, operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let ret_mem = self.memory.get(ret_reg.unwrap().pointer); let ret_mem = self.memory.get(ret_reg.unwrap().pointer);
if ret_mem.is_none() { if ret_mem.is_none() {
let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location not found for register `{}`", operation.arg1), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -686,13 +710,13 @@ impl Machine {
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8); let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
let reg3 = get_register_by_id(&reg_clone, operation.arg3); let reg3 = get_register_by_id(&reg_clone, operation.arg3);
if reg2.is_none() || reg3.is_none() { if reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` or `{}` not found", operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let mem2 = self.memory.get(reg2.unwrap().pointer); let mem2 = self.memory.get(reg2.unwrap().pointer);
if mem2.is_none() { if mem2.is_none() {
let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location out of bounds for register `{}`", operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -708,7 +732,7 @@ impl Machine {
} }
}, },
_ => { _ => {
let err = create_error(&format!("Only string keys are allowed for GET enviroment"), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType); let err = create_error(&format!("Only string keys are allowed for GET enviroment"), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -728,14 +752,14 @@ impl Machine {
let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8); let reg2 = get_register_by_id(&reg_clone, operation.arg2 as u8);
let reg3 = get_register_by_id(&reg_clone, operation.arg3); let reg3 = get_register_by_id(&reg_clone, operation.arg3);
if reg.is_none() || reg2.is_none() || reg3.is_none() { if reg.is_none() || reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
let mem1 = self.memory.get(reg.unwrap().pointer); let mem1 = self.memory.get(reg.unwrap().pointer);
let mem2 = self.memory.get(reg2.unwrap().pointer); let mem2 = self.memory.get(reg2.unwrap().pointer);
if mem1.is_none() || mem2.is_none() { if mem1.is_none() || mem2.is_none() {
let err = create_error(&format!("Memory location not found for register `{}` or `{}`", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location not found for register `{}` or `{}`", operation.arg1, operation.arg2), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -752,7 +776,7 @@ impl Machine {
} }
}, },
_ => { _ => {
let err = create_error(&format!("Wrong memory type for GET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType); let err = create_error(&format!("Wrong memory type for GET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -773,7 +797,7 @@ impl Machine {
let reg2 = get_register_by_id(&self.registers, operation.arg2 as u8); let reg2 = get_register_by_id(&self.registers, operation.arg2 as u8);
let reg3 = get_register_by_id(&self.registers, operation.arg3); let reg3 = get_register_by_id(&self.registers, operation.arg3);
if reg.is_none() || reg2.is_none() || reg3.is_none() { if reg.is_none() || reg2.is_none() || reg3.is_none() {
let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound); let err = create_error(&format!("Register `{}` or `{}` or `{}` not found", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::RegisterNotFound, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -781,7 +805,7 @@ impl Machine {
let mem2 = self.memory.get(reg2.unwrap().pointer); let mem2 = self.memory.get(reg2.unwrap().pointer);
let mem3 = self.memory.get(reg3.unwrap().pointer); let mem3 = self.memory.get(reg3.unwrap().pointer);
if mem1.is_none() || mem2.is_none() || mem3.is_none() { if mem1.is_none() || mem2.is_none() || mem3.is_none() {
let err = create_error(&format!("Memory location not found for register `{}` or `{}` or `{}`", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds); let err = create_error(&format!("Memory location not found for register `{}` or `{}` or `{}`", operation.arg1, operation.arg2, operation.arg3), operation.pos, ErrorType::MachineError, ErrorSubType::MemoryOutOfBounds, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
@ -793,18 +817,19 @@ impl Machine {
set_mem_tbl_val(tbl, mem2, mem3); set_mem_tbl_val(tbl, mem2, mem3);
}, },
_ => { _ => {
let err = create_error(&format!("Wrong memory type for SET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType); let err = create_error(&format!("Wrong memory type for SET operation, position: `{}`", reg.unwrap().pointer), operation.pos, ErrorType::TypeError, ErrorSubType::WrongType, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
} }
}, },
_ => { _ => {
let err = create_error(&format!("Unknown operation code: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode); let err = create_error(&format!("Unknown operation code: `{}`", operation.opcode), operation.pos, ErrorType::MachineError, ErrorSubType::UnknownOPCode, &self.ctx[self.call_stack[executed_stack].func].clone());
print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone()); print_error(&err, &self.ctx[self.call_stack[executed_stack].func].clone());
process::exit(1); process::exit(1);
} }
} }
} }
self.state = VMState::Finished;
} }
} }