Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

Begin implementation of mir

Instead of attempting to compile directly from Gleam's typed AST
(granted it does have a few transformations already), we instead compile
this typed AST down to a lower level IR that will make compiling with
cranelift much easier.

author
Danielle Maywood
committer
nandi
date (Jul 26, 2026, 12:11 PM -0700) commit b07e9632 parent 1a7fd9ce change-id qqqmvnml
+131 -1
+25 -1
compiler-core/src/codegen.rs
··· 7 7 ErlangAppCodegenConfiguration, Module, module_erlang_name, package_compiler::StdlibPackage, 8 8 }, 9 9 config::PackageConfig, 10 - erlang, 10 + cranelift, erlang, 11 11 io::FileSystemWriter, 12 12 javascript::{self, ModuleConfig}, 13 13 line_numbers::LineNumbers, ··· 338 338 insta::assert_snapshot!(app); 339 339 } 340 340 } 341 + 342 + #[derive(Debug)] 343 + pub struct Cranelift<'a> { 344 + output_directory: &'a Utf8Path, 345 + } 346 + 347 + impl<'a> Cranelift<'a> { 348 + pub fn new(output_directory: &'a Utf8Path) -> Self { 349 + Self { output_directory } 350 + } 351 + 352 + pub fn render(&self, writer: &impl FileSystemWriter, modules: &[Module]) -> Result<()> { 353 + _ = self.output_directory; 354 + _ = writer; 355 + 356 + for module in modules { 357 + let mir_module = cranelift::mir::Translator::default().translate(&module.ast); 358 + 359 + dbg!(mir_module); 360 + } 361 + 362 + Ok(()) 363 + } 364 + }
+1
compiler-core/src/cranelift.rs
··· 1 + pub mod mir;
+87
compiler-core/src/cranelift/mir.rs
··· 1 + use ecow::EcoString; 2 + 3 + use crate::{ast, type_}; 4 + 5 + #[derive(Debug, Default)] 6 + pub struct Module { 7 + functions: Vec<Function>, 8 + } 9 + 10 + #[derive(Debug)] 11 + pub struct Function { 12 + pub name: EcoString, 13 + pub parameters: Vec<FunctionParameter>, 14 + } 15 + 16 + #[derive(Debug)] 17 + pub struct FunctionParameter { 18 + pub type_: Type, 19 + pub name: Option<EcoString>, 20 + } 21 + 22 + #[derive(Debug, Default)] 23 + pub struct Translator { 24 + module: Module, 25 + } 26 + 27 + #[derive(Debug, Clone, Copy)] 28 + pub enum Type { 29 + Int, 30 + Float, 31 + } 32 + 33 + impl Translator { 34 + pub fn translate(mut self, module: &ast::TypedModule) -> Module { 35 + for definition in &module.definitions { 36 + match definition { 37 + ast::Definition::Function(function) => { 38 + self.module 39 + .functions 40 + .push(Self::translate_function(function)); 41 + } 42 + ast::Definition::TypeAlias(_type_alias) => todo!(), 43 + ast::Definition::CustomType(_custom_type) => todo!(), 44 + ast::Definition::Import(_import) => todo!(), 45 + ast::Definition::ModuleConstant(_module_constant) => todo!(), 46 + } 47 + } 48 + 49 + self.module 50 + } 51 + 52 + fn translate_function(function: &ast::TypedFunction) -> Function { 53 + let (_, name) = function.name.clone().expect("function should have a name"); 54 + 55 + let parameters = Iterator::collect(function.arguments.iter().map(|argument| { 56 + let name = argument.get_variable_name().cloned(); 57 + let type_ = Self::translate_type(&argument.type_); 58 + 59 + FunctionParameter { name, type_ } 60 + })); 61 + 62 + Function { name, parameters } 63 + } 64 + 65 + fn translate_type(type_: &type_::Type) -> Type { 66 + match type_ { 67 + type_::Type::Named { 68 + publicity: _, 69 + package: _, 70 + module, 71 + name, 72 + arguments: _, 73 + inferred_variant: _, 74 + } => match (module.as_str(), name.as_str()) { 75 + ("gleam", "Int") => Type::Int, 76 + ("gleam", "Float") => Type::Float, 77 + (_, _) => todo!(), 78 + }, 79 + type_::Type::Fn { 80 + arguments: _, 81 + return_: _, 82 + } => todo!(), 83 + type_::Type::Var { type_: _ } => todo!(), 84 + type_::Type::Tuple { elements: _ } => todo!(), 85 + } 86 + } 87 + }
+1
compiler-core/src/lib.rs
··· 72 72 pub mod build; 73 73 pub mod codegen; 74 74 pub mod config; 75 + pub mod cranelift; 75 76 pub mod dependency; 76 77 pub mod diagnostic; 77 78 pub mod docs;
+4
test/project_cranelift/.gitignore
··· 1 + *.beam 2 + *.ez 3 + /build 4 + erl_crash.dump
+3
test/project_cranelift/gleam.toml
··· 1 + name = "project_cranelift" 2 + version = "1.0.0" 3 + target = "cranelift"
+7
test/project_cranelift/manifest.toml
··· 1 + # This file was generated by Gleam 2 + # You typically do not need to edit this file 3 + 4 + packages = [ 5 + ] 6 + 7 + [requirements]
+3
test/project_cranelift/src/project_cranelift.gleam
··· 1 + pub fn add(lhs: Int, rhs: Int) -> Int { 2 + lhs + rhs 3 + }