Compare commits
4 Commits
abcbe9d68b
...
dcfb3147ba
Author | SHA1 | Date | |
---|---|---|---|
|
dcfb3147ba | ||
|
b1cb4a0a0e | ||
|
92f7ec405d | ||
|
09ac457b9d |
30
project_euler/problem_1.qbl
Normal file
30
project_euler/problem_1.qbl
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import "../std.qbl"
|
||||||
|
|
||||||
|
true 3 0
|
||||||
|
while
|
||||||
|
{
|
||||||
|
// i sum
|
||||||
|
dup check req req +
|
||||||
|
incAndCheck req
|
||||||
|
}
|
||||||
|
|
||||||
|
deq intToStr println
|
||||||
|
|
||||||
|
function int => int check
|
||||||
|
{
|
||||||
|
3 dup % 0 req != req
|
||||||
|
// not_divisible start
|
||||||
|
if
|
||||||
|
{
|
||||||
|
5 dup % 0 req != req
|
||||||
|
if
|
||||||
|
{
|
||||||
|
deq 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function int => bool int incAndCheck
|
||||||
|
{
|
||||||
|
1 + 1000 dup < req
|
||||||
|
}
|
74
src/main.rs
74
src/main.rs
@ -357,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 = 4096;
|
const ASSEMBLY_LINUX_X64_QUEUE_LENGTH: u32 = 8192;
|
||||||
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";
|
||||||
@ -436,6 +436,22 @@ fn generate_assembly_linux_x64(operations: &Vec<Operation>, functions: &Vec<Func
|
|||||||
data.code += "\tmov rdi, -1\n";
|
data.code += "\tmov rdi, -1\n";
|
||||||
data.code += "\tsyscall\n";
|
data.code += "\tsyscall\n";
|
||||||
}
|
}
|
||||||
|
if data.code.contains("exception_queue_read_out_of_bounds")
|
||||||
|
{
|
||||||
|
data.strings += "\texception_queue_oob_msg db \"Queue overflow\", 10\n";
|
||||||
|
data.code += "exception_queue_read_out_of_bounds:\n";
|
||||||
|
//TODO: report the passed sizes
|
||||||
|
data.code += "\tmov rax, 1\n";
|
||||||
|
data.code += "\tmov rdi, 2\n";
|
||||||
|
// size
|
||||||
|
data.code += "\tmov rdx, 37\n";
|
||||||
|
// data
|
||||||
|
data.code += "\tmov rsi, exception_queue_oob_msg\n";
|
||||||
|
data.code += "\tsyscall\n";
|
||||||
|
data.code += "\tmov rax, 60\n";
|
||||||
|
data.code += "\tmov rdi, -1\n";
|
||||||
|
data.code += "\tsyscall\n";
|
||||||
|
}
|
||||||
|
|
||||||
return fs::write("out.asm", format!("{}{}{}{}", ASSEMBLY_LINUX_X64_HEADER, data.code, data.arrays, data.strings));
|
return fs::write("out.asm", format!("{}{}{}{}", ASSEMBLY_LINUX_X64_HEADER, data.code, data.arrays, data.strings));
|
||||||
}
|
}
|
||||||
@ -452,6 +468,13 @@ fn generate_assembly_linux_x64_array_oob_check(length: i64) -> String
|
|||||||
return data.clone();
|
return data.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_assembly_linux_x64_queue_oob_check() -> String
|
||||||
|
{
|
||||||
|
return "\t\t;;Queue bounds check\n".to_string() +
|
||||||
|
format!("\tcmp qword r13, {}\n", ASSEMBLY_LINUX_X64_QUEUE_LENGTH).as_str() +
|
||||||
|
"\tjge exception_queue_read_out_of_bounds\n\t\t;;Queue bounds over\n";
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, arrays: &Vec<Arr>, debug: bool) -> AssemblyData
|
fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, arrays: &Vec<Arr>, debug: bool) -> AssemblyData
|
||||||
{
|
{
|
||||||
let mut data = AssemblyData
|
let mut data = AssemblyData
|
||||||
@ -501,19 +524,39 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.code += "\tinc r13\n";
|
data.code += "\tinc r13\n";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
Operation::Requeue(line, col) =>
|
Operation::Requeue(line, col) =>
|
||||||
{
|
{
|
||||||
data.code += format!("\t;;req {}:{}\n", line, col).as_str();
|
data.code += format!("\t;;req {}:{}\n", line, col).as_str();
|
||||||
|
data.code += "\tmov rax, r13\n";
|
||||||
|
data.code += "\tsub rax, r12\n";
|
||||||
|
data.code += "\tcmp rax, 2\n";
|
||||||
|
data.code += format!("\tje req_{line}_{col}_special\n").as_str();
|
||||||
data.code += "\tmov rax, [queue+8*r12]\n";
|
data.code += "\tmov rax, [queue+8*r12]\n";
|
||||||
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;
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
|
data.code += format!("\tjmp req_{line}_{col}_end\n").as_str();
|
||||||
|
data.code += format!("req_{line}_{col}_special:\n").as_str();
|
||||||
|
data.code += "\tmov qword rax, [queue+8*r12]\n";
|
||||||
|
data.code += "\tmov qword rdi, [queue+8*r12+8]\n";
|
||||||
|
data.code += "\tmov qword r12, r14\n";
|
||||||
|
data.code += "\tmov qword r13, r14\n";
|
||||||
|
data.code += "\tmov qword [queue+8*r12], rdi\n";
|
||||||
|
data.code += "\tmov qword [queue+8*r12+8], rax\n";
|
||||||
|
data.code += "\tadd r13, 2\n";
|
||||||
|
data.code += format!("req_{line}_{col}_end:\n").as_str();
|
||||||
}
|
}
|
||||||
Operation::Swap(line, col) =>
|
Operation::Swap(line, col) =>
|
||||||
{
|
{
|
||||||
data.code += format!("\t;;swp {}:{}\n", line, col).as_str();
|
data.code += format!("\t;;swp {}:{}\n", line, col).as_str();
|
||||||
|
data.code += "\tmov rax, r13\n";
|
||||||
|
data.code += "\tsub rax, r12\n";
|
||||||
|
data.code += "\tcmp rax, 2\n";
|
||||||
|
data.code += format!("\tje swp_{line}_{col}_special\n").as_str();
|
||||||
data.code += "\tmov rax, [queue+8*r12]\n";
|
data.code += "\tmov rax, [queue+8*r12]\n";
|
||||||
data.code += "\tmov rbx, [queue+8*r12+8]\n";
|
data.code += "\tmov rbx, [queue+8*r12+8]\n";
|
||||||
data.code += "\tadd r12, 2\n";
|
data.code += "\tadd r12, 2\n";
|
||||||
@ -521,6 +564,17 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += "\tmov [queue+8*r13], rbx\n";
|
data.code += "\tmov [queue+8*r13], rbx\n";
|
||||||
data.code += "\tmov [queue+8*r13+8], rax\n";
|
data.code += "\tmov [queue+8*r13+8], rax\n";
|
||||||
data.code += "\tadd r13, 2\n";
|
data.code += "\tadd r13, 2\n";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
|
data.code += format!("\tjmp swp_{line}_{col}_end\n").as_str();
|
||||||
|
data.code += format!("swp_{line}_{col}_special:\n").as_str();
|
||||||
|
data.code += "\tmov qword rax, [queue+8*r12]\n";
|
||||||
|
data.code += "\tmov qword rdi, [queue+8*r12+8]\n";
|
||||||
|
data.code += "\tmov qword r12, r14\n";
|
||||||
|
data.code += "\tmov qword r13, r14\n";
|
||||||
|
data.code += "\tmov qword [queue+8*r12], rdi\n";
|
||||||
|
data.code += "\tmov qword [queue+8*r12+8], rax\n";
|
||||||
|
data.code += "\tadd r13, 2\n";
|
||||||
|
data.code += format!("swp_{line}_{col}_end:\n").as_str();
|
||||||
}
|
}
|
||||||
Operation::While(while_operations, line, col) =>
|
Operation::While(while_operations, line, col) =>
|
||||||
{
|
{
|
||||||
@ -561,6 +615,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += "\tmov rax, [queue+8*r12]\n";
|
data.code += "\tmov rax, [queue+8*r12]\n";
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
Operation::Intrinsic(name, line, col) =>
|
Operation::Intrinsic(name, line, col) =>
|
||||||
{
|
{
|
||||||
@ -616,6 +671,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += "\tcall intToStr\n";
|
data.code += "\tcall intToStr\n";
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"-" =>
|
"-" =>
|
||||||
{
|
{
|
||||||
@ -627,6 +683,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += "\tsub rax, rbx\n";
|
data.code += "\tsub rax, rbx\n";
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"+" =>
|
"+" =>
|
||||||
{
|
{
|
||||||
@ -638,6 +695,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += "\tadd rax, rbx\n";
|
data.code += "\tadd rax, rbx\n";
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"*" =>
|
"*" =>
|
||||||
{
|
{
|
||||||
@ -649,6 +707,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += "\tmul rbx\n";
|
data.code += "\tmul rbx\n";
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"divmod" =>
|
"divmod" =>
|
||||||
{
|
{
|
||||||
@ -661,8 +720,10 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += "\tidiv rbx\n";
|
data.code += "\tidiv rbx\n";
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
data.code += "\tmov [queue+8*r13], rdx\n";
|
data.code += "\tmov [queue+8*r13], rdx\n";
|
||||||
data.code += "\tinc r13\n";
|
data.code += "\tinc r13\n";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
">" =>
|
">" =>
|
||||||
{
|
{
|
||||||
@ -675,6 +736,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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 += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"<" =>
|
"<" =>
|
||||||
{
|
{
|
||||||
@ -687,6 +749,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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 += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
">=" =>
|
">=" =>
|
||||||
{
|
{
|
||||||
@ -699,6 +762,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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 += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"<=" =>
|
"<=" =>
|
||||||
{
|
{
|
||||||
@ -711,6 +775,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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 += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"==" =>
|
"==" =>
|
||||||
{
|
{
|
||||||
@ -723,6 +788,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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 += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"!=" =>
|
"!=" =>
|
||||||
{
|
{
|
||||||
@ -735,6 +801,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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 += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"&&" =>
|
"&&" =>
|
||||||
{
|
{
|
||||||
@ -745,6 +812,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
_ => todo!("intrinsic {} {}:{}", name, line, col)
|
_ => todo!("intrinsic {} {}:{}", name, line, col)
|
||||||
}
|
}
|
||||||
@ -764,6 +832,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += format!("\tmov qword rbx, [arr_{}+8*rax]\n", name).as_str();
|
data.code += format!("\tmov qword rbx, [arr_{}+8*rax]\n", name).as_str();
|
||||||
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 += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
"write" =>
|
"write" =>
|
||||||
{
|
{
|
||||||
@ -780,6 +849,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
{
|
{
|
||||||
data.code += format!("\tmov qword [queue+8*r13], {}\n", array.length).as_str();
|
data.code += format!("\tmov qword [queue+8*r13], {}\n", array.length).as_str();
|
||||||
data.code += "\tinc r13\n";
|
data.code += "\tinc r13\n";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
_ => todo!("apply {}", word)
|
_ => todo!("apply {}", word)
|
||||||
}
|
}
|
||||||
@ -795,6 +865,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
|||||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||||
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";
|
||||||
|
data.code += generate_assembly_linux_x64_queue_oob_check().as_str();
|
||||||
}
|
}
|
||||||
data.code += "\t;; move pointers\n";
|
data.code += "\t;; move pointers\n";
|
||||||
// save the current base
|
// save the current base
|
||||||
@ -1494,6 +1565,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
|
||||||
{
|
{
|
||||||
|
if name == "test" {return "test_".to_string();}
|
||||||
return name.replace("-", "_").replace("+", "_").replace("%", "percent").replace("/", "slash");
|
return name.replace("-", "_").replace("+", "_").replace("%", "percent").replace("/", "slash");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user