diff --git a/compiler/src/builtins/funcs.rs b/compiler/src/builtins/funcs.rs index b8a657a..b83a4bf 100755 --- a/compiler/src/builtins/funcs.rs +++ b/compiler/src/builtins/funcs.rs @@ -1,10 +1,10 @@ use crate::Compiler; use gccjit_sys::*; -use utils::compiler_error; -use utils::compile_time_errors::errors::*; use std::{ffi::CString, ptr::null_mut}; +use utils::compile_time_errors::errors::*; +use utils::compiler_error; -pub fn builtin_func__len( +pub fn builtin_func_len( file_path: String, context: *mut gcc_jit_context, args: Vec<*mut gcc_jit_rvalue>, @@ -17,7 +17,7 @@ pub fn builtin_func__len( let size_t_type = Compiler::size_t_type(context); let void_ptr_type = Compiler::void_ptr_type(context); - let wrapper_func_name = CString::new("__cyrus_builtin_wrapped_func__len").unwrap(); + let wrapper_func_name = CString::new("__cyrus_builtin__len").unwrap(); // TODO Check param type to be array or string let rvalue_param_name = CString::new("rvalue").unwrap(); let rvalue_param = @@ -38,40 +38,56 @@ pub fn builtin_func__len( let block_name = CString::new("entry").unwrap(); let block = unsafe { gcc_jit_function_new_block(wrapper_func, block_name.as_ptr()) }; - let sizeof_array = unsafe { gcc_jit_context_new_sizeof(context, rvalue_type) }; - let first_item_of_array = unsafe { - gcc_jit_context_new_array_access( + let sizeof_array = unsafe { + gcc_jit_context_new_cast( + context, + null_mut(), + gcc_jit_context_new_sizeof(context, rvalue_type), + size_t_type, + ) + }; + + let sizeof_first_item = unsafe { + gcc_jit_context_new_cast( context, null_mut(), - rvalue, - gcc_jit_context_new_rvalue_from_int(context, Compiler::i32_type(context), 0), + gcc_jit_context_new_sizeof( + context, + gcc_jit_rvalue_get_type(gcc_jit_lvalue_as_rvalue(gcc_jit_context_new_array_access( + context, + null_mut(), + rvalue, + gcc_jit_context_new_rvalue_from_int(context, Compiler::i32_type(context), 0), + ))), + ), + size_t_type, ) }; - let len_result = unsafe { + let mut return_rvalue = unsafe { gcc_jit_context_new_binary_op( context, null_mut(), gcc_jit_binary_op::GCC_JIT_BINARY_OP_DIVIDE, - size_t_type, + Compiler::i32_type(context), sizeof_array, - unsafe { - gcc_jit_lvalue_as_rvalue(first_item_of_array) - }, + sizeof_first_item, ) }; + return_rvalue = unsafe { gcc_jit_context_new_cast(context, null_mut(), return_rvalue, size_t_type) }; - unsafe { gcc_jit_block_end_with_return(block, null_mut(), len_result) }; - - return len_result; + unsafe { gcc_jit_block_end_with_return(block, null_mut(), return_rvalue) }; + return return_rvalue; } -pub fn builtin_func__sizeof(file_path: String, +pub fn builtin_func_sizeof( + _: String, context: *mut gcc_jit_context, - args: Vec<*mut gcc_jit_rvalue>,) -> *mut gcc_jit_rvalue { + args: Vec<*mut gcc_jit_rvalue>, +) -> *mut gcc_jit_rvalue { let rvalue = args.first().unwrap(); let rvalue_type = unsafe { gcc_jit_rvalue_get_type(*rvalue) }; let rvalue_size = unsafe { gcc_jit_context_new_sizeof(context, rvalue_type) }; return rvalue_size; -} \ No newline at end of file +} diff --git a/compiler/src/builtins/loader.rs b/compiler/src/builtins/loader.rs index 2866b73..8121d0b 100755 --- a/compiler/src/builtins/loader.rs +++ b/compiler/src/builtins/loader.rs @@ -1,8 +1,8 @@ use gccjit_sys::{gcc_jit_context, gcc_jit_rvalue}; use std::{collections::HashMap, sync::LazyLock}; -use super::funcs::builtin_func__len; -use crate::builtins::funcs::builtin_func__sizeof; +use super::funcs::builtin_func_len; +use crate::builtins::funcs::builtin_func_sizeof; pub type BuiltinFuncDef = fn(file_path: String, context: *mut gcc_jit_context, args: Vec<*mut gcc_jit_rvalue>) -> *mut gcc_jit_rvalue; @@ -22,7 +22,7 @@ macro_rules! build_builtin_funcs { pub static BUILTIN_FUNCS: LazyLock = LazyLock::new(|| { build_builtin_funcs! { - "len" => builtin_func__len, - "sizeof" => builtin_func__sizeof + "len" => builtin_func_len, + "sizeof" => builtin_func_sizeof } }); diff --git a/compiler/src/expressions.rs b/compiler/src/expressions.rs index 922d1a8..561152f 100755 --- a/compiler/src/expressions.rs +++ b/compiler/src/expressions.rs @@ -5,12 +5,12 @@ use std::rc::Rc; use ast::ast::*; use ast::token::*; use gccjit_sys::*; -use utils::compiler_error; use utils::compile_time_errors::errors::*; +use utils::compiler_error; use utils::purify_string::purify_string; -use crate::scope::ScopeRef; use crate::Compiler; +use crate::scope::ScopeRef; impl Compiler { pub(crate) fn access_identifier_values( @@ -32,7 +32,10 @@ impl Compiler { } } - compiler_error!(format!("'{}' is not defined in this scope.", from_package.to_string()), self.file_path.clone()) + compiler_error!( + format!("'{}' is not defined in this scope.", from_package.to_string()), + self.file_path.clone() + ) } fn compile_identifier(&mut self, scope: ScopeRef, identifier: Identifier) -> *mut gcc_jit_rvalue { @@ -66,7 +69,9 @@ impl Compiler { let last_chain = chains_copy.last().unwrap(); if let Some(method_call) = last_chain.method_call.clone() { - self.eval_func_call(result, method_call.loc); + if result != null_mut() { + self.eval_func_call(result, method_call.loc); + } null_mut() } else { result @@ -86,7 +91,9 @@ impl Compiler { 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()); + if rvalue != null_mut() { + self.eval_func_call(rvalue, method_call.loc.clone()); + } } null_mut() } @@ -193,7 +200,10 @@ impl Compiler { dimensions: Vec, ) -> *mut gcc_jit_lvalue { if dimensions.len() == 0 { - compiler_error!("You are trying to access an array item lvalue with empty dimension.", self.file_path.clone()) + compiler_error!( + "You are trying to access an array item lvalue with empty dimension.", + self.file_path.clone() + ) } let mut result: *mut gcc_jit_lvalue = variable; @@ -217,13 +227,19 @@ impl Compiler { result = lvalue; } else { - compiler_error!("Unable to access array lvalue through a non-integer literal.", self.file_path.clone()) + compiler_error!( + "Unable to access array lvalue through a non-integer literal.", + self.file_path.clone() + ) } } } if result == variable { - compiler_error!("Unexpected behavior when trying to compile array_dimension_as_lvalue.", self.file_path.clone()) + compiler_error!( + "Unexpected behavior when trying to compile array_dimension_as_lvalue.", + self.file_path.clone() + ) } result @@ -316,7 +332,10 @@ impl Compiler { return casted_rvalue; } else { - compiler_error!("Incorrect usage of the assignment. Assignments must be performed inside a valid block.", self.file_path.clone()); + compiler_error!( + "Incorrect usage of the assignment. Assignments must be performed inside a valid block.", + self.file_path.clone() + ); } } @@ -334,7 +353,10 @@ impl Compiler { let rvalue_type = unsafe { gcc_jit_rvalue_get_type(rvalue) }; if !self.is_int_data_type(rvalue_type) { - compiler_error!("Unary operations are only valid for integer types.", self.file_path.clone()); + compiler_error!( + "Unary operations are only valid for integer types.", + self.file_path.clone() + ); } let fixed_number = unsafe { gcc_jit_context_new_rvalue_from_int(self.context, rvalue_type, 1) }; @@ -360,7 +382,10 @@ impl Compiler { unsafe { gcc_jit_block_add_assignment(block, loc, tmp_local, rvalue) }; } } else { - compiler_error!("Unary operators (++, --, etc.) are only allowed inside functions.", self.file_path.clone()); + compiler_error!( + "Unary operators (++, --, etc.) are only allowed inside functions.", + self.file_path.clone() + ); } let tmp_rvalue = unsafe { gcc_jit_lvalue_as_rvalue(tmp_local) }; @@ -396,7 +421,10 @@ impl Compiler { let op = match unary_expression.operator.kind { TokenKind::Minus => gcc_jit_unary_op::GCC_JIT_UNARY_OP_MINUS, TokenKind::Bang => gcc_jit_unary_op::GCC_JIT_UNARY_OP_LOGICAL_NEGATE, - _ => compiler_error!("Invalid operator given for the prefix expression.", self.file_path.clone()), + _ => compiler_error!( + "Invalid operator given for the prefix expression.", + self.file_path.clone() + ), }; let expr = self.compile_expression(scope, *unary_expression.operand); @@ -454,7 +482,10 @@ impl Compiler { | bin_op @ TokenKind::NotEqual => { self.compile_comparison_operation(bin_op, casted_left, casted_right, binary_expression.loc) } - _ => compiler_error!("Invalid operator given for the infix expression.", self.file_path.clone()), + _ => compiler_error!( + "Invalid operator given for the infix expression.", + self.file_path.clone() + ), } } diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 6f4cbb0..285751f 100755 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -1,14 +1,15 @@ -use ast::{ - ast::*, - token::{Location, Span, TokenKind}, -}; +use ast::ast::*; use control_flow::LoopBlockPair; use funcs::{FuncMetadata, FuncParamsRecords}; use gccjit_sys::*; use options::CompilerOptions; use scope::{Scope, ScopeRef}; use std::{ - cell::RefCell, collections::HashMap, ffi::CString, ops::Deref, rc::Rc, sync::{Arc, Mutex} + cell::RefCell, + collections::HashMap, + ffi::CString, + rc::Rc, + sync::{Arc, Mutex}, }; use structs::StructMetadata; diff --git a/compiler/src/output.rs b/compiler/src/output.rs index cf78f2b..0c0fe50 100755 --- a/compiler/src/output.rs +++ b/compiler/src/output.rs @@ -1,5 +1,5 @@ use crate::{Compiler, scope::Scope}; -use ast::token::{Location, TokenKind}; +use ast::token::TokenKind; use gccjit_sys::*; use std::{ cell::RefCell, diff --git a/compiler/src/structs.rs b/compiler/src/structs.rs index 0c549f9..2f70ecc 100755 --- a/compiler/src/structs.rs +++ b/compiler/src/structs.rs @@ -114,7 +114,13 @@ impl Compiler { let args =self.compile_func_arguments(Rc::clone(&scope), None, method_call.arguments); let rvalue = func_def(self.file_path.clone(), self.context, args); return rvalue; - } + } + // else { + // compiler_error!(format!( + // "Function '{}' not defined at this module.", + // func_name + // ), self.file_path.clone()); + // } } let rvalue: *mut gcc_jit_rvalue = { @@ -152,7 +158,7 @@ impl Compiler { if let (Some(func), Some(block)) = (func, block) { let mut result = rvalue.clone(); - if result == null_mut() { + if result == null_mut() && chains.len() > 1 { compiler_error!("Chained field_access_or_method_call on null value.", self.file_path.clone()); } @@ -342,7 +348,7 @@ impl Compiler { } } else { compiler_error!( - "Unexpected behaviour because compiler is trying to call struct method with empty chain.", + "Unexpected behavior because compiler is trying to call struct method with empty chain.", self.file_path.clone() ); } @@ -354,7 +360,7 @@ impl Compiler { } if result == null_mut() { - compiler_error!("Unexpected behaviour in struct field access compilation.", self.file_path.clone()); + compiler_error!("Unexpected behavior in struct field access compilation.", self.file_path.clone()); } self.field_access_or_method_call(Rc::clone(&scope), result, method_call_chain) diff --git a/examples/main.cyr b/examples/main.cyr index a5ec184..7475d9b 100755 --- a/examples/main.cyr +++ b/examples/main.cyr @@ -1,2 +1,7 @@ -#arr: i32[3] = [1, 2, 3]; -#item = arr[2]; \ No newline at end of file +import std::io; + +fn main() { + #arr: i32[4] = [1, 2, 3]; + #size = len(arr); + std::io::printf("size: %d\n", size); +} \ No newline at end of file diff --git a/parser/src/expressions.rs b/parser/src/expressions.rs index 3d01f28..9727ff2 100755 --- a/parser/src/expressions.rs +++ b/parser/src/expressions.rs @@ -81,10 +81,11 @@ impl<'a> Parser<'a> { }) } else if self.current_token_is(TokenKind::Assign) { self.parse_assignment(from_package)? - } else if self.current_token_is(TokenKind::LeftBracket) { + } else if self.peek_token_is(TokenKind::LeftBracket) { + self.next_token(); // consume identifier let array_index = self.parse_array_index(from_package)?; - if self.peek_token_is(TokenKind::Assign) { + if self.current_token_is(TokenKind::Assign) { self.parse_array_index_assign(array_index)? } else { Expression::ArrayIndex(array_index) @@ -620,8 +621,6 @@ impl<'a> Parser<'a> { } pub fn parse_array_index_assign(&mut self, array_index: ArrayIndex) -> Result { - self.next_token(); // consume right bracket - self.expect_current(TokenKind::Assign)?; let expr = self.parse_expression(Precedence::Lowest)?.0; @@ -641,13 +640,12 @@ impl<'a> Parser<'a> { pub fn parse_array_index(&mut self, from_package: FromPackage) -> Result { let start = self.current_token.span.start; - dbg!(self.current_token.kind.clone()); - let mut dimensions: Vec = Vec::new(); while self.current_token_is(TokenKind::LeftBracket) { let expr = self.parse_array_items()?; dimensions.push(expr); + self.next_token(); } let end = self.current_token.span.end;