Skip to content

Commit

Permalink
Started adding support for inline functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-M-Lucas committed Jun 6, 2024
1 parent 2a22044 commit aad9441
Show file tree
Hide file tree
Showing 13 changed files with 184 additions and 30 deletions.
39 changes: 23 additions & 16 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions src/root/builtin/int/add.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use unique_type_id::UniqueTypeId;
use crate::root::builtin::{BuiltinInlineFunction, InlineFunctionGenerator};
use crate::root::builtin::int::IntType;
use crate::root::errors::WErr;
use crate::root::name_resolver::name_resolvers::NameResult::Function;
use crate::root::name_resolver::resolve_function_signatures::FunctionSignature;

use crate::root::shared::common::{FunctionID, Indirection, LocalAddress, TypeID, TypeRef};

#[derive(UniqueTypeId)]
#[UniqueTypeIdType = "u16"]
pub struct IntAdd {}

impl BuiltinInlineFunction for IntAdd {
fn id(&self) -> FunctionID {
FunctionID(-(IntAdd::unique_type_id().0 as isize) - 1)
}

fn name(&self) -> &'static str {
"add"
}

fn signature(&self) -> FunctionSignature {
FunctionSignature::new_inline_builtin(
&[("lhs", IntType::id().immediate()), ("rhs", IntType::id().immediate())],
Some(IntType::id().immediate())
)
}

fn inline(&self) -> InlineFunctionGenerator {
|args: &[LocalAddress], return_addr: Option<LocalAddress>| -> Result<String, WErr> {
todo!()
}
}

fn parent_type(&self) -> Option<TypeID> {
Some(IntType::id())
}
}
10 changes: 10 additions & 0 deletions src/root/builtin/int.rs → src/root/builtin/int/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
mod add;

use b_box::b;
use unique_type_id::UniqueTypeId;
use crate::root::builtin::int::add::IntAdd;
use crate::root::compiler::assembly::utils::get_qword_stack_pointer;
use crate::root::errors::WErr;
use crate::root::name_resolver::name_resolvers::GlobalDefinitionTable;
use crate::root::parser::parse_function::parse_literal::{LiteralToken, LiteralTokens};
use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, LocalAddress, TypeID};
use crate::root::shared::types::Type;

pub fn register_int(global_table: &mut GlobalDefinitionTable) {
global_table.register_builtin_type("int".to_string(), b!(IntType{}));
global_table.register_inline_function(&IntAdd{});
}

#[derive(UniqueTypeId)]
#[UniqueTypeIdType = "u16"]
pub struct IntType {}
Expand Down
23 changes: 15 additions & 8 deletions src/root/builtin/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
pub mod int;

use crate::root::builtin::int::IntType;
use crate::root::builtin::int::{IntType, register_int};
use crate::root::errors::WErr;
use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable};
use crate::root::name_resolver::resolve_function_signatures::FunctionSignature;
use crate::root::shared::common::{FunctionID, LocalAddress, TypeID};
use crate::root::shared::types::Type;

pub fn register_builtin(global_table: &mut GlobalDefinitionTable) {
let types: [(String, Box<dyn Type>); 1] = [
("int".to_string(), Box::new(IntType{}))
];

for (n, t) in types {
global_table.register_builtin_type(n, t);
}
register_int(global_table);
}

pub type InlineFunctionGenerator = fn(&[LocalAddress], Option<LocalAddress>) -> Result<String, WErr>;

pub trait BuiltinInlineFunction {
fn id(&self) -> FunctionID;
fn name(&self) -> &'static str;
fn signature(&self) -> FunctionSignature;
fn inline(&self) -> InlineFunctionGenerator;
fn parent_type(&self) -> Option<TypeID>;
}
6 changes: 6 additions & 0 deletions src/root/compiler/compile_function_call.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use crate::root::errors::WErr;
use crate::root::shared::common::{FunctionID, LocalAddress};

pub fn call_function(fid: FunctionID, arguments: &[LocalAddress], return_address: Option<LocalAddress>) -> Result<String, WErr> {
todo!()
}
3 changes: 2 additions & 1 deletion src/root/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ pub mod compile;
pub mod local_variable_table;
mod compile_function;
pub mod assembly;
mod compile_evaluable;
mod compile_evaluable;
pub mod compile_function_call;
2 changes: 1 addition & 1 deletion src/root/name_resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pub mod resolve;
pub mod resolve_names;
pub mod resolve_type_sizes;
pub mod name_resolvers;
mod resolve_function_signatures;
pub mod resolve_function_signatures;
41 changes: 37 additions & 4 deletions src/root/name_resolver/name_resolvers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::path::PathBuf;
use std::rc::Rc;
use derive_getters::Getters;
use either::{Either, Left, Right};
use crate::root::builtin::{BuiltinInlineFunction, InlineFunctionGenerator};
use crate::root::compiler::compile_function_call::call_function;
use crate::root::compiler::local_variable_table::LocalVariableTable;
use crate::root::errors::name_resolver_errors::NRErrors;
use crate::root::errors::name_resolver_errors::NRErrors::IdentifierNotFound;
Expand All @@ -16,7 +18,7 @@ use crate::root::parser::parse_function::parse_evaluable::{FullNameToken, FullNa
use crate::root::parser::parse_name::SimpleNameToken;
use crate::root::parser::parse_struct::StructToken;
use crate::root::POINTER_SIZE;
use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, TypeID, TypeRef};
use crate::root::shared::common::{AddressedTypeRef, ByteSize, FunctionID, LocalAddress, TypeID, TypeRef};

#[derive(Debug)]
enum NameTreeEntry {
Expand Down Expand Up @@ -55,11 +57,13 @@ impl TopLevelNameTree {
}
}


pub struct GlobalDefinitionTable {
id_counter: isize,
type_definitions: HashMap<TypeID, Box<dyn Type>>,
impl_definitions: HashMap<TypeID, HashMap<String, FunctionID>>,
function_signatures: HashMap<FunctionID, FunctionSignature>,
inline_functions: HashMap<FunctionID, InlineFunctionGenerator>,
name_table: TopLevelNameTree,
builtin_type_name_table: HashMap<String, TypeID>,
builtin_function_name_table: HashMap<String, FunctionID>
Expand All @@ -79,6 +83,7 @@ impl GlobalDefinitionTable {
type_definitions: Default::default(),
impl_definitions: Default::default(),
function_signatures: Default::default(),
inline_functions: Default::default(),
name_table: Default::default(),
builtin_type_name_table: Default::default(),
builtin_function_name_table: Default::default(),
Expand All @@ -90,9 +95,29 @@ impl GlobalDefinitionTable {
self.builtin_type_name_table.insert(name, id);
}

pub fn register_builtin_function(&mut self, name: String, t: FunctionSignature, id: FunctionID) {
self.function_signatures.insert(id, t);
self.builtin_function_name_table.insert(name, id);
// pub fn register_builtin_function(&mut self, name: String, t: FunctionSignature, id: FunctionID) {
// self.function_signatures.insert(id, t);
// self.builtin_function_name_table.insert(name, id);
// }

fn get_impl_mut(&mut self, t: TypeID) -> &mut HashMap<String, FunctionID> {
if !self.impl_definitions.contains_key(&t) {
self.impl_definitions.insert(t, Default::default());
}

self.impl_definitions.get_mut(&t).unwrap()
}

pub fn register_inline_function(&mut self, inline: &dyn BuiltinInlineFunction) {
self.function_signatures.insert(inline.id(), inline.signature());
self.inline_functions.insert(inline.id(), inline.inline());

if let Some(parent) = inline.parent_type() {
self.get_impl_mut(parent).insert(inline.name().to_string(), inline.id());
}
else {
self.builtin_function_name_table.insert(inline.name().to_string(), inline.id());
}
}

pub fn add_from_struct_token(&mut self, st: &StructToken) -> TypeID {
Expand Down Expand Up @@ -271,4 +296,12 @@ impl GlobalDefinitionTable {

Err(WErr::n(NRErrors::CannotFindName(name.name().clone()), name.location().clone()))
}

pub fn call_function(&self, function: FunctionID, arguments: &[LocalAddress], return_address: Option<LocalAddress>) -> Result<String, WErr> {
if let Some(inline) = self.inline_functions.get(&function) {
return inline(arguments, return_address);
}

call_function(function, arguments, return_address)
}
}
10 changes: 10 additions & 0 deletions src/root/name_resolver/resolve_function_signatures.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use derive_getters::Getters;
use itertools::Itertools;
use crate::root::errors::WErr;
use crate::root::name_resolver::name_resolvers::{GlobalDefinitionTable};
use crate::root::shared::common::TypeRef;
Expand All @@ -11,6 +12,15 @@ pub struct FunctionSignature {
return_type: Option<TypeRef>
}

impl FunctionSignature {
pub fn new_inline_builtin(args: &[(&str, TypeRef)], return_type: Option<TypeRef>) -> FunctionSignature {
FunctionSignature {
args: args.into_iter().map(|(name, t)| (SimpleNameToken::new_builtin(name.to_string()), t.clone())).collect_vec(),
return_type
}
}
}

pub fn resolve_function_signature(function_token: &FunctionToken, global_table: &mut GlobalDefinitionTable) -> Result<FunctionSignature, WErr> {
let mut args = Vec::new();

Expand Down
23 changes: 23 additions & 0 deletions src/root/parser/parse.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::cmp::min;
use std::ffi::OsStr;
use std::fmt::{Display, Formatter};
use crate::root::parser::parse_toplevel;
use nom::IResult;
Expand All @@ -9,6 +10,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use color_print::cformat;
use derive_getters::Getters;
use lazy_static::lazy_static;
use crate::root::errors::WErr;
use crate::root::parser::parse_toplevel::TopLevelTokens;

Expand All @@ -22,6 +24,10 @@ pub type ErrorTree<'a> = GenericErrorTree<
Box<dyn std::error::Error + Send + Sync + 'static>,
>;

lazy_static! {
static ref BUILTIN_PATH: &'static OsStr = OsStr::new("builtin");
}

#[derive(Debug, Clone, Getters, Hash)]
pub struct Location {
path: Rc<PathBuf>,
Expand All @@ -39,6 +45,18 @@ impl Location {
line: span.location_line(),
}
}

pub fn builtin() -> Location {
Location {
path: Rc::new(PathBuf::from(*BUILTIN_PATH)),
offset: 0,
line: 0
}
}

pub fn is_builtin(&self) -> bool {
self.path.as_os_str() == *BUILTIN_PATH
}
}

const CHAR_LIMIT: usize = 61;
Expand All @@ -49,6 +67,11 @@ impl Display for Location {
// TODO: Inefficient!
// (Maybe fine because it is a 'bad' path?)

if self.path.as_os_str() == *BUILTIN_PATH {
writeln!(f, "{}", cformat!("<c,bold>Builtin Definition</>"))?;
return Ok(())
}

writeln!(f, "{}", cformat!("<c,bold>In File:</>"))?;
writeln!(f, " {}", self.path.as_path().to_string_lossy())?;
writeln!(f, "{}", cformat!("<c,bold>At:</>"))?;
Expand Down
7 changes: 7 additions & 0 deletions src/root/parser/parse_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ impl SimpleNameToken {
name: s.to_string()
}
}

pub fn new_builtin(s: String) -> SimpleNameToken {
SimpleNameToken {
location: Location::builtin(),
name: s.to_string()
}
}
}

pub fn parse_simple_name<'a>(s: Span<'a>) -> ParseResult<'a, Span, SimpleNameToken> {
Expand Down
10 changes: 10 additions & 0 deletions src/root/shared/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ use derive_getters::{Dissolve, Getters};
#[display(fmt = "TypeID: {}", .0)]
pub struct TypeID(pub isize);

impl TypeID {
pub fn with_indirection(self, indirection: usize) -> TypeRef {
TypeRef::new(self, Indirection(indirection))
}

pub fn immediate(self) -> TypeRef {
TypeRef::new(self, Indirection(0))
}
}

#[derive(Debug, PartialEq, Eq, Hash, Display, Copy, Clone)]
#[display(fmt = "FunctionID: {}", .0)]
pub struct FunctionID(pub isize);
Expand Down
1 change: 1 addition & 0 deletions types.toml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
IntType=0
IntAdd=1

0 comments on commit aad9441

Please sign in to comment.