about summary refs log tree commit diff
path: root/users/glittershark/achilles/src/codegen
diff options
context:
space:
mode:
authorGriffin Smith <grfn@gws.fyi>2021-03-20T00·46-0400
committerglittershark <grfn@gws.fyi>2021-03-20T20·20+0000
commit2c838ab845bc54c5ef6cb0561332c84f34249368 (patch)
treec54c95ebc7f503a1db255566b3e25494bbaa28b3 /users/glittershark/achilles/src/codegen
parentfec6595d211e7e3ea616d8335fe5d143a4a7507d (diff)
feat(gs/achilles): Implement extern decls, for glibc functions r/2293
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>
Diffstat (limited to 'users/glittershark/achilles/src/codegen')
-rw-r--r--users/glittershark/achilles/src/codegen/llvm.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/users/glittershark/achilles/src/codegen/llvm.rs b/users/glittershark/achilles/src/codegen/llvm.rs
index 9b580d3c4536..f49e084a8174 100644
--- a/users/glittershark/achilles/src/codegen/llvm.rs
+++ b/users/glittershark/achilles/src/codegen/llvm.rs
@@ -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> {