feat(gs/achilles): Implement extern decls, for glibc functions

Implement extern decls, which codegen to LLVM as forward-declared
functions, and use these as a hook into calling glibc functions.

We can print to the terminal now! The integration tests can test this
now.

Change-Id: I70af4546b417b888ad9fbb18798db240f77f4e71
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2614
Tested-by: BuildkiteCI
Reviewed-by: glittershark <grfn@gws.fyi>
This commit is contained in:
Griffin Smith 2021-03-19 20:46:19 -04:00 committed by glittershark
parent fec6595d21
commit 2c838ab845
9 changed files with 147 additions and 28 deletions

View file

@ -9,7 +9,7 @@ use inkwell::module::Module;
use inkwell::support::LLVMString;
use inkwell::types::{BasicType, BasicTypeEnum, FunctionType, IntType};
use inkwell::values::{AnyValueEnum, BasicValueEnum, FunctionValue};
use inkwell::IntPredicate;
use inkwell::{AddressSpace, IntPredicate};
use thiserror::Error;
use crate::ast::hir::{Binding, Decl, Expr};
@ -249,6 +249,26 @@ impl<'ctx, 'ast> Codegen<'ctx, 'ast> {
Ok(self.finish_function(&res))
}
pub fn codegen_extern(
&mut self,
name: &str,
args: &'ast [Type],
ret: &'ast Type,
) -> Result<()> {
self.module.add_function(
name,
self.codegen_type(ret).fn_type(
&args
.iter()
.map(|t| self.codegen_type(t))
.collect::<Vec<_>>(),
false,
),
None,
);
Ok(())
}
pub fn codegen_decl(&mut self, decl: &'ast Decl<'ast, Type>) -> Result<()> {
match decl {
Decl::Fun {
@ -257,6 +277,11 @@ impl<'ctx, 'ast> Codegen<'ctx, 'ast> {
self.codegen_function(name.into(), args, body)?;
Ok(())
}
Decl::Extern {
name,
arg_types,
ret_type,
} => self.codegen_extern(name.into(), arg_types, ret_type),
}
}
@ -274,7 +299,18 @@ impl<'ctx, 'ast> Codegen<'ctx, 'ast> {
fn codegen_type(&self, type_: &'ast Type) -> BasicTypeEnum<'ctx> {
// TODO
self.context.i64_type().into()
match type_ {
Type::Int => self.context.i64_type().into(),
Type::Float => self.context.f64_type().into(),
Type::Bool => self.context.bool_type().into(),
Type::CString => self
.context
.i8_type()
.ptr_type(AddressSpace::Generic)
.into(),
Type::Function(_) => todo!(),
Type::Var(_) => unreachable!(),
}
}
fn codegen_int_type(&self, type_: &'ast Type) -> IntType<'ctx> {