Skip to content

Commit

Permalink
Begun work towards heap allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-M-Lucas committed Jul 27, 2024
1 parent a9a9030 commit d3a4bec
Show file tree
Hide file tree
Showing 19 changed files with 237 additions and 131 deletions.

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ nom-supreme = "0.8.0"
substring = "1.4.5"
derive-getters = "0.4.0"
derive_more = "0.99.18"
termsize = "0.1.9"

[profile.release]
opt-level = 3
Expand Down
114 changes: 34 additions & 80 deletions build/out.asm
Original file line number Diff line number Diff line change
Expand Up @@ -5,98 +5,52 @@ section .text
main:
push rbp
mov rbp, rsp
mov qword [rbp-16], 3
mov qword [rbp-8], 4
mov rax, rbp
add rax, -16
mov qword [rbp-24], rax
mov rax, rbp
add rax, -16
; Heap Alloc
mov qword [rbp-24], 3
mov qword [rbp-16], 4
mov rdi, 16
sub rsp, 24
extern malloc
call malloc
sub rsp, 24
mov qword [rbp-32], rax
mov rdx, qword [rbp-32]
mov rax, qword [rbp-24]
mov qword [rdx+0], rax
mov rax, qword [rbp-16]
mov qword [rdx+8], rax
mov rax, qword [rbp-32]
mov qword [rbp-40], rax
sub rsp, 40
call _3
add rsp, 40
mov rax, rbp
add rax, -16
mov qword [rbp-40], rax
mov rax, qword [rbp-40]
mov qword [rbp-8], rax
; Unheap
mov rdx, qword [rbp-8]
mov rax, qword [rdx+0]
mov qword [rbp-48], rax
sub rsp, 48
call _4
add rsp, 48
mov qword [rbp-48], 2
mov rax, qword [rbp-24]
mov rdx, qword [rbp-48]
add qword [rax], rdx
mov rax, qword [rdx+8]
mov qword [rbp-40], rax
; Get member
mov rax, rbp
add rax, -16
add rax, -48
mov qword [rbp-56], rax
mov rax, qword [rbp-56]
; Deref member
mov rdx, qword [rbp-56]
mov rax, qword [rdx+0]
mov qword [rbp-64], rax
sub rsp, 64
call _3
add rsp, 64
mov qword [rbp-64], 7
; Print
mov rax, qword [rbp-64]
leave
ret


_3:
push rbp
mov rbp, rsp
mov rax, [rbp+16]
add rax, 0
mov qword [rbp-16], rax
mov rdx, qword [rbp-16]
mov rax, qword [rdx+0]
mov qword [rbp-8], rax
mov rdi, __8_fstr
mov rsi, [rbp-8]
mov al, 0
sub rsp, 16
extern printf
call printf
add rsp, 16
mov rax, [rbp+16]
add rax, 8
mov qword [rbp-32], rax
mov rdx, qword [rbp-32]
mov rax, qword [rdx+0]
mov qword [rbp-24], rax
mov qword [rbp-72], rax
mov rdi, __8_fstr
mov rsi, [rbp-24]
mov rsi, [rbp-72]
mov al, 0
sub rsp, 32
sub rsp, 72
extern printf
call printf
add rsp, 32

leave
ret

_4:
push rbp
mov rbp, rsp
mov rax, [rbp+16]
add rax, 0
mov qword [rbp-8], rax
mov qword [rbp-16], 1
mov rax, qword [rbp-8]
mov rdx, qword [rbp-16]
add qword [rax], rdx
mov rax, [rbp+16]
add rax, 8
mov qword [rbp-24], rax
mov qword [rbp-32], 1
mov rax, qword [rbp-24]
mov rdx, qword [rbp-32]
add qword [rax], rdx
add rsp, 72
; Return
mov qword [rbp-80], 7
mov rax, qword [rbp-80]
leave
ret

leave
ret

section .data_readonly
__8_fstr db `Integer: %ld\n`,0
Binary file modified build/out.o
Binary file not shown.
Binary file modified build/out.out
Binary file not shown.
32 changes: 8 additions & 24 deletions main.why
Original file line number Diff line number Diff line change
@@ -1,31 +1,15 @@
struct MyStruct {
a: int,
b: int
struct LL {
has_node: bool,
first: &Node
}

impl MyStruct {
fn print(&self) {
printi(*self.a);
printi(*self.b);
}

fn increment(&self) {
self.a += 1;
self.b += 1;
}
struct Node {
val: int,
has_next: bool,
next: &Node
}

fn main() -> int {
let x: MyStruct = MyStruct {
a: 3,
b: 4
};
let y: &int = x.a;

x.print();
x.increment();
y += 2;
x.print();

return 7;
let r: LL = LL { has_node: false, first: Node::null() };
}
13 changes: 12 additions & 1 deletion src/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,18 @@ pub fn main_args(args: Args) -> Result<(), WErr> {
if args.build {
println!("Skipping execution")
} else {
println!("Executing...");
let termsize::Size {rows, cols} = termsize::get().unwrap();
const EXECUTING: &str = "Executing";
if cols < EXECUTING.len() as u16 || cols > 300 {
cprintln!("<s><b>Executing...</>");
}
else {
let padl = (cols - EXECUTING.len() as u16) / 2;
let padr = if ((cols - EXECUTING.len() as u16) % 2) == 1 {
padl + 1
} else { padl };
cprintln!("<s><b>{}{}{}</>", "-".repeat(padl as usize), EXECUTING, "-".repeat(padr as usize));
}
run(&args.output);
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/root/compiler/assembly/heap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::root::assembler::assembly_builder::AssemblyBuilder;
use crate::root::compiler::local_variable_table::LocalVariableTable;
use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable;
use crate::root::shared::common::{AddressedTypeRef, TypeRef};

pub fn heap_alloc(t: TypeRef, global_table: &mut GlobalDefinitionTable, local_variable_table: &mut LocalVariableTable) -> (String, AddressedTypeRef) {
let size = global_table.get_size(&t).0;
let sz = local_variable_table.stack_size().0;
let output = global_table.add_local_variable_unnamed_base(t.plus_one_indirect(), local_variable_table);

(format!(" mov rdi, {size}
sub rsp, {sz}
extern malloc
call malloc
sub rsp, {sz}
mov qword {}, rax\n", output.local_address()), output)

}
1 change: 1 addition & 0 deletions src/root/compiler/assembly/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod utils;
pub mod heap;
3 changes: 2 additions & 1 deletion src/root/compiler/compile_function.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use color_print::cprintln;
use crate::root::assembler::assembly_builder::AssemblyBuilder;
use crate::root::builtin::types::bool::BoolType;
use crate::root::builtin::types::int::IntType;
Expand Down Expand Up @@ -329,7 +330,7 @@ fn recursively_compile_lines(
}
#[cfg(debug_assertions)]
LineTokens::Marker(value) => {
println!("\nCompiling marker [{}]", value.value());
cprintln!("\n<s><m!>At Compilation Marker:</> '{}'", value.value());
contents.line(&format!(";{}", value.value()));
}
}
Expand Down
20 changes: 19 additions & 1 deletion src/root/compiler/evaluation/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::root::shared::types::Type;
use either::{Left, Right};
use itertools::Itertools;
use std::any::Any;
use crate::root::compiler::evaluation::new::compile_evaluable_new;
use crate::root::parser::parse::Location;

/// Evaluates `et` putting the result into `target`
Expand Down Expand Up @@ -383,10 +384,27 @@ pub fn compile_evaluable_into(
}
EvaluableTokens::StructInitialiser(struct_init) => {
let t = global_table.resolve_to_type_ref(struct_init.name())?;

if *struct_init.heap_alloc() {
if target.type_ref() != &t.plus_one_indirect() {
todo!()
}
let mut ab = AssemblyBuilder::new();
let (c, sr) = compile_evaluable_new(fid, et, local_variables, global_table, global_tracker)?;
ab.other(&c);
let sr = sr.unwrap();
ab.other(&copy(*sr.local_address(), *target.local_address(), global_table.get_size(target.type_ref())));
return Ok(ab.finish());
}
debug_assert!(!t.indirection().has_indirection());
if &t != target.type_ref() {

if *struct_init.heap_alloc() && &t.plus_one_indirect() != target.type_ref() {
todo!()
}
if !struct_init.heap_alloc() && &t != target.type_ref() {
todo!();
}

let tt = global_table.get_type(t.type_id().clone());
let attributes = tt.get_attributes()?.iter().map(|x| x.clone()).collect_vec();
let give_attrs = struct_init.contents();
Expand Down
40 changes: 27 additions & 13 deletions src/root/compiler/evaluation/new.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
use either::{Left, Right};
use itertools::Itertools;

use crate::root::assembler::assembly_builder::AssemblyBuilder;
use crate::root::builtin::core::referencing::{set_deref, set_reference};
use crate::root::compiler::assembly::heap::heap_alloc;
use crate::root::compiler::assembly::utils::{
copy, copy_from_indirect_fixed_offset, copy_to_indirect,
copy, copy_to_indirect,
};
use crate::root::compiler::compile_function_call::call_function;
use crate::root::compiler::evaluation::coerce_self::coerce_self;
use crate::root::compiler::evaluation::reference::compile_evaluable_reference;
use crate::root::compiler::evaluation::{function_only, into, reference, type_only};
use crate::root::compiler::evaluation::reference::compile_evaluable_reference;
use crate::root::compiler::global_tracker::GlobalTracker;
use crate::root::compiler::local_variable_table::LocalVariableTable;
use crate::root::errors::evaluable_errors::EvalErrs;
use crate::root::errors::evaluable_errors::EvalErrs::{ExpectedNotNone, ExpectedReference};
use crate::root::errors::name_resolver_errors::NRErrs;
use crate::root::errors::WErr;
use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable, NameResult};
use crate::root::parser::parse::Location;
use crate::root::parser::parse_function::parse_evaluable::{EvaluableToken, EvaluableTokens};
use crate::root::parser::parse_function::parse_operator::{OperatorTokens, PrefixOrInfixEx};
use crate::root::parser::parse_parameters::SelfType;
use crate::root::shared::common::{
AddressedTypeRef, FunctionID, Indirection, LocalAddress, TypeRef,
};
use crate::root::shared::types::Type;
use either::{Left, Right};
use itertools::Itertools;
use crate::root::parser::parse::Location;

/// Evaluates `et` into a new address
pub fn compile_evaluable_new(
Expand Down Expand Up @@ -409,8 +409,17 @@ pub fn compile_evaluable_new(
}
EvaluableTokens::StructInitialiser(struct_init) => {
let t = global_table.resolve_to_type_ref(struct_init.name())?;
debug_assert!(!t.indirection().has_indirection());
let target = global_table.add_local_variable_unnamed_base(t.clone(), local_variables);
let size = global_table.get_size(&t);

let mut code = AssemblyBuilder::new();

let target = // if struct_init.heap_alloc() {
// let (c, ref_target) = heap_alloc(t.clone(), global_table, local_variables);
// code.other(&c);
// ref_target
// } else {
global_table.add_local_variable_unnamed_base(t.clone(), local_variables)
/* } */;

let tt = global_table.get_type(t.type_id().clone());
let attributes = tt.get_attributes()?.iter().map(|x| x.clone()).collect_vec();
Expand All @@ -420,9 +429,6 @@ pub fn compile_evaluable_new(
todo!()
}

let mut code = AssemblyBuilder::new();

// TODO: Doable without clone?
for ((offset, t_name, t_type), (name, val)) in attributes.iter().zip(give_attrs.iter())
{
if t_name.name() != name.name() {
Expand All @@ -443,7 +449,15 @@ pub fn compile_evaluable_new(
)?);
}

(code.finish(), Some(target))
if *struct_init.heap_alloc() {
let (c, ref_target) = heap_alloc(t, global_table, local_variables);
code.other(&c);
code.other(&copy_to_indirect(*target.local_address(), *ref_target.local_address(), size));
(code.finish(), Some(ref_target))
}
else {
(code.finish(), Some(target))
}
}
EvaluableTokens::None => (String::new(), None),
})
Expand Down
Loading

0 comments on commit d3a4bec

Please sign in to comment.