tidepool_codegen/emit/
mod.rs1pub mod expr;
2pub mod primop;
3pub mod case;
4pub mod join;
5
6use cranelift_codegen::ir::Value;
7use tidepool_repr::{VarId, JoinId, PrimOpKind};
8use std::collections::HashMap;
9
10pub const HEAP_HEADER_SIZE: u64 = 8;
12pub const CLOSURE_CODE_PTR_OFFSET: i32 = 8;
13pub const CLOSURE_NUM_CAPTURED_OFFSET: i32 = 16;
14pub const CLOSURE_CAPTURED_START: i32 = 24;
15pub const CON_TAG_OFFSET: i32 = 8;
16pub const CON_NUM_FIELDS_OFFSET: i32 = 16;
17pub const CON_FIELDS_START: i32 = 24;
18pub const LIT_TAG_OFFSET: i32 = 8;
19pub const LIT_VALUE_OFFSET: i32 = 16;
20pub const LIT_TOTAL_SIZE: u64 = 24;
21pub const LIT_TAG_INT: i64 = 0;
22pub const LIT_TAG_WORD: i64 = 1;
23pub const LIT_TAG_CHAR: i64 = 2;
24pub const LIT_TAG_FLOAT: i64 = 3;
25pub const LIT_TAG_DOUBLE: i64 = 4;
26pub const LIT_TAG_STRING: i64 = 5;
27
28#[derive(Debug, Clone, Copy)]
30pub enum SsaVal {
31 Raw(Value, i64),
33 HeapPtr(Value),
35}
36
37impl SsaVal {
38 pub fn value(self) -> Value {
39 match self {
40 SsaVal::Raw(v, _) | SsaVal::HeapPtr(v) => v,
41 }
42 }
43}
44
45pub struct EmitContext {
47 pub env: HashMap<VarId, SsaVal>,
48 pub join_blocks: HashMap<JoinId, JoinInfo>,
49 pub lambda_counter: u32,
50 pub prefix: String,
51}
52
53pub struct JoinInfo {
55 pub block: cranelift_codegen::ir::Block,
56 pub param_types: Vec<SsaVal>,
57}
58
59#[derive(Debug)]
61pub enum EmitError {
62 UnboundVariable(VarId),
63 NotYetImplemented(String),
64 CraneliftError(String),
65 InvalidArity(PrimOpKind, usize, usize),
66}
67
68impl std::fmt::Display for EmitError {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 match self {
71 EmitError::UnboundVariable(v) => write!(f, "unbound variable: {:?}", v),
72 EmitError::NotYetImplemented(s) => write!(f, "not yet implemented: {}", s),
73 EmitError::CraneliftError(s) => write!(f, "cranelift error: {}", s),
74 EmitError::InvalidArity(op, expected, got) => {
75 write!(f, "invalid arity for {:?}: expected {}, got {}", op, expected, got)
76 }
77 }
78 }
79}
80
81impl std::error::Error for EmitError {}
82
83impl EmitContext {
84 pub fn new(prefix: String) -> Self {
85 Self {
86 env: HashMap::new(),
87 join_blocks: HashMap::new(),
88 lambda_counter: 0,
89 prefix,
90 }
91 }
92
93 pub fn next_lambda_name(&mut self) -> String {
94 let n = self.lambda_counter;
95 self.lambda_counter += 1;
96 format!("{}_lambda_{}", self.prefix, n)
97 }
98}