diff --git a/docs/docs/asx.md b/docs/docs/asx.md index 04263d8..7062399 100644 --- a/docs/docs/asx.md +++ b/docs/docs/asx.md @@ -36,6 +36,8 @@ Ezt megtudod nézni a `ASL viewx ` parancs használatával. |Szövegek|Lásd: [Szövegek](#szövegek)|| |Funkciók száma|Elmondja, hogy a funkcióban mennyi funkció meghívás van.|4 bytes| |Funkciók|Lásd: [Funkció meghívások](#funkció-meghívások)|| +|Catch pos|Megmutatja a catch funkció helyzetét, csak try-ban. Normál funkciók esetén 0|4 bytes| +|Instrukciók száma|Elmondja, hogy a funkcióban mennyi instrukció van.|4 bytes| |Instukciók|Lásd: [Instrukciók](#instrukciók)|| ## Változók: diff --git a/src/compiler.rs b/src/compiler.rs index 6e98c67..33351e2 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -31,7 +31,8 @@ struct Compiled { operations: Vec, variables: Vec, strings: HashMap, - functions: HashMap + functions: HashMap, + try_catch: Option } #[derive(Debug, Clone)] @@ -238,7 +239,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va variables: variables.clone(), previous: Some(Box::new(traceback.clone())), }; - functions.insert(func_id, compile_function(func.body, Some(func.args), registers, next_var_id, ctx, &self_tb)); + functions.insert(func_id, compile_function(func.body, Some(func.args), registers, next_var_id, ctx, &self_tb, None)); *next_function_id += 1; let reg = allocate_register(registers); if reg.unbind_before { @@ -658,7 +659,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va }; 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); + let compiled = compile_function(ast, None, registers, next_var_id, &imp_ctx, &self_tb, None); functions.insert(*next_function_id, compiled); *next_function_id += 1; let reg = allocate_register(registers); @@ -677,12 +678,33 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va } } }, + ASTPart::TryCatch(tc) => { + let catch_f = compile_function(tc.catch_block.body, None, registers, next_var_id, ctx, traceback, None); + let mut try_f = compile_function(tc.try_block.body, None, registers, next_var_id, ctx, traceback, Some(0)); + let mut nextt_f = 1; + for (fid, _) in &try_f.functions { + if fid >= &nextt_f { + nextt_f = fid+1; + } + } + try_f.functions.insert(nextt_f, catch_f); + try_f.try_catch = Some(nextt_f); + functions.insert(*next_function_id, try_f); + *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: tc.pos as u32 }); + } + ops.push(Operation { opcode: 5, arg1: Some(reg.register), arg2: Some((*next_function_id-1) as f64), arg3: None, pos: tc.pos as u32 }); + ops.push(Operation { opcode: 27, arg1: Some(reg.register), arg2: None, arg3: None, pos: tc.pos as u32 }); + set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count }); + }, _ => {} } return 0; } -fn compile_function(ast: Vec, args: Option>, registers: &mut Vec, next_var_id: &mut u32, ctx: &Context, traceback: &PrevFunc) -> Compiled { +fn compile_function(ast: Vec, args: Option>, registers: &mut Vec, next_var_id: &mut u32, ctx: &Context, traceback: &PrevFunc, try_catch: Option) -> Compiled { let mut ops: Vec = vec![]; let mut variables: Vec = vec![]; @@ -727,6 +749,7 @@ fn compile_function(ast: Vec, args: Option>, registers: &mu variables, strings, functions, + try_catch }; } @@ -805,6 +828,14 @@ fn compile_body(compiled: Compiled, fpos: &mut usize, ctx: &Context) -> (Vec contexts.extend_from_slice(&context); additional.push(compiled); } + match compiled.try_catch { + Some(tc) => { + append_be_num(&mut output, 4, tc as usize); + }, + None => { + append_be_num(&mut output, 4, 0); + } + } //function body append_be_num(&mut output, 4, compiled.operations.len()); for ops in compiled.operations { @@ -851,7 +882,7 @@ pub fn compile(ast: Vec, ctx: &Context) -> (Vec, Vec) { variables: vec![], previous: None, }; - let compiled = compile_function(ast, None, &mut registers, &mut next_var_id, ctx, &empty_tb); + let compiled = compile_function(ast, None, &mut registers, &mut next_var_id, ctx, &empty_tb, None); let mut output: Vec = vec![]; //doctype specifier diff --git a/src/decompiler.rs b/src/decompiler.rs index ae39057..f572519 100644 --- a/src/decompiler.rs +++ b/src/decompiler.rs @@ -7,7 +7,8 @@ pub struct DecompiledFunction { pub body: Vec, pub variables: Vec, pub strings: HashMap, - pub functions: HashMap + pub functions: HashMap, + pub try_catch: u32, } #[derive(Debug, Clone)] pub struct DecompiledOperation { @@ -145,6 +146,8 @@ fn load_func(data: Vec, offset: &mut usize) -> DecompiledFunction { *offset += 4; functions.insert(func_id, func_pos); } + let try_catch = read_be_num(&data[*offset..*offset + 4]); + *offset += 4; let mut body: Vec = Vec::new(); let instr_len: usize = read_be_num(&data[*offset..*offset + 4]); *offset += 4; @@ -170,6 +173,7 @@ fn load_func(data: Vec, offset: &mut usize) -> DecompiledFunction { variables: variables, strings: strings, functions: functions, + try_catch: try_catch as u32, }; } diff --git a/src/main.rs b/src/main.rs index 1a24992..892827c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -183,6 +183,7 @@ fn main() { for (id, pos) in &func.functions { println!(" {}: {}", id, pos); } + println!(" Try/Catch: {}", func.try_catch); println!(" Body:"); //Print these under each other like when you tabulate let mut longest_cols: Vec = vec![0, 0, 0, 0]; diff --git a/src/parser.rs b/src/parser.rs index 3ec85e0..c5d8687 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -26,6 +26,7 @@ pub enum ASTPart { TableGet(AstTableGet), TableSet(AstTableSet), Import(AstImport), + TryCatch(AstTryCatch), NOOP } #[derive(Debug, Clone, PartialEq)] @@ -156,6 +157,12 @@ pub struct AstImport { pub path: String, pub pos: usize } +#[derive(Debug, Clone, PartialEq)] +pub struct AstTryCatch { + pub try_block: AstFunction, + pub catch_block: AstFunction, + pub pos: usize +} fn is_end(input: &Token, end: &Vec) -> bool { for token in end { @@ -857,6 +864,32 @@ fn next_operation(pos: &mut usize, input: &Vec, op_ends: &Vec, par let func = read_function(input, pos, true, ctx); return check_continue(pos, input, func, op_ends, parse_ends, ctx); } + } else if token.value == "piszolj" { + let func = read_function(input, pos, false, ctx); + let tryp = match func { + ASTPart::Function(f) => f, + _ => { + let err = create_error(&format!("Expected function body"), token.pos, ErrorType::SyntaxError, ErrorSubType::Expected); + print_error(&err, &ctx); + process::exit(1); + } + }; + 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); + print_error(&err, &ctx); + process::exit(1); + } + *pos += 1; + let func2 = read_function(input, pos, true, ctx); + let catchp = match func2 { + ASTPart::Function(f) => f, + _ => { + let err = create_error(&format!("Expected function body"), input[*pos].pos, ErrorType::SyntaxError, ErrorSubType::Expected); + print_error(&err, &ctx); + process::exit(1); + } + }; + return ASTPart::TryCatch(AstTryCatch { try_block: tryp, catch_block: catchp, pos: token.pos }); } else { let err = create_error(&format!("Unexpected `{:?}({})`", token.typ, token.value), token.pos, ErrorType::SyntaxError, ErrorSubType::Unexpected); print_error(&err, &ctx); diff --git a/test.asl b/test.asl index de2e50f..60adf39 100644 --- a/test.asl +++ b/test.asl @@ -1,11 +1,5 @@ -gethelj time = mennyi az idő() -ugass(time) -gethelj bemenet = joink() -ugass(bemenet) -gethelj time2 = mennyi az idő() -gethelj msg = szaft"Took: "szaft+bimbabemb(time2-time, szaft"string"szaft)+szaft"ms"szaft -ugass(msg) - -ugass(intéző.infó(szaft"test.asl"szaft)) -ugass(intéző.olvass(szaft"test.asl"szaft)) -ugass(intéző.írj(szaft"bimbabemb.txt"szaft,szaft"óóóóó bimbabemb!"szaft)) \ No newline at end of file +piszolj { + gethelj test = szaft"a"szaft+1 +} csecs(err) { + ugass(szaft"Hibás bemb"szaft) +} \ No newline at end of file