Skip to content

Commit

Permalink
refactor method_call and func_call in compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
tahadostifam committed Feb 10, 2025
1 parent f062ba5 commit 9b1e096
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 33 deletions.
27 changes: 19 additions & 8 deletions compiler/src/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ impl Compiler {
loc: func_def.loc,
});

self.param_table.borrow_mut().insert(declare_function, func_params.clone());
self.param_table
.borrow_mut()
.insert(declare_function, func_params.clone());

// Build func block
let name = CString::new("entry").unwrap();
Expand Down Expand Up @@ -233,12 +235,12 @@ impl Compiler {
pub(crate) fn compile_func_call(&mut self, scope: ScopeRef, func_call: FuncCall) -> *mut gcc_jit_rvalue {
let guard = self.block_func_ref.lock().unwrap();

if let Some(block) = guard.block {
if let (Some(block), Some(func)) = (guard.block, guard.func) {
drop(guard);

let loc = self.gccjit_location(func_call.loc.clone());

let func = {
let metadata = {
let func_table = self.func_table.borrow_mut();
match func_table.get(&func_call.func_name.name) {
Some(func) => func.clone(),
Expand All @@ -250,21 +252,30 @@ impl Compiler {
};

let mut args =
self.compile_func_arguments(Rc::clone(&scope), Some(func.params.clone()), func_call.arguments);
self.compile_func_arguments(Rc::clone(&scope), Some(metadata.params.clone()), func_call.arguments);

let rvalue = unsafe {
gcc_jit_context_new_call(
self.context,
loc.clone(),
func.ptr,
metadata.ptr,
args.len().try_into().unwrap(),
args.as_mut_ptr(),
)
};
let rvalue_type = unsafe { gcc_jit_rvalue_get_type(rvalue) };
let temp_lvalue = self.new_local_temp(func, rvalue_type, func_call.loc.clone());

unsafe {
gcc_jit_block_add_assignment(
block,
self.gccjit_location(func_call.loc),
temp_lvalue,
rvalue,
)
};

unsafe { gcc_jit_block_add_eval(block, loc, rvalue) };

return rvalue;
unsafe { gcc_jit_lvalue_as_rvalue(temp_lvalue) }
} else {
compiler_error!("Calling any function at top-level nodes isn't allowed.");
}
Expand Down
15 changes: 14 additions & 1 deletion compiler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ast::ast::*;
use ast::{ast::*, token::Location};
use control_flow::LoopBlockPair;
use funcs::{FuncMetadata, FuncParamsRecords};
use gccjit_sys::*;
Expand All @@ -13,6 +13,7 @@ use std::{
sync::{Arc, Mutex},
};
use structs::StructMetadata;
use utils::generate_random_hex::generate_random_hex;

mod blocks;
mod context;
Expand Down Expand Up @@ -149,6 +150,18 @@ impl Compiler {
),
}
}

pub(crate) fn new_local_temp(&mut self, func: *mut gcc_jit_function, ty: *mut gcc_jit_type, loc: Location) -> *mut gcc_jit_lvalue {
let temp_name = CString::new(format!("temp_{}", generate_random_hex())).unwrap();
unsafe {
gcc_jit_function_new_local(
func,
self.gccjit_location(loc),
ty,
temp_name.as_ptr(),
)
}
}
}

impl Drop for Compiler {
Expand Down
34 changes: 26 additions & 8 deletions compiler/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl Compiler {

fn compile_struct_method_call(
&mut self,
func: *mut gcc_jit_function,
block: *mut gcc_jit_block,
struct_name: String,
struct_metadata: StructMetadata,
Expand All @@ -60,22 +61,33 @@ impl Compiler {
.position(|key| key.func_def.name == method_name.clone())
{
Some(method_idx) => {
let func_def = struct_metadata.methods[method_idx].clone();
let func_def = struct_metadata.methods[method_idx].clone().func_def;
let func_ptr = struct_metadata.method_ptrs[method_idx];

let rvalue = unsafe {
gcc_jit_context_new_call(
self.context,
self.gccjit_location(func_def.func_def.loc.clone()),
self.gccjit_location(func_def.loc.clone()),
func_ptr,
arguments.len().try_into().unwrap(),
arguments.as_mut_ptr(),
)
};
let rvalue_type = unsafe { gcc_jit_rvalue_get_type(rvalue) };

unsafe { gcc_jit_block_add_eval(block, self.gccjit_location(func_def.func_def.loc), rvalue) };
let temp_lvalue =
self.new_local_temp(func, rvalue_type, func_def.loc.clone());

return rvalue;
unsafe {
gcc_jit_block_add_assignment(
block,
self.gccjit_location(func_def.loc),
temp_lvalue,
rvalue,
)
};

unsafe { gcc_jit_lvalue_as_rvalue(temp_lvalue) }
}
None => compiler_error!(format!(
"Method '{}' not defined for struct '{}'",
Expand All @@ -100,7 +112,11 @@ impl Compiler {
}
}

pub(crate) fn compile_struct_field_access(&mut self, scope: ScopeRef, statement: StructFieldAccess) -> *mut gcc_jit_rvalue {
pub(crate) fn compile_struct_field_access(
&mut self,
scope: ScopeRef,
statement: StructFieldAccess,
) -> *mut gcc_jit_rvalue {
let mut method_call_chain = statement.chains.clone();

let (func, block) = {
Expand Down Expand Up @@ -140,6 +156,7 @@ impl Compiler {
};

result = self.compile_struct_method_call(
func,
block,
identifier.name.clone(),
struct_metadata.clone(),
Expand All @@ -160,9 +177,9 @@ impl Compiler {
result = self.compile_expression(Rc::clone(&scope), statement.expr.clone());
}

if result == null_mut() {
compiler_error!("Unexpected behaviour in struct field access compilation.");
}
// if result == null_mut() {
// compiler_error!("Unexpected behaviour in struct field access compilation.");
// }

for item in method_call_chain {
unsafe { gcc_jit_type_is_struct(gcc_jit_rvalue_get_type(result)) }; // check to be struct
Expand Down Expand Up @@ -209,6 +226,7 @@ impl Compiler {
arguments.insert(0, self_arg);

result = self.compile_struct_method_call(
func,
block,
struct_name.clone(),
struct_metadata.clone(),
Expand Down
18 changes: 15 additions & 3 deletions examples/main.cy
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
pub fn main(): i32 {

return 0;


fn get_string(msg: string): string {
return "some msg";
}

struct Sample {
pub fn sample(): string {
return "some shit\n";
}
}

pub fn main() {
#result = Sample.sample();
#value = get_string("hello");
}
12 changes: 6 additions & 6 deletions examples/sample.cy
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pub struct Person {
name: string;
age: i32;
import io;
import memory;

pub fn sample() {
cprintf("sample.cy executed.\n");
}
fn get_string(msg: string): string {
return "some msg";
}

pub fn main() {
}
14 changes: 7 additions & 7 deletions parser/src/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ impl<'a> Parser<'a> {
match self.current_token.kind {
TokenKind::If => self.parse_if(),
TokenKind::Function | TokenKind::Decl | TokenKind::Extern | TokenKind::Pub | TokenKind::Inline => {
if self.peek_token_is(TokenKind::Function) {
if self.current_token_is(TokenKind::Function) || self.peek_token_is(TokenKind::Function) {
self.parse_func()
} else if self.peek_token_is(TokenKind::Struct) {
} else if self.current_token_is(TokenKind::Struct) || self.peek_token_is(TokenKind::Struct) {
self.parse_struct()
} else {
compiler_error!("Expected struct/fn definition after vis_type token");
Expand Down Expand Up @@ -631,15 +631,15 @@ impl<'a> Parser<'a> {

let (expr, span) = self.parse_expression(Precedence::Lowest)?;

// NOTE
// This line here is potential to raise some serious problems
// NOTE
// This line here is potential to raise some serious problems
// in parsing process. But now i don't have any idea that how we can fix it.
// The reason is that some expressions need consume last token (before semicolon) and some does not.
if self.peek_token_is(TokenKind::Semicolon) {
self.next_token();
self.next_token();
}
//
//

if !self.current_token_is(TokenKind::Semicolon) {
return Err(CompileTimeError {
location: self.current_location(),
Expand Down
Binary file removed stdlib/io.o
Binary file not shown.

0 comments on commit 9b1e096

Please sign in to comment.