Add divmod

This commit is contained in:
0x4261756D 2023-07-28 03:01:13 +02:00
parent 95133360ee
commit abcbe9d68b
2 changed files with 46 additions and 3 deletions

View File

@ -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<Operation>, 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<Operation>, 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<Operation>, 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<Operation>, queue: &mut Vec<String>, funct
let multiplicant2 = queue.remove(0).parse::<i64>().unwrap();
queue.push((multiplicant1 * multiplicant2).to_string());
}
"divmod" =>
{
let dividend = queue.remove(0).parse::<i64>().unwrap();
let divisor = queue.remove(0).parse::<i64>().unwrap();
queue.push((dividend / divisor).to_string());
queue.push((dividend % divisor).to_string());
}
">" =>
{
let first = queue.remove(0).parse::<i64>().unwrap();
@ -1461,7 +1494,7 @@ fn extract_arrays(tokens: &mut Vec<Token>, intrinsics: &HashMap<&str, (Vec<Datat
fn sanitize_name(name: String) -> String
{
return name.replace("-", "_").replace("+", "_");
return name.replace("-", "_").replace("+", "_").replace("%", "percent").replace("/", "slash");
}
fn str_to_datatype(s: &str, line: i32, col: i32) -> Result<Datatype, String>

10
std.qbl
View File

@ -9,3 +9,13 @@ function bool => str boolToStr
"false"
}
}
function int int => int %
{
divmod deq
}
function int int => int /
{
divmod req deq
}