Skip to content

Commit

Permalink
refactor error messages and main-func wrapper feature added
Browse files Browse the repository at this point in the history
  • Loading branch information
tahadostifam committed Mar 1, 2025
1 parent a1a2514 commit 8e2787a
Show file tree
Hide file tree
Showing 18 changed files with 279 additions and 137 deletions.
8 changes: 8 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 @@ -13,6 +13,7 @@ path = "./cli.rs"

[dependencies]
clap = { version = "4.5.23", features = ["derive"] }
colorized = "1.0.0"
lexer = { path = "./lexer", version = "*" }
ast = { path = "./ast", version = "*" }
parser = { path = "./parser", version = "*" }
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use gccjit_sys::*;
use std::ffi::CString;
use std::rc::Rc;
use utils::compiler_error;
use utils::compile_time_errors::errors::*;
use utils::generate_random_hex::generate_random_hex;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -218,7 +219,7 @@ impl Compiler {
},
);
} else {
compiler_error!("For statement variable must be initialized with a valid value.");
compiler_error!("For statement variable must be initialized with a valid value.", self.file_path.clone());
}
}

Expand Down Expand Up @@ -298,7 +299,7 @@ impl Compiler {
unsafe { gcc_jit_block_end_with_return(block, self.gccjit_location(statement.loc), ret_value) };
}
} else {
compiler_error!("Incorrect usage of the return statement. It must be used inside a function definition.");
compiler_error!("Return statement must be used inside a func definition.", self.file_path.clone());
}
}
}
21 changes: 11 additions & 10 deletions compiler/src/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ast::ast::*;
use ast::token::*;
use gccjit_sys::*;
use utils::compiler_error;
use utils::compile_time_errors::errors::*;
use utils::purify_string::purify_string;

use crate::scope::ScopeRef;
Expand All @@ -31,7 +32,7 @@ impl Compiler {
}
}

compiler_error!(format!("'{}' is not defined in this scope.", from_package.to_string()))
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 {
Expand Down Expand Up @@ -182,7 +183,7 @@ impl Compiler {
}
};
} else {
compiler_error!("Array index assignment in invalid block.");
compiler_error!("Array index assignment in invalid block.", self.file_path.clone());
}
}

Expand All @@ -193,7 +194,7 @@ impl Compiler {
dimensions: Vec<Expression>,
) -> *mut gcc_jit_lvalue {
if dimensions.len() == 0 {
compiler_error!("You are trying to access an array item lvalue with empty dimension.")
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;
Expand All @@ -217,13 +218,13 @@ impl Compiler {

result = lvalue;
} else {
compiler_error!("Unable to access array lvalue through a non-integer literal.")
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.")
compiler_error!("Unexpected behavior when trying to compile array_dimension_as_lvalue.", self.file_path.clone())
}

result
Expand Down Expand Up @@ -316,7 +317,7 @@ impl Compiler {

return casted_rvalue;
} else {
compiler_error!("Incorrect usage of the assignment. Assignments must be performed inside a valid block.");
compiler_error!("Incorrect usage of the assignment. Assignments must be performed inside a valid block.", self.file_path.clone());
}
}

Expand All @@ -334,7 +335,7 @@ 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.");
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) };
Expand All @@ -360,7 +361,7 @@ impl Compiler {
unsafe { gcc_jit_block_add_assignment(block, loc, tmp_local, rvalue) };
}
} else {
compiler_error!("Unary operators (++, --, etc.) are only allowed inside functions.");
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) };
Expand Down Expand Up @@ -396,7 +397,7 @@ 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."),
_ => compiler_error!("Invalid operator given for the prefix expression.", self.file_path.clone()),
};

let expr = self.compile_expression(scope, *unary_expression.operand);
Expand Down Expand Up @@ -454,7 +455,7 @@ 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."),
_ => compiler_error!("Invalid operator given for the infix expression.", self.file_path.clone()),
}
}

Expand Down
66 changes: 32 additions & 34 deletions compiler/src/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use std::ffi::CString;
use std::ptr::null_mut;
use std::rc::Rc;

use crate::scope::ScopeRef;
use crate::Compiler;
use crate::scope::ScopeRef;
use ast::ast::*;
use ast::token::*;
use gccjit_sys::*;
use utils::compiler_error;
use utils::compile_time_errors::errors::*;

#[derive(Debug, Clone)]
pub struct FuncMetadata {
Expand All @@ -27,6 +28,21 @@ pub struct FuncParamRecord {
pub type FuncParamsRecords = Vec<FuncParamRecord>;

impl Compiler {
pub fn safe_func_return_type_token(&mut self, return_type: Option<Token>) -> TokenKind {
return_type
.clone()
.unwrap_or(Token {
kind: TokenKind::Void,
span: Span::default(),
})
.kind
}

pub fn safe_func_return_type(&mut self, return_type: Option<Token>) -> *mut gcc_jit_type {
let return_type_token = self.safe_func_return_type_token(return_type);
self.token_as_data_type(self.context, return_type_token.clone())
}

fn declare_function(&mut self, func_decl: FuncDecl) -> (*mut gcc_jit_function, FuncParamsRecords) {
let func_type = match func_decl.vis_type {
VisType::Extern => gcc_jit_function_kind::GCC_JIT_FUNCTION_IMPORTED, // imported function
Expand All @@ -35,16 +51,7 @@ impl Compiler {
VisType::Inline => gcc_jit_function_kind::GCC_JIT_FUNCTION_ALWAYS_INLINE,
};

let return_type_token = func_decl
.return_type
.clone()
.unwrap_or(Token {
kind: TokenKind::Void,
span: Span::default(),
})
.kind;

let return_type = self.token_as_data_type(self.context, return_type_token.clone());
let return_type = self.safe_func_return_type(func_decl.return_type);

let mut params: Vec<*mut gcc_jit_param> = Vec::new();
let mut func_params = FuncParamsRecords::new();
Expand Down Expand Up @@ -95,28 +102,26 @@ impl Compiler {
}

pub(crate) fn compile_func_def(&mut self, scope: ScopeRef, func_def: FuncDef) -> *mut gcc_jit_function {
let (declare_function, func_params) = self.declare_function(FuncDecl {
let (func_ptr, func_params) = self.declare_function(FuncDecl {
name: func_def.name.clone(),
params: func_def.params,
params: func_def.params.clone(),
return_type: func_def.return_type.clone(),
vis_type: func_def.vis_type,
vis_type: func_def.vis_type.clone(),
renamed_as: None,
span: func_def.span,
loc: func_def.loc,
});

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

// Build func block
let name = CString::new("entry").unwrap();
let block = unsafe { gcc_jit_function_new_block(declare_function, name.as_ptr()) };
let block = unsafe { gcc_jit_function_new_block(func_ptr, name.as_ptr()) };
let mut return_compiled = false;

let mut guard = self.block_func_ref.lock().unwrap();
guard.block = Some(block);
guard.func = Some(declare_function);
guard.func = Some(func_ptr);
drop(guard);

for item in func_def.body.body {
Expand All @@ -132,7 +137,7 @@ impl Compiler {
compiler_error!(format!(
"Explicit return statement required for the function '{}'.",
func_def.name
));
), self.file_path.clone());
}
} else {
let guard = self.block_func_ref.lock().unwrap();
Expand All @@ -142,19 +147,20 @@ impl Compiler {
unsafe { gcc_jit_block_end_with_void_return(block, null_mut()) };
}
}
}
}

return declare_function;
return func_ptr;
}

pub(crate) fn compile_func_decl(&mut self, declare_function: FuncDecl) {
let (func, _) = self.declare_function(declare_function.clone());
let return_type = self.safe_func_return_type(declare_function.return_type);
let return_type = self.safe_func_return_type_token(declare_function.return_type);
let func_name = if let Some(renamed_as) = declare_function.renamed_as {
renamed_as
} else {
declare_function.name
};

self.func_table.borrow_mut().insert(
func_name,
FuncMetadata {
Expand All @@ -167,15 +173,6 @@ impl Compiler {
);
}

pub(crate) fn safe_func_return_type(&mut self, return_type: Option<Token>) -> TokenKind {
return_type
.unwrap_or(Token {
kind: TokenKind::Void,
span: Span::default(),
})
.kind
}

pub(crate) fn compile_func_params(
&mut self,
func_name: String,
Expand Down Expand Up @@ -252,17 +249,18 @@ impl Compiler {
return func_metadata.1.clone();
}

dbg!(binding.keys());
compiler_error!(format!(
"Function '{}' not defined at this module.",
from_package.to_string()
))
), self.file_path.clone())
}

pub(crate) fn compile_func_call(&mut self, scope: ScopeRef, func_call: FuncCall) -> *mut gcc_jit_rvalue {
let loc = self.gccjit_location(func_call.loc.clone());

let metadata = self.get_func(func_call.func_name);

let mut args = self.compile_func_arguments(
Rc::clone(&scope),
Some(metadata.params.list.clone()),
Expand Down
9 changes: 5 additions & 4 deletions compiler/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::fs;
use std::path::Path;
use std::ptr::null_mut;
use utils::compiler_error;
use utils::compile_time_errors::errors::*;

use crate::funcs::FuncMetadata;
use crate::structs::StructMetadata;
Expand All @@ -30,13 +31,13 @@ impl Compiler {
}
"./" => {
if finding_std {
compiler_error!("Importing package with relative path to find stdlib is not allowed.");
compiler_error!("Importing package with relative path to find stdlib is not allowed.", self.file_path.clone());
}
import_file_path += "./";
}
"../" => {
if finding_std {
compiler_error!("Importing package with relative path to find stdlib is not allowed.");
compiler_error!("Importing package with relative path to find stdlib is not allowed.", self.file_path.clone());
}
import_file_path += "../";
}
Expand All @@ -58,7 +59,7 @@ impl Compiler {
compiler_error!(format!(
"File '{}' not found to be imported by the compiler.",
import_file_path + package_name
));
), self.file_path.clone());
}
}
}
Expand All @@ -85,7 +86,7 @@ impl Compiler {
let compile_error = unsafe { gcc_jit_context_get_first_error(context) };
if compile_error != null_mut() {
let error_string = unsafe { CStr::from_ptr(compile_error) };
compiler_error!(format!("{} compilation failed: {}", file_name, error_string.to_str().unwrap()));
compiler_error!(format!("{} compilation failed: {}", file_name, error_string.to_str().unwrap()), self.file_path.clone());
}

compiler.make_object_file(output_library_path.clone());
Expand Down
Loading

0 comments on commit 8e2787a

Please sign in to comment.