diff --git a/compiler/src/expressions.rs b/compiler/src/expressions.rs index d1783e2..3bd0d15 100644 --- a/compiler/src/expressions.rs +++ b/compiler/src/expressions.rs @@ -40,7 +40,11 @@ impl Compiler { Expression::Identifier(identifier) => self.compile_identifier(scope, identifier), Expression::Prefix(unary_expression) => self.compile_prefix_expression(scope, unary_expression), Expression::Infix(binary_expression) => self.compile_infix_expression(scope, binary_expression), - Expression::FuncCall(func_call) => self.compile_func_call(scope, func_call), + Expression::FuncCall(func_call) => { + let rvalue = self.compile_func_call(scope, func_call.clone()); + self.eval_func_call(rvalue, func_call.loc.clone()); + null_mut() + } Expression::UnaryOperator(unary_operator) => self.compile_unary_operator(scope, unary_operator), Expression::Array(array) => self.compile_array(Rc::clone(&scope), array, null_mut()), Expression::ArrayIndex(array_index) => self.compile_array_index(Rc::clone(&scope), array_index), @@ -52,7 +56,12 @@ impl Compiler { Expression::Dereference(expression) => self.compile_dereference(Rc::clone(&scope), expression), Expression::StructInit(struct_init) => self.compile_struct_init(scope, struct_init), Expression::StructFieldAccess(struct_field_access) => { - self.compile_struct_field_access(scope, *struct_field_access) + let item = struct_field_access.chains[struct_field_access.chains.len() - 1].clone(); + if let Some(method_call) = item.method_call { + let rvalue = self.compile_struct_field_access(scope, *struct_field_access.clone()); + self.eval_func_call(rvalue, method_call.loc.clone()); + } + null_mut() } Expression::CastAs(cast_as) => self.compile_cast_as(Rc::clone(&scope), cast_as), } @@ -119,31 +128,13 @@ impl Compiler { unsafe { gcc_jit_block_add_assignment(block, loc, array_item_ptr, expr) }; } - // TODO + // TODO // Make a new construction to return the assigned array - return null_mut(); + return null_mut(); } _ => { - let rvalue = self.compile_expression(Rc::clone(&scope), array_index_assign.expr); - - let casted_rvalue = unsafe { - gcc_jit_context_new_cast( - self.context, - self.gccjit_location(array_index_assign.loc.clone()), - rvalue, - gcc_jit_rvalue_get_type(gcc_jit_lvalue_as_rvalue(lvalue)), - ) - }; - - unsafe { - gcc_jit_block_add_assignment( - block, - self.gccjit_location(array_index_assign.loc.clone()), - lvalue, - casted_rvalue, - ) - } - return rvalue; + let rvalue_type = unsafe { gcc_jit_rvalue_get_type(gcc_jit_lvalue_as_rvalue(lvalue))}; + return self.safe_assign_lvalue(Rc::clone(&scope), lvalue, rvalue_type, array_index_assign.expr.clone(), array_index_assign.loc); } }; } else { @@ -253,33 +244,46 @@ impl Compiler { } } - fn compile_assignment(&mut self, scope: ScopeRef, assignment: Assignment) -> *mut gcc_jit_rvalue { - let (lvalue, rvalue) = self.access_identifier_values(Rc::clone(&scope), assignment.identifier); - + fn safe_assign_lvalue(&mut self, scope: ScopeRef, lvalue: *mut gcc_jit_lvalue, rvalue_type:*mut gcc_jit_type, expr: Expression, loc: Location) -> *mut gcc_jit_rvalue { let block_func = self.block_func_ref.lock().unwrap(); if let Some(block) = block_func.block { drop(block_func); - let target_type = unsafe { gcc_jit_rvalue_get_type(rvalue) }; - let new_rvalue = self.compile_expression(scope, assignment.expr); + let new_rvalue = match expr.clone() { + Expression::FuncCall(func_call) => self.compile_func_call(Rc::clone(&scope), func_call), + Expression::StructFieldAccess(struct_field_access) => { + self.compile_struct_field_access(Rc::clone(&scope), *struct_field_access.clone()) + } + _ => self.compile_expression(scope, expr), + }; let casted_rvalue = unsafe { gcc_jit_context_new_cast( self.context, - self.gccjit_location(assignment.loc.clone()), + self.gccjit_location(loc.clone()), new_rvalue, - target_type, + rvalue_type, ) }; unsafe { - gcc_jit_block_add_assignment(block, self.gccjit_location(assignment.loc.clone()), lvalue, casted_rvalue); + gcc_jit_block_add_assignment( + block, + self.gccjit_location(loc.clone()), + lvalue, + casted_rvalue, + ); }; - return rvalue; + return casted_rvalue; } else { compiler_error!("Incorrect usage of the assignment. Assignments must be performed inside a valid block."); } } + fn compile_assignment(&mut self, scope: ScopeRef, assignment: Assignment) -> *mut gcc_jit_rvalue { + let (lvalue, rvalue) = self.access_identifier_values(Rc::clone(&scope), assignment.identifier); + let rvalue_type = unsafe { gcc_jit_rvalue_get_type(rvalue)}; + self.safe_assign_lvalue(Rc::clone(&scope), lvalue, rvalue_type, assignment.expr, assignment.loc) + } fn compile_unary_operator(&mut self, scope: ScopeRef, unary_operator: UnaryOperator) -> *mut gcc_jit_rvalue { let loc = self.gccjit_location(unary_operator.loc.clone()); diff --git a/compiler/src/funcs.rs b/compiler/src/funcs.rs index 55896f6..d8acaa6 100644 --- a/compiler/src/funcs.rs +++ b/compiler/src/funcs.rs @@ -263,24 +263,23 @@ impl Compiler { 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_lvalue_as_rvalue(temp_lvalue) } + rvalue } else { compiler_error!("Calling any function at top-level nodes isn't allowed."); } } + pub(crate) fn eval_func_call(&mut self, func_call: *mut gcc_jit_rvalue, loc: Location) { + let guard = self.block_func_ref.lock().unwrap(); + + if let Some(block) = guard.block { + drop(guard); + + unsafe { gcc_jit_block_add_eval(block, self.gccjit_location(loc), func_call) }; + } + } + pub(crate) fn access_current_func_param( &mut self, identifier: Identifier, diff --git a/compiler/src/structs.rs b/compiler/src/structs.rs index 73619ca..3ca5db4 100644 --- a/compiler/src/structs.rs +++ b/compiler/src/structs.rs @@ -48,8 +48,6 @@ 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, method_name: String, @@ -64,7 +62,7 @@ impl Compiler { let func_def = struct_metadata.methods[method_idx].clone().func_def; let func_ptr = struct_metadata.method_ptrs[method_idx]; - let rvalue = unsafe { + unsafe { gcc_jit_context_new_call( self.context, self.gccjit_location(func_def.loc.clone()), @@ -72,22 +70,7 @@ impl Compiler { arguments.len().try_into().unwrap(), arguments.as_mut_ptr(), ) - }; - let rvalue_type = unsafe { gcc_jit_rvalue_get_type(rvalue) }; - - let temp_lvalue = - self.new_local_temp(func, rvalue_type, func_def.loc.clone()); - - 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 '{}'", @@ -156,8 +139,6 @@ impl Compiler { }; result = self.compile_struct_method_call( - func, - block, identifier.name.clone(), struct_metadata.clone(), method_call.func_name.name, @@ -177,9 +158,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 @@ -226,8 +207,6 @@ impl Compiler { arguments.insert(0, self_arg); result = self.compile_struct_method_call( - func, - block, struct_name.clone(), struct_metadata.clone(), method_call.func_name.name, diff --git a/compiler/src/varables.rs b/compiler/src/varables.rs index 3e68606..d0a98ce 100644 --- a/compiler/src/varables.rs +++ b/compiler/src/varables.rs @@ -26,6 +26,10 @@ impl Compiler { if let Some(expr) = variable.expr { rvalue = match expr { Expression::Array(array) => self.compile_array(Rc::clone(&scope), array, var_type), + Expression::FuncCall(func_call) => self.compile_func_call(Rc::clone(&scope), func_call), + Expression::StructFieldAccess(struct_field_access) => { + self.compile_struct_field_access(Rc::clone(&scope), *struct_field_access.clone()) + } _ => self.compile_expression(Rc::clone(&scope), expr), }; diff --git a/examples/main.cy b/examples/main.cy index ee6cd64..c6e7f01 100644 --- a/examples/main.cy +++ b/examples/main.cy @@ -1,16 +1,13 @@ - - -fn get_string(msg: string): string { - return "some msg"; -} - -struct Sample { +pub struct Sample { pub fn sample(): string { return "some shit\n"; } } pub fn main() { - #result = Sample.sample(); - #value = get_string("hello"); + #arr: string[3]; + + Sample.sample(); + arr[0] = "bllblblbl"; + arr[1] = Sample.sample(); } \ No newline at end of file