Add divmod
This commit is contained in:
parent
95133360ee
commit
abcbe9d68b
39
src/main.rs
39
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]))),
|
("+", (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]))),
|
(">", (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();
|
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_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_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";
|
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 += format!("while_{}_{}_end:\n", line, col).as_str();
|
||||||
data.code += "\tinc r12\n";
|
data.code += "\tinc r12\n";
|
||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
Operation::If(if_operations, maybe_else_operations, line, col) =>
|
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 += "\tmov [queue+8*r13], rax\n";
|
||||||
data.code += "\tinc r13\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";
|
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 += "\tmov qword [queue+8*r13], rbx\n";
|
||||||
data.code += "\tinc r13\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";
|
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();
|
let multiplicant2 = queue.remove(0).parse::<i64>().unwrap();
|
||||||
queue.push((multiplicant1 * multiplicant2).to_string());
|
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();
|
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
|
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>
|
fn str_to_datatype(s: &str, line: i32, col: i32) -> Result<Datatype, String>
|
||||||
|
Reference in New Issue
Block a user