prepare the error system for try/catch
This commit is contained in:
parent
1a98959be0
commit
3dd28cedd3
7 changed files with 146 additions and 118 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
112
src/parser.rs
112
src/parser.rs
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(®_clone, operation.arg2 as u8);
|
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||||
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
||||||
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(®_clone, operation.arg1);
|
let reg1 = get_register_by_id(®_clone, operation.arg1);
|
||||||
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||||
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(®_clone, operation.arg2 as u8);
|
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||||
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
||||||
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(®_clone, operation.arg2 as u8);
|
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||||
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue