Skip to content

Commit

Permalink
extern variadic funcs works now
Browse files Browse the repository at this point in the history
  • Loading branch information
tahadostifam committed Feb 10, 2025
1 parent 5fedbec commit 8be5629
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 44 deletions.
6 changes: 5 additions & 1 deletion ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,11 @@ pub struct FunctionParam {
pub loc: Location,
}

pub type FunctionParams = Vec<FunctionParam>;
#[derive(Debug, Clone)]
pub struct FunctionParams {
pub list: Vec<FunctionParam>,
pub is_variadic: bool
}

#[derive(Debug, Clone)]
pub struct If {
Expand Down
4 changes: 2 additions & 2 deletions ast/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ mod tests {

let func = FuncDef {
name: "add".to_string(),
params: vec![param.clone()],
params: FunctionParams { list: vec![param.clone()], is_variadic: false },
body: Box::new(BlockStatement {
body: vec![],
span: Span::default(),
Expand All @@ -208,7 +208,7 @@ mod tests {
};

assert_eq!(func.name, "add");
assert_eq!(func.params[0].identifier.name, "a");
assert_eq!(func.params.list[0].identifier.name, "a");
}

#[test]
Expand Down
4 changes: 4 additions & 0 deletions ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub enum TokenKind {
Comma,
Hashtag,
Dot,
DoubleDot,
TripleDot,
DoubleQuote,
SingleQuote,
Pipe,
Expand Down Expand Up @@ -114,6 +116,8 @@ impl fmt::Display for TokenKind {
Self::RightBracket => write!(f, "]]"),
Self::Comma => write!(f, ","),
Self::Hashtag => write!(f, "#"),
Self::DoubleDot => write!(f, ".."),
Self::TripleDot => write!(f, "..."),
Self::Dot => write!(f, "."),
Self::DoubleQuote => write!(f, "\""),
Self::SingleQuote => write!(f, "'"),
Expand Down
42 changes: 21 additions & 21 deletions compiler/src/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct FuncMetadata {
pub(crate) func_type: VisType,
pub(crate) ptr: *mut gcc_jit_function,
pub(crate) return_type: TokenKind,
pub(crate) params: Vec<FunctionParam>,
pub(crate) params: FunctionParams,
}

#[derive(Debug, Clone)]
Expand All @@ -26,15 +26,15 @@ pub struct FuncParamRecord {
pub type FuncParamsRecords = Vec<FuncParamRecord>;

impl Compiler {
fn declare_function(&mut self, declare_function: FuncDecl) -> (*mut gcc_jit_function, FuncParamsRecords) {
let func_type = match declare_function.vis_type {
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
VisType::Pub => gcc_jit_function_kind::GCC_JIT_FUNCTION_EXPORTED,
VisType::Internal => gcc_jit_function_kind::GCC_JIT_FUNCTION_INTERNAL,
VisType::Inline => gcc_jit_function_kind::GCC_JIT_FUNCTION_ALWAYS_INLINE,
};

let return_type_token = declare_function
let return_type_token = func_decl
.return_type
.clone()
.unwrap_or(Token {
Expand All @@ -48,7 +48,7 @@ impl Compiler {
let mut params: Vec<*mut gcc_jit_param> = Vec::new();
let mut func_params = FuncParamsRecords::new();

for (idx, func_def_param) in declare_function.params.iter().enumerate() {
for (idx, func_def_param) in func_decl.params.list.iter().enumerate() {
let name = CString::new(func_def_param.identifier.name.clone()).unwrap();

let ty_token = if let Some(user_def) = &func_def_param.ty {
Expand Down Expand Up @@ -76,17 +76,17 @@ impl Compiler {
});
}

let func_name = CString::new(declare_function.name.clone()).unwrap();
let func_name = CString::new(func_decl.name.clone()).unwrap();
let func = unsafe {
gcc_jit_context_new_function(
self.context,
self.gccjit_location(declare_function.loc.clone()),
self.gccjit_location(func_decl.loc.clone()),
func_type,
return_type.clone(),
func_name.as_ptr(),
params.len().try_into().unwrap(),
params.as_mut_ptr(),
0,
self.cbool(func_decl.params.is_variadic),
)
};

Expand Down Expand Up @@ -210,18 +210,18 @@ impl Compiler {
let mut expr = self.compile_expression(Rc::clone(&scope), expr.clone());

if let Some(ref func_params) = func_params {
let param = func_params[idx].clone();

if let Some(var_token_type) = param.ty {
if self.auto_castable_data_types(var_token_type.clone()) {
expr = unsafe {
gcc_jit_context_new_cast(
self.context,
self.gccjit_location(param.loc.clone()),
expr,
self.token_as_data_type(self.context, var_token_type),
)
};
if let Some(param) = func_params.get(idx) {
if let Some(var_token_type) = &param.ty {
if self.auto_castable_data_types(var_token_type.clone()) {
expr = unsafe {
gcc_jit_context_new_cast(
self.context,
self.gccjit_location(param.loc.clone()),
expr,
self.token_as_data_type(self.context, var_token_type.clone()),
)
};
}
}
}
}
Expand All @@ -247,7 +247,7 @@ impl Compiler {
};

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

let rvalue = unsafe {
gcc_jit_context_new_call(
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl Compiler {
fn define_imported_func_as_extern_decl(
&mut self,
func_name: String,
params: Vec<FunctionParam>,
params: FunctionParams,
return_type: Option<Token>,
loc: Location,
) -> *mut gcc_jit_function {
Expand All @@ -160,7 +160,7 @@ impl Compiler {
})
.kind;

let mut func_params = self.compile_func_params(func_name.clone(), params.clone(), loc.clone());
let mut func_params = self.compile_func_params(func_name.clone(), params.list.clone(), loc.clone());
let func_name_cstr = CString::new(func_name.clone()).unwrap();
let decl_func = unsafe {
gcc_jit_context_new_function(
Expand All @@ -171,7 +171,7 @@ impl Compiler {
func_name_cstr.as_ptr(),
func_params.len().try_into().unwrap(),
func_params.as_mut_ptr(),
0, // FIXME Variadic
self.cbool(params.is_variadic)
)
};

Expand Down
8 changes: 4 additions & 4 deletions compiler/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl Compiler {
// Isolate the mutable borrow to avoid conflict with immutable borrows.
self.compile_func_arguments(
Rc::clone(&scope),
Some(method_def.params),
Some(method_def.params.list),
method_call.arguments,
)
};
Expand Down Expand Up @@ -176,11 +176,11 @@ impl Compiler {
// Inserting self argument
let mut arguments = self.compile_func_arguments(
Rc::clone(&scope),
Some(method_def.params.clone()),
Some(method_def.params.list.clone()),
method_call.arguments,
);
let self_param = method_def
.params
.params.list
.iter()
.find(|&key| key.identifier.name == "self")
.unwrap();
Expand Down Expand Up @@ -363,7 +363,7 @@ impl Compiler {
for item in methods.clone() {
let mut is_static = true;

if let Some(self_param) = item.params.iter().find(|&key| key.identifier.name == "self") {
if let Some(self_param) = item.params.list.iter().find(|&key| key.identifier.name == "self") {
is_static = false;

if !self.struct_self_param_valid(struct_name.clone(), self_param.ty.clone().unwrap()) {
Expand Down
5 changes: 2 additions & 3 deletions examples/main.cy
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub fn _sum() {
import io;

}
pub fn main() {
_sum();
printf("Hello: %s %s\n", "adad", "aasd");
}
23 changes: 22 additions & 1 deletion lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,28 @@ impl Lexer {
'[' => TokenKind::LeftBracket,
']' => TokenKind::RightBracket,
',' => TokenKind::Comma,
'.' => TokenKind::Dot,
'.' => {
self.read_char();

let mut kind = TokenKind::Dot;

if self.ch == '.' && self.peek_char() == '.' {
self.read_char();
self.read_char();
kind = TokenKind::TripleDot;
} else if self.ch == '.' {
self.read_char();
kind = TokenKind::DoubleDot;
}

return Token {
kind,
span: Span {
start: self.pos - 1,
end: self.pos - 1,
},
};
},
'#' => TokenKind::Hashtag,
'"' => return self.read_string(),
'\'' => return self.read_char_literal(),
Expand Down
34 changes: 29 additions & 5 deletions parser/src/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,15 +342,39 @@ impl<'a> Parser<'a> {
}
}

pub fn parse_func_params(&mut self) -> Result<FunctionParams, ParseError> {
pub fn parse_func_params(&mut self, func_def_start: usize) -> Result<FunctionParams, ParseError> {
let params_start = self.current_token.span.start;

self.expect_current(TokenKind::LeftParen)?;

let mut params: Vec<FunctionParam> = Vec::new();
let mut triple_dots_count = 0;
let mut is_variadic = false;
let mut list: Vec<FunctionParam> = Vec::new();

while self.current_token.kind != TokenKind::RightParen {
match self.current_token.kind.clone() {
TokenKind::TripleDot => {
if triple_dots_count >= 1 {
return Err(CompileTimeError {
location: self.current_location(),
etype: ParserErrorType::InvalidToken(self.current_token.kind.clone()),
file_name: Some(self.lexer.file_name.clone()),
code_raw: Some(self.lexer.select(func_def_start..self.current_token.span.end + 1)),
verbose: Some(String::from(
"Only one triple_dot is allowed in func decl and it must be positioned as final param.",
)),
caret: true,
});
}
self.next_token();
is_variadic = true;
triple_dots_count += 1;

if self.current_token_is(TokenKind::Comma) {
self.next_token();
continue;
}
}
TokenKind::Identifier { name } => {
self.next_token(); // consume the identifier

Expand All @@ -375,7 +399,7 @@ impl<'a> Parser<'a> {
self.next_token(); // consume the expression
}

params.push(FunctionParam {
list.push(FunctionParam {
identifier: Identifier {
name: name,
span: self.current_token.span.clone(),
Expand Down Expand Up @@ -428,7 +452,7 @@ impl<'a> Parser<'a> {

self.expect_current(TokenKind::RightParen)?;

Ok(params)
Ok(FunctionParams { list, is_variadic })
}

pub fn parse_for_loop(&mut self) -> Result<Statement, ParseError> {
Expand Down Expand Up @@ -687,7 +711,7 @@ impl<'a> Parser<'a> {
}; // export the name of the function
self.next_token(); // consume the name of the identifier

let params = self.parse_func_params()?;
let params = self.parse_func_params(start)?;

let mut return_type: Option<Token> = None;

Expand Down
2 changes: 1 addition & 1 deletion parser/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ mod tests {
fn test_parse_function_params() {
let mut lexer = Lexer::new(String::from("(a: i32, b: u32 = 1, c: string)"), String::from("parser_test.cy"));
let mut parser = Parser::new(&mut lexer);
let params = parser.parse_func_params().unwrap();
let params = parser.parse_func_params(0).unwrap().list;

assert_eq!(params.index(0).identifier.name, "a");
assert_eq!(params.index(0).default_value.is_none(), true);
Expand Down
6 changes: 3 additions & 3 deletions stdlib/io.cy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extern fn printf(fmt: string): void as local_printf;
extern fn printf(fmt: string, ...): void as _printf;

pub fn printf(fmt: string) {
local_printf(fmt);
pub fn printf(fmt: string, ...) {
_printf(fmt);
}

0 comments on commit 8be5629

Please sign in to comment.