1mod binding;
2mod compile_eval;
3mod control;
4mod iteration;
5mod labels;
6mod lambda;
7mod macros;
8mod structure;
9
10use tracing::debug;
11
12use crate::ast::Expr;
13use crate::error::{Error, Result};
14use crate::runtime::SymbolTable;
15
16use crate::ast::WasmType;
17
18use super::context::CompileContext;
19use super::emit::FunctionEmitter;
20
21pub(in crate::compiler) use control::is_truthy;
22pub(in crate::compiler) use structure::set_place as setf_set_place;
23
24pub fn call(symbols: &mut SymbolTable, name: &str, args: &[Expr]) -> Result<Expr> {
25 debug!(special_form = %name, args = args.len(), "calling special form");
26 match name {
27 "QUOTE" => control::quote(args),
28 "DEFUN" => binding::defun(symbols, args),
29 "LAMBDA" => lambda::lambda(args),
30 "FUNCTION" => lambda::function_form(symbols, args),
31 "DEFVAR" => binding::defvar(symbols, args),
32 "DEFPARAMETER" => binding::defparameter(symbols, args),
33 "DESCRIBE" => compile_eval::describe(symbols, args),
34 "FUNCALL" => lambda::funcall(symbols, args),
35 "APPLY" => lambda::apply(symbols, args),
36 "BEGIN" => control::begin_form(symbols, args),
37 "AND" => control::and_form(symbols, args),
38 "OR" => control::or_form(symbols, args),
39 "IF" => control::if_form(symbols, args),
40 "COND" => control::cond_form(symbols, args),
41 "LET" => binding::let_form(symbols, args),
42 "LET*" => binding::let_star(symbols, args),
43 "DO" => iteration::do_form(symbols, args),
44 "DO*" => iteration::do_star_form(symbols, args),
45 "DEFMACRO" => macros::defmacro(symbols, args),
46 "MACROEXPAND-1" => macros::macroexpand_1(symbols, args),
47 "MACROEXPAND" => macros::macroexpand(symbols, args),
48 "COMPILE" => compile_eval::compile_form(symbols, args),
49 "EVAL" => compile_eval::eval_form(symbols, args),
50 "LABELS" => labels::labels_form(symbols, args),
51 "DOLIST" => iteration::dolist_form(symbols, args),
52 "DEFSTRUCT" => structure::defstruct(symbols, args),
53 "SETF" => structure::setf(symbols, args),
54 _ => Err(Error::Compile(format!(
55 "special form '{name}' not yet implemented"
56 ))),
57 }
58}
59
60pub(super) fn compile(
61 ctx: &mut CompileContext,
62 emit: &mut FunctionEmitter,
63 symbols: &mut SymbolTable,
64 name: &str,
65 args: &[Expr],
66) -> Result<()> {
67 debug!(special_form = %name, args = args.len(), "compiling special form");
68 match name {
69 "QUOTE" => control::compile_quote(ctx, emit, args),
70 "DEFUN" => binding::compile_defun(ctx, emit, symbols, args),
71 "LAMBDA" => lambda::compile_lambda_form(ctx, emit, args),
72 "FUNCTION" => lambda::compile_function_form(ctx, emit, symbols, args),
73 "DEFVAR" => binding::compile_defvar(ctx, emit, symbols, args),
74 "DEFPARAMETER" => binding::compile_defparam(ctx, emit, symbols, args),
75 "DESCRIBE" => compile_eval::compile_describe(ctx, emit, symbols, args),
76 "FUNCALL" => lambda::compile_funcall(ctx, emit, symbols, args),
77 "APPLY" => lambda::compile_apply_form(ctx, emit, symbols, args),
78 "BEGIN" => control::compile_begin(ctx, emit, symbols, args),
79 "AND" => control::compile_and(ctx, emit, symbols, args),
80 "OR" => control::compile_or(ctx, emit, symbols, args),
81 "IF" => control::compile_if(ctx, emit, symbols, args),
82 "COND" => control::compile_cond(ctx, emit, symbols, args),
83 "LET" => binding::compile_let(ctx, emit, symbols, args),
84 "LET*" => binding::compile_let_star(ctx, emit, symbols, args),
85 "DO" => iteration::compile_do(ctx, emit, symbols, args),
86 "DO*" => iteration::compile_do_star(ctx, emit, symbols, args),
87 "DEFMACRO" => macros::compile_defmacro_form(ctx, emit, symbols, args),
88 "MACROEXPAND-1" => macros::compile_macroexpand_1_form(ctx, emit, symbols, args),
89 "MACROEXPAND" => macros::compile_macroexpand_form(ctx, emit, symbols, args),
90 "COMPILE" => compile_eval::compile_compile_form(ctx, emit, symbols, args),
91 "EVAL" => compile_eval::compile_eval_form(ctx, emit, symbols, args),
92 "LABELS" => labels::compile_labels(ctx, emit, symbols, args),
93 "DOLIST" => iteration::compile_dolist(ctx, emit, symbols, args),
94 "DEFSTRUCT" => structure::compile_defstruct(ctx, emit, symbols, args),
95 "SETF" => structure::compile_setf(ctx, emit, symbols, args),
96 _ => Err(Error::Compile(format!(
97 "special form '{name}' not yet implemented"
98 ))),
99 }
100}
101
102pub(super) fn compile_for_effect(
103 ctx: &mut CompileContext,
104 emit: &mut FunctionEmitter,
105 symbols: &mut SymbolTable,
106 name: &str,
107 args: &[Expr],
108) -> Result<()> {
109 match name {
110 "DO" => iteration::compile_do_for_effect(ctx, emit, symbols, args),
111 "DO*" => iteration::compile_do_star_for_effect(ctx, emit, symbols, args),
112 "DOLIST" => iteration::compile_dolist_for_effect(ctx, emit, symbols, args),
113 "LET" => binding::compile_let_for_effect(ctx, emit, symbols, args),
114 "LET*" => binding::compile_let_star_for_effect(ctx, emit, symbols, args),
115 "COND" => control::compile_cond_for_effect(ctx, emit, symbols, args),
116 "AND" => control::compile_and_for_effect(ctx, emit, symbols, args),
117 "OR" => control::compile_or_for_effect(ctx, emit, symbols, args),
118 _ => compile(ctx, emit, symbols, name, args),
119 }
120}
121
122pub(super) fn compile_for_stack(
123 ctx: &mut CompileContext,
124 emit: &mut FunctionEmitter,
125 symbols: &mut SymbolTable,
126 name: &str,
127 args: &[Expr],
128) -> Result<WasmType> {
129 match name {
130 "IF" => control::compile_if_for_stack(ctx, emit, symbols, args),
131 "AND" => control::compile_and_for_stack(ctx, emit, symbols, args),
132 "OR" => control::compile_or_for_stack(ctx, emit, symbols, args),
133 "DO" => iteration::compile_do_for_stack(ctx, emit, symbols, args),
134 "DO*" => iteration::compile_do_star_for_stack(ctx, emit, symbols, args),
135 "LET" => binding::compile_let_for_stack(ctx, emit, symbols, args),
136 "LET*" => binding::compile_let_star_for_stack(ctx, emit, symbols, args),
137 "BEGIN" => control::compile_begin_for_stack(ctx, emit, symbols, args),
138 _ => Err(Error::Compile(format!(
139 "special form '{name}' cannot produce stack value"
140 ))),
141 }
142}