Skip to content

Commit

Permalink
Improved operator support
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-M-Lucas committed Jun 8, 2024
1 parent b573fba commit ad80498
Show file tree
Hide file tree
Showing 17 changed files with 180 additions and 94 deletions.
73 changes: 47 additions & 26 deletions .idea/workspace.xml

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

50 changes: 12 additions & 38 deletions build/out.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,34 @@

section .text

_2:
push rbp
mov rbp, rsp
mov rax, qword [rbp+16]
mov qword [rbp-16], rax
mov rax, qword [rbp+24]
mov qword [rbp-24], rax
mov rax, qword [rbp-16]
add rax, qword [rbp-24]
mov qword [rbp-8], rax
mov qword [rbp-32], 1
mov rax, qword [rbp-8]
add rax, qword [rbp-32]
mov qword [rbp+32], rax
leave
ret

main:
push rbp
mov rbp, rsp
mov qword [rbp-16], 3
mov qword [rbp-24], 2
mov rax, qword [rbp-16]
mov qword [rbp-48], rax
mov qword [rbp-8], -12
mov rax, qword [rbp-8]
mov qword [rbp-24], rax
mov rax, qword [rbp-24]
mov qword [rbp-56], rax
sub rsp, 56
mov qword [rbp-40], rax
sub rsp, 40
call _1
add rsp, 56
mov rax, qword [rbp-40]
mov qword [rbp-8], rax
mov rax, qword [rbp-8]
add rsp, 40
mov rax, qword [rbp-32]
mov qword [rbp-16], rax
mov rax, qword [rbp-16]
leave
ret

_1:
push rbp
mov rbp, rsp
mov qword [rbp-8], 0
mov rax, qword [rbp+16]
mov qword [rbp-8], rax
mov rax, qword [rbp+24]
mov qword [rbp-16], rax
mov rax, qword [rbp-8]
mov qword [rbp-40], rax
mov rax, qword [rbp-16]
mov qword [rbp-48], rax
sub rsp, 48
call _2
add rsp, 48
mov rax, qword [rbp-32]
mov qword [rbp+32], rax
sub rax, qword [rbp-16]
mov qword [rbp+24], rax
leave
ret

Binary file modified build/out.o
Binary file not shown.
Binary file modified build/out.out
Binary file not shown.
11 changes: 4 additions & 7 deletions main.why
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
impl int {
fn sub(lhs: int, rhs: int) -> int {
return lhs == rhs;
}

fn eq(lhs: int, rhs: int) -> int {
return (lhs + rhs) + 1;
fn p_sub(self) -> Self {
return 0 - self;
}
}

fn main() -> int {
return 3 - 2;
let x: int = -12;
return -x;
}

1 change: 1 addition & 0 deletions src/root/builtin/int/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl BuiltinInlineFunction for IntAdd {

fn signature(&self) -> FunctionSignature {
FunctionSignature::new_inline_builtin(
true,
&[("lhs", IntType::id().immediate()), ("rhs", IntType::id().immediate())],
Some(IntType::id().immediate())
)
Expand Down
3 changes: 3 additions & 0 deletions src/root/builtin/int/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
mod add;
mod sub;

use b_box::b;
use unique_type_id::UniqueTypeId;
use crate::root::builtin::int::add::IntAdd;
use crate::root::builtin::int::sub::IntSub;
use crate::root::errors::WErr;
use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable;
use crate::root::parser::parse_function::parse_literal::{LiteralToken, LiteralTokens};
Expand All @@ -12,6 +14,7 @@ use crate::root::shared::types::Type;
pub fn register_int(global_table: &mut GlobalDefinitionTable) {
global_table.register_builtin_type(b!(IntType));
global_table.register_inline_function(&IntAdd);
global_table.register_inline_function(&IntSub);
}

#[derive(UniqueTypeId)]
Expand Down
46 changes: 46 additions & 0 deletions src/root/builtin/int/sub.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use unique_type_id::UniqueTypeId;
use crate::root::builtin::{BuiltinInlineFunction, InlineFunctionGenerator};
use crate::root::builtin::int::IntType;
use crate::root::errors::WErr;
use crate::root::name_resolver::name_resolvers::NameResult::Function;
use crate::root::name_resolver::resolve_function_signatures::FunctionSignature;

use crate::root::shared::common::{FunctionID, Indirection, LocalAddress, TypeID, TypeRef};

#[derive(UniqueTypeId)]
#[UniqueTypeIdType = "u16"]
pub struct IntSub;

impl BuiltinInlineFunction for IntSub {
fn id(&self) -> FunctionID {
FunctionID(-(IntSub::unique_type_id().0 as isize) - 1)
}

fn name(&self) -> &'static str {
"sub"
}

fn signature(&self) -> FunctionSignature {
FunctionSignature::new_inline_builtin(
true,
&[("lhs", IntType::id().immediate()), ("rhs", IntType::id().immediate())],
Some(IntType::id().immediate())
)
}

fn inline(&self) -> InlineFunctionGenerator {
|args: &[LocalAddress], return_into: Option<LocalAddress>| -> String {
let lhs = args[0];
let rhs = args[1];
let return_into = return_into.unwrap();
format!(
" mov rax, qword {lhs}
sub rax, qword {rhs}
mov qword {return_into}, rax")
}
}

fn parent_type(&self) -> Option<TypeID> {
Some(IntType::id())
}
}
52 changes: 39 additions & 13 deletions src/root/compiler/compile_evaluable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,16 @@ pub fn compile_evaluable_into(
t.instantiate_from_literal(target.local_address(), literal)?
}
EvaluableTokens::InfixOperator(lhs, op, rhs) => {
// if op.is_prefix_opt_t() {
// return Err(WErr::n(EvalErrs::FoundPrefixNotInfixOp(op.operator().to_str().to_string()), op.location().clone()));
// }

let mut code = String::new();

// let (mut code, lhs) = compile_evaluable(fid, lhs, local_variables, global_table, function_calls)?;
let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, function_calls)?;
// code += "\n";
let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Infix)?;
let signature = global_table.get_function_signature(op_fn);

if signature.args().len() != 2 {
return Err(
WErr::n(
EvalErrs::OpWrongArgumentCount(
EvalErrs::InfixOpWrongArgumentCount(
op.operator().to_str().to_string(),
global_table.get_type(*lhs_type.type_id()).name().to_string(),
op.operator().get_method_name(PrefixOrInfixEx::Infix).unwrap(),
Expand All @@ -127,18 +121,50 @@ pub fn compile_evaluable_into(
}
}

// let rhs_type_target = signature.args()[1].1.clone();
// let rhs_box = global_table.add_local_variable_unnamed_base(rhs_type_target, local_variables);
// code += &compile_evaluable_into(fid, rhs, rhs_box.clone(), local_variables, global_table, function_calls)?;
// code += "\n";

let (c, _) = call_function(fid, op_fn, &[Left(lhs), Left(rhs)], Some(target), global_table, local_variables, function_calls)?;

code += &c;

code
},
EvaluableTokens::PrefixOperator(_, _) => todo!(),
EvaluableTokens::PrefixOperator(op, lhs) => {
let mut code = String::new();

let lhs_type = compile_evaluable_type_only(fid, lhs, local_variables, global_table, function_calls)?;
let op_fn = global_table.get_operator_function(*lhs_type.type_id(), op, PrefixOrInfixEx::Prefix)?;
let signature = global_table.get_function_signature(op_fn);

if signature.args().len() != 1 {
return Err(
WErr::n(
EvalErrs::InfixOpWrongArgumentCount(
op.operator().to_str().to_string(),
global_table.get_type(*lhs_type.type_id()).name().to_string(),
op.operator().get_method_name(PrefixOrInfixEx::Prefix).unwrap(),
signature.args().len()
),
op.location().clone()
)
);
}

match signature.return_type() {
None => {
return Err(WErr::n(OpNoReturn(global_table.get_type_name(target.type_ref())), op.location().clone()))
}
Some(rt) => {
if rt != target.type_ref() {
return Err(WErr::n(OpWrongReturnType(global_table.get_type_name(target.type_ref()), global_table.get_type_name(rt)), op.location().clone()))
}
}
}

let (c, _) = call_function(fid, op_fn, &[Left(lhs)], Some(target), global_table, local_variables, function_calls)?;

code += &c;

code
},
EvaluableTokens::DynamicAccess(_, _) => todo!(), // Accessed methods must be called
EvaluableTokens::StaticAccess(_, n) => return Err(WErr::n(NRErrors::CannotFindConstantAttribute(n.name().clone()), n.location().clone())), // Accessed methods must be called
EvaluableTokens::FunctionCall(inner, args) => {
Expand Down
Loading

0 comments on commit ad80498

Please sign in to comment.