diff --git a/src/main.rs b/src/main.rs index 438e359..688c13c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,6 +95,7 @@ fn main() ("-", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Int]))), ("+", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Int]))), ("*", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Int]))), + ("divmod", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Int, Datatype::Int]))), ("<", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Bool]))), (">", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Bool]))), (">=", (Vec::from([Datatype::Int, Datatype::Int]), Vec::from([Datatype::Bool]))), @@ -356,7 +357,7 @@ fn merge_assemblies(data: &mut AssemblyData, data2: AssemblyData) data.strings += data2.strings.as_str(); } -const ASSEMBLY_LINUX_X64_QUEUE_LENGTH: u32 = 1024; +const ASSEMBLY_LINUX_X64_QUEUE_LENGTH: u32 = 4096; const ASSEMBLY_LINUX_X64_HEADER: &str = "format ELF64 executable 3\n"; const ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE: &str = "\tcmp r12, r13\n\tcmove r12, r14\n\tcmove r13, r14\n"; const ASSEMBLY_LINUX_X64_EXIT: &str = "\tmov rax, 60\n\tmov rdi, 0\n\tsyscall\n"; @@ -535,7 +536,6 @@ fn generate_assembly_linux_x64_block(operations: &Vec, functions: &Ve data.code += format!("while_{}_{}_end:\n", line, col).as_str(); data.code += "\tinc r12\n"; data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE; - } Operation::If(if_operations, maybe_else_operations, line, col) => { @@ -650,6 +650,20 @@ fn generate_assembly_linux_x64_block(operations: &Vec, functions: &Ve data.code += "\tmov [queue+8*r13], rax\n"; data.code += "\tinc r13\n"; } + "divmod" => + { + data.code += "\tmov qword rax, [queue+8*r12]\n"; + data.code += "\tmov qword rdx, 0\n"; + data.code += "\tinc r12\n"; + data.code += "\tmov qword rbx, [queue+8*r12]\n"; + data.code += "\tinc r12\n"; + data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE; + data.code += "\tidiv rbx\n"; + data.code += "\tmov [queue+8*r13], rax\n"; + data.code += "\tinc r13\n"; + data.code += "\tmov [queue+8*r13], rdx\n"; + data.code += "\tinc r13\n"; + } ">" => { data.code += "\tmov rbx, 0\n"; @@ -710,6 +724,18 @@ fn generate_assembly_linux_x64_block(operations: &Vec, functions: &Ve data.code += "\tmov qword [queue+8*r13], rbx\n"; data.code += "\tinc r13\n"; } + "!=" => + { + data.code += "\tmov rbx, 0\n"; + data.code += "\tmov rcx, 1\n"; + data.code += "\tmov rax, [queue+8*r12]\n"; + data.code += "\tcmp qword rax, [queue+8*r12+8]\n"; + data.code += "\tcmovne rbx, rcx\n"; + data.code += "\tadd r12, 2\n"; + data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE; + data.code += "\tmov qword [queue+8*r13], rbx\n"; + data.code += "\tinc r13\n"; + } "&&" => { data.code += "\tmov rax, [queue+8*r12]\n"; @@ -911,6 +937,13 @@ fn interpret_program(operations: &Vec, queue: &mut Vec, funct let multiplicant2 = queue.remove(0).parse::().unwrap(); queue.push((multiplicant1 * multiplicant2).to_string()); } + "divmod" => + { + let dividend = queue.remove(0).parse::().unwrap(); + let divisor = queue.remove(0).parse::().unwrap(); + queue.push((dividend / divisor).to_string()); + queue.push((dividend % divisor).to_string()); + } ">" => { let first = queue.remove(0).parse::().unwrap(); @@ -1461,7 +1494,7 @@ fn extract_arrays(tokens: &mut Vec, intrinsics: &HashMap<&str, (Vec String { - return name.replace("-", "_").replace("+", "_"); + return name.replace("-", "_").replace("+", "_").replace("%", "percent").replace("/", "slash"); } fn str_to_datatype(s: &str, line: i32, col: i32) -> Result diff --git a/std.qbl b/std.qbl index 920e95d..37af110 100644 --- a/std.qbl +++ b/std.qbl @@ -9,3 +9,13 @@ function bool => str boolToStr "false" } } + +function int int => int % +{ + divmod deq +} + +function int int => int / +{ + divmod req deq +} \ No newline at end of file