Skip to main content

seqc/codegen/
runtime.rs

1//! Runtime function declarations for LLVM IR.
2//!
3//! The full set of `declare` statements and Seq-word → C-symbol mappings is
4//! split across the sibling `runtime/` sub-modules by category. Each
5//! sub-module exposes two slices — `DECLS` and `SYMBOLS` — and this file
6//! concatenates them into the public `RUNTIME_DECLARATIONS` and
7//! `BUILTIN_SYMBOLS` statics used by the rest of codegen.
8//!
9//! Adding a new runtime entry point is a two-line edit to the appropriate
10//! sub-module: append a `RuntimeDecl { decl, category }` and, if the entry
11//! point is callable from Seq, append a `(seq-word, c-symbol)` pair.
12
13mod adt;
14mod args_exit;
15mod arith;
16mod callable;
17mod closure;
18mod collections;
19mod concurrency;
20mod dns;
21mod float;
22mod fs;
23mod http;
24mod misc;
25mod os;
26mod stack;
27mod stdio;
28mod tcp;
29mod test_time;
30mod text;
31mod tls;
32mod udp;
33
34use super::error::CodeGenError;
35use std::collections::HashMap;
36use std::fmt::Write as _;
37use std::sync::LazyLock;
38
39/// A runtime function declaration for LLVM IR.
40pub struct RuntimeDecl {
41    /// LLVM declaration string (e.g., "declare ptr @patch_seq_add(ptr)")
42    pub decl: &'static str,
43    /// Optional category comment (e.g., "; Stack operations")
44    pub category: Option<&'static str>,
45}
46
47/// All runtime function declarations, assembled in IR-emission order.
48pub static RUNTIME_DECLARATIONS: LazyLock<Vec<&'static RuntimeDecl>> = LazyLock::new(|| {
49    let slices: &[&[RuntimeDecl]] = &[
50        stdio::DECLS,
51        arith::DECLS,
52        stack::DECLS,
53        callable::DECLS,
54        closure::DECLS,
55        concurrency::DECLS,
56        args_exit::DECLS,
57        fs::DECLS,
58        collections::DECLS,
59        tcp::DECLS,
60        udp::DECLS,
61        dns::DECLS,
62        tls::DECLS,
63        http::DECLS,
64        os::DECLS,
65        text::DECLS,
66        adt::DECLS,
67        float::DECLS,
68        test_time::DECLS,
69        misc::DECLS,
70    ];
71    slices.iter().flat_map(|s| s.iter()).collect()
72});
73
74/// Mapping from Seq word names to their C runtime symbol names.
75/// This centralizes all the name transformations in one place:
76/// - Symbolic operators (=, <, >) map to descriptive names (eq, lt, gt)
77/// - Hyphens become underscores for C compatibility
78/// - Special characters get escaped (?, +, ->)
79/// - Reserved words get suffixes (drop -> drop_op)
80pub static BUILTIN_SYMBOLS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
81    let slices: &[&[(&str, &str)]] = &[
82        stdio::SYMBOLS,
83        args_exit::SYMBOLS,
84        arith::SYMBOLS,
85        stack::SYMBOLS,
86        concurrency::SYMBOLS,
87        callable::SYMBOLS,
88        closure::SYMBOLS,
89        tcp::SYMBOLS,
90        udp::SYMBOLS,
91        dns::SYMBOLS,
92        tls::SYMBOLS,
93        http::SYMBOLS,
94        os::SYMBOLS,
95        text::SYMBOLS,
96        misc::SYMBOLS,
97        adt::SYMBOLS,
98        fs::SYMBOLS,
99        collections::SYMBOLS,
100        float::SYMBOLS,
101        test_time::SYMBOLS,
102    ];
103    slices.iter().flat_map(|s| s.iter().copied()).collect()
104});
105
106/// Emit all runtime function declarations to the IR string.
107pub fn emit_runtime_decls(ir: &mut String) -> Result<(), CodeGenError> {
108    for decl in RUNTIME_DECLARATIONS.iter() {
109        if let Some(cat) = decl.category {
110            writeln!(ir, "{}", cat)?;
111        }
112        writeln!(ir, "{}", decl.decl)?;
113    }
114    writeln!(ir)?;
115    Ok(())
116}