added imports
This commit is contained in:
parent
ce93fb10d4
commit
b4f930d1c5
8 changed files with 91 additions and 14 deletions
|
@ -1,5 +1,5 @@
|
||||||
use std::{collections::HashMap, process, vec};
|
use std::{collections::HashMap, fs, process, vec};
|
||||||
use crate::{errors::{create_error, print_error, ErrorType, ErrorSubType}, parser::ASTPart, Context};
|
use crate::{errors::{create_error, print_error, ErrorSubType, ErrorType}, lexer::lex, parser::{parse, ASTPart}, Context};
|
||||||
|
|
||||||
const ASXVERSION: [u8; 3] = [0,1,0];
|
const ASXVERSION: [u8; 3] = [0,1,0];
|
||||||
|
|
||||||
|
@ -607,6 +607,42 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
|
||||||
let value_reg = do_ast_op(*tbl_set.value, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
let value_reg = do_ast_op(*tbl_set.value, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers, ctx, traceback);
|
||||||
ops.push(Operation { opcode: 31, arg1: Some(table_reg), arg2: Some(key_reg as i64), arg3: Some(value_reg), pos: tbl_set.pos as u32 });
|
ops.push(Operation { opcode: 31, arg1: Some(table_reg), arg2: Some(key_reg as i64), arg3: Some(value_reg), pos: tbl_set.pos as u32 });
|
||||||
},
|
},
|
||||||
|
ASTPart::Import(impr) => {
|
||||||
|
let fi = fs::read_to_string(&impr.path);
|
||||||
|
match fi {
|
||||||
|
Ok(data) => {
|
||||||
|
let imp_ctx = Context {
|
||||||
|
file: String::from(&impr.path),
|
||||||
|
raw_file: data.clone(),
|
||||||
|
c_funcid: 0,
|
||||||
|
known: true
|
||||||
|
};
|
||||||
|
let self_tb = PrevFunc {
|
||||||
|
variables: variables.clone(),
|
||||||
|
previous: Some(Box::new(traceback.clone())),
|
||||||
|
};
|
||||||
|
let lexed = lex(data, &imp_ctx);
|
||||||
|
let ast = parse(lexed, &imp_ctx);
|
||||||
|
let compiled = compile_function(ast, None, registers, next_var_id, &imp_ctx, &self_tb);
|
||||||
|
functions.insert(*next_function_id, compiled);
|
||||||
|
*next_function_id += 1;
|
||||||
|
let reg = allocate_register(registers);
|
||||||
|
if reg.unbind_before {
|
||||||
|
ops.push(Operation { opcode: 8, arg1: Some(reg.register), arg2: None, arg3: None, pos: impr.pos as u32 });
|
||||||
|
}
|
||||||
|
ops.push(Operation { opcode: 5, arg1: Some(reg.register), arg2: Some((*next_function_id-1) as i64), arg3: None, pos: impr.pos as u32 });
|
||||||
|
ops.push(Operation { opcode: 27, arg1: Some(reg.register), arg2: Some(reg.register as i64), arg3: None, pos: impr.pos as u32 });
|
||||||
|
set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count });
|
||||||
|
return reg.register;
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
let err = create_error(&format!("Failed to read file `{}`: {}", impr.path, e), impr.pos, ErrorType::IOError, ErrorSubType::FileError);
|
||||||
|
print_error(&err, &ctx);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub enum ErrorType {
|
||||||
TypeError,
|
TypeError,
|
||||||
MathError,
|
MathError,
|
||||||
MachineError,
|
MachineError,
|
||||||
|
IOError,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ErrorSubType {
|
pub enum ErrorSubType {
|
||||||
|
@ -36,6 +37,8 @@ pub enum ErrorSubType {
|
||||||
DivisionByZero,
|
DivisionByZero,
|
||||||
//Type errors
|
//Type errors
|
||||||
WrongType,
|
WrongType,
|
||||||
|
//IO errors
|
||||||
|
FileError
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ASLError {
|
pub struct ASLError {
|
||||||
|
@ -53,6 +56,7 @@ fn convert_types_to_string(typ: &ErrorType) -> String {
|
||||||
ErrorType::MathError => String::from("Math Error: "),
|
ErrorType::MathError => String::from("Math Error: "),
|
||||||
ErrorType::SemanticError => String::from("Semantic Error: "),
|
ErrorType::SemanticError => String::from("Semantic Error: "),
|
||||||
ErrorType::MachineError => String::from("Machine Error: "),
|
ErrorType::MachineError => String::from("Machine Error: "),
|
||||||
|
ErrorType::IOError => String::from("IO Error: "),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn convert_types_to_short(typ: &ErrorType) -> String {
|
fn convert_types_to_short(typ: &ErrorType) -> String {
|
||||||
|
@ -62,6 +66,7 @@ fn convert_types_to_short(typ: &ErrorType) -> String {
|
||||||
ErrorType::MathError => String::from("MT:"),
|
ErrorType::MathError => String::from("MT:"),
|
||||||
ErrorType::SemanticError => String::from("SM:"),
|
ErrorType::SemanticError => String::from("SM:"),
|
||||||
ErrorType::MachineError => String::from("MC:"),
|
ErrorType::MachineError => String::from("MC:"),
|
||||||
|
ErrorType::IOError => String::from("IO:"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn convert_subtypes_to_string(stype: &ErrorSubType) -> String {
|
fn convert_subtypes_to_string(stype: &ErrorSubType) -> String {
|
||||||
|
@ -88,6 +93,7 @@ fn convert_subtypes_to_string(stype: &ErrorSubType) -> String {
|
||||||
ErrorSubType::DivisionByZero => String::from("Division by zero"),
|
ErrorSubType::DivisionByZero => String::from("Division by zero"),
|
||||||
ErrorSubType::WrongType => String::from("Wrong type"),
|
ErrorSubType::WrongType => String::from("Wrong type"),
|
||||||
ErrorSubType::TooManyArguments => String::from("Too many arguments"),
|
ErrorSubType::TooManyArguments => String::from("Too many arguments"),
|
||||||
|
ErrorSubType::FileError => String::from("File error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
|
fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
|
||||||
|
@ -114,6 +120,7 @@ fn convert_subtypes_to_short(stype: &ErrorSubType) -> String {
|
||||||
ErrorSubType::DivisionByZero => String::from("DZ:"),
|
ErrorSubType::DivisionByZero => String::from("DZ:"),
|
||||||
ErrorSubType::WrongType => String::from("WT:"),
|
ErrorSubType::WrongType => String::from("WT:"),
|
||||||
ErrorSubType::TooManyArguments => String::from("TA:"),
|
ErrorSubType::TooManyArguments => String::from("TA:"),
|
||||||
|
ErrorSubType::FileError => String::from("FE:"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +140,9 @@ pub fn create_error(message: &str, position: usize, typ: ErrorType, stype: Error
|
||||||
fn get_exact_pos(file: &String, pos: usize) -> (usize, usize) {
|
fn get_exact_pos(file: &String, pos: usize) -> (usize, usize) {
|
||||||
let mut line = 1;
|
let mut line = 1;
|
||||||
let mut column = 1;
|
let mut column = 1;
|
||||||
|
if pos < 1 {
|
||||||
|
return (line, column);
|
||||||
|
}
|
||||||
for (i, c) in file.chars().enumerate() {
|
for (i, c) in file.chars().enumerate() {
|
||||||
if i == pos-1 {
|
if i == pos-1 {
|
||||||
return (line, column);
|
return (line, column);
|
||||||
|
@ -203,7 +213,11 @@ pub fn print_error(error: &ASLError, ctx: &Context) {
|
||||||
out.push_str(" ");
|
out.push_str(" ");
|
||||||
out.push_str(&" ".repeat(column - 1));
|
out.push_str(&" ".repeat(column - 1));
|
||||||
out.push_str("^ ");
|
out.push_str("^ ");
|
||||||
out.push_str(&error.message);
|
if error.message.len() < 1 {
|
||||||
|
out.push_str(&convert_subtypes_to_string(&error.subtype));
|
||||||
|
} else {
|
||||||
|
out.push_str(&error.message);
|
||||||
|
}
|
||||||
|
|
||||||
out.push_str("\n");
|
out.push_str("\n");
|
||||||
out.push_str(&(line+1).to_string());
|
out.push_str(&(line+1).to_string());
|
||||||
|
|
|
@ -113,7 +113,7 @@ fn generate_combinations(words: Vec<&str>) -> Vec<String> {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
fn read_identifier(splitted: &Vec<&str>, pos: &mut usize, out: &mut Vec<Token>) {
|
fn read_identifier(splitted: &Vec<&str>, pos: &mut usize, out: &mut Vec<Token>) {
|
||||||
let keywords = vec!["kraf","piszolj","ha nem geny akkor geny","ha nem geny","nem piszv","kopva","gethelj","ha geny","lőcsve","csecs","reti","piszv","amíg geny","nincs hám","szard le"];
|
let keywords = vec!["kraf","piszolj","ha nem geny akkor geny","ha nem geny","nem piszv","kopva","gethelj","ha geny","lőcsve","csecs","reti","piszv","amíg geny","nincs hám","szard le","hámozd","be","ba"];
|
||||||
let mut raw_keywords: Vec<String> = vec![];
|
let mut raw_keywords: Vec<String> = vec![];
|
||||||
for keyword in &keywords {
|
for keyword in &keywords {
|
||||||
let spi: Vec<&str> = keyword.split(" ").collect();
|
let spi: Vec<&str> = keyword.split(" ").collect();
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::fs;
|
||||||
use parser::ASTPart;
|
use parser::ASTPart;
|
||||||
use virtualmachine::Machine;
|
use virtualmachine::Machine;
|
||||||
|
|
||||||
|
|
||||||
mod lexer;
|
mod lexer;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod enviroment;
|
mod enviroment;
|
||||||
|
@ -131,6 +130,9 @@ fn log_ast_part(part: &ASTPart, prefix: String) {
|
||||||
println!("{} Value:", prefix);
|
println!("{} Value:", prefix);
|
||||||
log_ast_part(&tbl_set.value, format!("{} ", prefix));
|
log_ast_part(&tbl_set.value, format!("{} ", prefix));
|
||||||
},
|
},
|
||||||
|
ASTPart::Import(imp) => {
|
||||||
|
println!("{}{}: Import: {}", prefix, imp.pos, imp.path);
|
||||||
|
},
|
||||||
ASTPart::NOOP => println!("{}NOOP", prefix)
|
ASTPart::NOOP => println!("{}NOOP", prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,11 +146,11 @@ struct Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let inp = fs::read_to_string("./test.as");
|
let inp = fs::read_to_string("./test.asl");
|
||||||
match inp {
|
match inp {
|
||||||
Result::Ok(data) => {
|
Result::Ok(data) => {
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
file: String::from("./test.as"),
|
file: String::from("./test.asl"),
|
||||||
raw_file: data.clone(),
|
raw_file: data.clone(),
|
||||||
c_funcid: 0,
|
c_funcid: 0,
|
||||||
known: true
|
known: true
|
||||||
|
|
|
@ -25,6 +25,7 @@ pub enum ASTPart {
|
||||||
Table(AstTable),
|
Table(AstTable),
|
||||||
TableGet(AstTableGet),
|
TableGet(AstTableGet),
|
||||||
TableSet(AstTableSet),
|
TableSet(AstTableSet),
|
||||||
|
Import(AstImport),
|
||||||
NOOP
|
NOOP
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
@ -150,6 +151,11 @@ pub struct AstTableSet {
|
||||||
pub value: Box<ASTPart>,
|
pub value: Box<ASTPart>,
|
||||||
pub pos: usize
|
pub pos: usize
|
||||||
}
|
}
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct AstImport {
|
||||||
|
pub path: String,
|
||||||
|
pub pos: usize
|
||||||
|
}
|
||||||
|
|
||||||
fn is_end(input: &Token, end: &Vec<Token>) -> bool {
|
fn is_end(input: &Token, end: &Vec<Token>) -> bool {
|
||||||
for token in end {
|
for token in end {
|
||||||
|
@ -786,6 +792,28 @@ 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::Return(AstReturn { value: Box::new(value), pos: token.pos });
|
return ASTPart::Return(AstReturn { value: Box::new(value), pos: token.pos });
|
||||||
}
|
}
|
||||||
|
} else if token.value == "hámozd" {
|
||||||
|
let var = &input[*pos];
|
||||||
|
*pos += 1;
|
||||||
|
if var.typ != TokenType::IDENTIFIER {
|
||||||
|
let err = create_error(&format!("Expected identifier after hámozd"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected);
|
||||||
|
print_error(&err, &ctx);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
print_error(&err, &ctx);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
*pos += 1;
|
||||||
|
let path = &input[*pos];
|
||||||
|
if path.typ != TokenType::STRING {
|
||||||
|
let err = create_error(&format!("Expected string for hámozd"), path.pos, ErrorType::SyntaxError, ErrorSubType::Expected);
|
||||||
|
print_error(&err, &ctx);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
*pos += 1;
|
||||||
|
return ASTPart::Assigment(AstAssigment { variable: var.value.clone(), value: Box::new(ASTPart::Import(AstImport { path: path.value.clone(), pos: token.pos })), 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);
|
||||||
print_error(&err, &ctx);
|
print_error(&err, &ctx);
|
||||||
|
|
7
test.as
7
test.as
|
@ -1,7 +0,0 @@
|
||||||
gethelj a = 5
|
|
||||||
gethelj b = lőcsve() {
|
|
||||||
ugass(a, c)
|
|
||||||
}
|
|
||||||
gethelj c = 10
|
|
||||||
|
|
||||||
b()
|
|
2
test.asl
Normal file
2
test.asl
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
hámozd test be szaft"test2.asl"szaft
|
||||||
|
ugass(test)
|
2
test2.asl
Normal file
2
test2.asl
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ugass(szaft"Hell yeah!"szaft)
|
||||||
|
reti 1
|
Loading…
Add table
Add a link
Reference in a new issue