begin adding try/catch

This commit is contained in:
afonya 2025-06-18 12:56:54 +02:00
parent 8dee35c68f
commit 1a98959be0
Signed by: afonya
GPG key ID: EBB9C4CAFAAFB2DC
6 changed files with 82 additions and 17 deletions

View file

@ -36,6 +36,8 @@ Ezt megtudod nézni a `ASL viewx <fájl>` parancs használatával.
|Szövegek|Lásd: [Szövegek](#szövegek)|| |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 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)|| |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)|| |Instukciók|Lásd: [Instrukciók](#instrukciók)||
## Változók: ## Változók:

View file

@ -31,7 +31,8 @@ struct Compiled {
operations: Vec<Operation>, operations: Vec<Operation>,
variables: Vec<Variable>, variables: Vec<Variable>,
strings: HashMap<u32, String>, strings: HashMap<u32, String>,
functions: HashMap<u32, Compiled> functions: HashMap<u32, Compiled>,
try_catch: Option<u32>
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -238,7 +239,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
variables: variables.clone(), variables: variables.clone(),
previous: Some(Box::new(traceback.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; *next_function_id += 1;
let reg = allocate_register(registers); let reg = allocate_register(registers);
if reg.unbind_before { if reg.unbind_before {
@ -658,7 +659,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, va
}; };
let lexed = lex(data, &imp_ctx); let lexed = lex(data, &imp_ctx);
let ast = parse(lexed, &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); functions.insert(*next_function_id, compiled);
*next_function_id += 1; *next_function_id += 1;
let reg = allocate_register(registers); let reg = allocate_register(registers);
@ -677,12 +678,33 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec<Operation>, 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; return 0;
} }
fn compile_function(ast: Vec<ASTPart>, args: Option<Vec<String>>, registers: &mut Vec<RegisterState>, next_var_id: &mut u32, ctx: &Context, traceback: &PrevFunc) -> Compiled { fn compile_function(ast: Vec<ASTPart>, args: Option<Vec<String>>, registers: &mut Vec<RegisterState>, next_var_id: &mut u32, ctx: &Context, traceback: &PrevFunc, try_catch: Option<u32>) -> Compiled {
let mut ops: Vec<Operation> = vec![]; let mut ops: Vec<Operation> = vec![];
let mut variables: Vec<Variable> = vec![]; let mut variables: Vec<Variable> = vec![];
@ -727,6 +749,7 @@ fn compile_function(ast: Vec<ASTPart>, args: Option<Vec<String>>, registers: &mu
variables, variables,
strings, strings,
functions, functions,
try_catch
}; };
} }
@ -805,6 +828,14 @@ fn compile_body(compiled: Compiled, fpos: &mut usize, ctx: &Context) -> (Vec<u8>
contexts.extend_from_slice(&context); contexts.extend_from_slice(&context);
additional.push(compiled); 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 //function body
append_be_num(&mut output, 4, compiled.operations.len()); append_be_num(&mut output, 4, compiled.operations.len());
for ops in compiled.operations { for ops in compiled.operations {
@ -851,7 +882,7 @@ pub fn compile(ast: Vec<ASTPart>, ctx: &Context) -> (Vec<u8>, Vec<Context>) {
variables: vec![], variables: vec![],
previous: None, 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<u8> = vec![]; let mut output: Vec<u8> = vec![];
//doctype specifier //doctype specifier

View file

@ -7,7 +7,8 @@ pub struct DecompiledFunction {
pub body: Vec<DecompiledOperation>, pub body: Vec<DecompiledOperation>,
pub variables: Vec<Variable>, pub variables: Vec<Variable>,
pub strings: HashMap<u32, String>, pub strings: HashMap<u32, String>,
pub functions: HashMap<u32, u32> pub functions: HashMap<u32, u32>,
pub try_catch: u32,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DecompiledOperation { pub struct DecompiledOperation {
@ -145,6 +146,8 @@ fn load_func(data: Vec<u8>, offset: &mut usize) -> DecompiledFunction {
*offset += 4; *offset += 4;
functions.insert(func_id, func_pos); functions.insert(func_id, func_pos);
} }
let try_catch = read_be_num(&data[*offset..*offset + 4]);
*offset += 4;
let mut body: Vec<DecompiledOperation> = Vec::new(); let mut body: Vec<DecompiledOperation> = Vec::new();
let instr_len: usize = read_be_num(&data[*offset..*offset + 4]); let instr_len: usize = read_be_num(&data[*offset..*offset + 4]);
*offset += 4; *offset += 4;
@ -170,6 +173,7 @@ fn load_func(data: Vec<u8>, offset: &mut usize) -> DecompiledFunction {
variables: variables, variables: variables,
strings: strings, strings: strings,
functions: functions, functions: functions,
try_catch: try_catch as u32,
}; };
} }

View file

@ -183,6 +183,7 @@ fn main() {
for (id, pos) in &func.functions { for (id, pos) in &func.functions {
println!(" {}: {}", id, pos); println!(" {}: {}", id, pos);
} }
println!(" Try/Catch: {}", func.try_catch);
println!(" Body:"); println!(" Body:");
//Print these under each other like when you tabulate //Print these under each other like when you tabulate
let mut longest_cols: Vec<usize> = vec![0, 0, 0, 0]; let mut longest_cols: Vec<usize> = vec![0, 0, 0, 0];

View file

@ -26,6 +26,7 @@ pub enum ASTPart {
TableGet(AstTableGet), TableGet(AstTableGet),
TableSet(AstTableSet), TableSet(AstTableSet),
Import(AstImport), Import(AstImport),
TryCatch(AstTryCatch),
NOOP NOOP
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -156,6 +157,12 @@ pub struct AstImport {
pub path: String, pub path: String,
pub pos: usize 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<Token>) -> bool { fn is_end(input: &Token, end: &Vec<Token>) -> bool {
for token in end { for token in end {
@ -857,6 +864,32 @@ fn next_operation(pos: &mut usize, input: &Vec<Token>, op_ends: &Vec<Token>, par
let func = read_function(input, pos, true, ctx); let func = read_function(input, pos, true, ctx);
return check_continue(pos, input, func, op_ends, parse_ends, 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 { } 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);

View file

@ -1,11 +1,5 @@
gethelj time = mennyi az idő() piszolj {
ugass(time) gethelj test = szaft"a"szaft+1
gethelj bemenet = joink() } csecs(err) {
ugass(bemenet) ugass(szaft"Hibás bemb"szaft)
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))