Skip to content

Commit

Permalink
generating 'extern' functions and interfacing with C
Browse files Browse the repository at this point in the history
  • Loading branch information
rigel-star committed Jul 25, 2024
1 parent 618e734 commit 3f1b57e
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 20 deletions.
4 changes: 2 additions & 2 deletions bichara
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ elif [ "$1" = "build" ]; then
fi
OUTPUT_FILE="$2"
if ! [ -e "./$OUTPUT_DIR/ir" ]; then mkdir -p "./$OUTPUT_DIR/ir"; fi
cargo run 1> "./$OUTPUT_DIR/ir/$OUTPUT_FILE"
cargo run 1> "./$OUTPUT_DIR/ir/$OUTPUT_FILE.S"
if ! [ $? -eq 0 ]; then
echo "*** COMPILATION FAILED ***";
exit 2;
fi
gcc -o "./$OUTPUT_DIR/output" "./$OUTPUT_DIR/ir/$OUTPUT_FILE"
gcc -o "./$OUTPUT_DIR/ir/$OUTPUT_FILE" "./$OUTPUT_DIR/ir/$OUTPUT_FILE.S" "./$OUTPUT_DIR/ir/"*.c -lm
fi
6 changes: 2 additions & 4 deletions examples/input1.bic
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
def print_me() -> void {
let a = 222;
}
def extern calculate_sin_5() -> void;

def main() -> void {
print_me();
calculate_sin_5();
}
6 changes: 5 additions & 1 deletion src/code_gen/aarch64/aarch64_codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> {
panic!("Please provide a context to work on!");
};
// function preamble
if func_info.storage_class == StorageClass::EXTERN {
println!(".extern _{}", func_name);
return 0xFFFFFFFF;
}
println!(".global _{}\n_{}:", func_name, func_name);
println!("sub sp, sp, {}", func_info.stack_size);
if let Some(ref body) = ast.left {
Expand Down Expand Up @@ -381,7 +385,7 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> {
if let Some(ctx_rc) = &self.ctx {
let ctx_borrow = ctx_rc.borrow_mut();
if let Some(symbol) = ctx_borrow.sym_table.get_symbol(symbol_id) {
println!("call {}", symbol.name);
println!("bl _{}", symbol.name);
}
}
}
Expand Down
33 changes: 26 additions & 7 deletions src/parser/parser_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@ impl<'parser> Parser<'parser> {
self.local_offset = 0;
// match and ignore function declaration keyword 'def'
_ = self.token_match(TokenKind::KW_DEF);

// Storage class of the function that is being parsed.
// By default, it is set to 'GLOBAL'.
let mut func_storage_class: StorageClass = StorageClass::GLOBAL;

// 'def' keyword could be followed by the 'extern' keyword,
// symbolizing the external definition of the function's body.
if self.current_token.kind == TokenKind::KW_EXTERN {
_ = self.token_match(TokenKind::KW_EXTERN);
func_storage_class = StorageClass::EXTERN;
}

let id_token: Token = self.token_match(TokenKind::T_IDENTIFIER).clone();
_ = self.token_match(TokenKind::T_LPAREN);
_ = self.token_match(TokenKind::T_RPAREN);
Expand All @@ -264,7 +276,7 @@ impl<'parser> Parser<'parser> {
id_token.lexeme.clone(),
func_return_type,
SymbolType::Function,
StorageClass::GLOBAL,
func_storage_class,
));
// in case the function symbol addition process fails
if function_id.is_none() {
Expand All @@ -274,12 +286,18 @@ impl<'parser> Parser<'parser> {
)));
}
self.current_function_id = function_id.unwrap();
let mut function_body: Option<AST> = None;
// create function body
let function_body_res: ParseResult2 = self.parse_compound_stmt();
let function_body: AST = match function_body_res {
Ok(ast) => ast,
Err(err) => return Err(err)
};
if func_storage_class != StorageClass::EXTERN {
let function_body_res: ParseResult2 = self.parse_compound_stmt();
let __body: AST = match function_body_res {
Ok(ast) => ast,
Err(err) => return Err(err)
};
function_body = Some(__body);
} else {
_ = self.token_match(TokenKind::T_SEMICOLON);
}
let temp_func_id: usize = self.current_function_id;
self.current_function_id = INVALID_FUNC_ID; // function parsing done; exiting out of function body
// function information collection
Expand All @@ -289,6 +307,7 @@ impl<'parser> Parser<'parser> {
function_id.unwrap(),
stack_offset,
func_return_type,
func_storage_class
);
// create a new FunctionInfo
if let Some(ctx_rc) = &mut self.ctx {
Expand All @@ -304,7 +323,7 @@ impl<'parser> Parser<'parser> {
func_id: temp_func_id,
})),
ASTOperation::AST_FUNCTION,
Some(function_body),
function_body,
None,
func_return_type,
))
Expand Down
16 changes: 13 additions & 3 deletions src/symbol/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ SOFTWARE.
use std::collections::HashMap;
use crate::types::LitTypeVariant;

use super::StorageClass;

/// Limit of local variables in a function.
pub const LOCAL_LIMIT: usize = 1024;

Expand Down Expand Up @@ -87,17 +89,25 @@ pub struct FunctionInfo {
pub stack_size: i32,
pub return_type: LitTypeVariant,
/// Contains information about the variables defined locally in 'this' function
pub local_syms: LocalSymtable
pub local_syms: LocalSymtable,
pub storage_class: StorageClass
}

impl FunctionInfo {
pub fn new(name: String, func_id: usize, stack_size: i32, return_type: LitTypeVariant) -> Self {
pub fn new(
name: String,
func_id: usize,
stack_size: i32,
return_type: LitTypeVariant,
storage_class: StorageClass
) -> Self {
Self {
name,
func_id,
stack_size,
return_type,
local_syms: LocalSymtable::new()
local_syms: LocalSymtable::new(),
storage_class
}
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/symbol/sym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,17 @@ pub enum SymbolType {

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum StorageClass {
GLOBAL, // globally visible symbol
LOCAL, // locally visible symbol
PARAM, // locally visible function parameter
/// Globally visible symbol.
GLOBAL,

/// Locally visible symbol.
LOCAL,

/// Locally visible function parameter.
PARAM,

/// Externally defined symbol.
EXTERN
}

#[derive(Clone, PartialEq, Debug)]
Expand Down

0 comments on commit 3f1b57e

Please sign in to comment.