1
mod binding;
2
mod compile_eval;
3
mod control;
4
mod iteration;
5
mod labels;
6
mod lambda;
7
mod macros;
8
mod structure;
9

            
10
use tracing::debug;
11

            
12
use crate::ast::Expr;
13
use crate::error::{Error, Result};
14
use crate::runtime::SymbolTable;
15

            
16
use crate::ast::WasmType;
17

            
18
use super::context::CompileContext;
19
use super::emit::FunctionEmitter;
20

            
21
pub(in crate::compiler) use control::is_truthy;
22
pub(in crate::compiler) use structure::set_place as setf_set_place;
23

            
24
96963
pub fn call(symbols: &mut SymbolTable, name: &str, args: &[Expr]) -> Result<Expr> {
25
96963
    debug!(special_form = %name, args = args.len(), "calling special form");
26
96963
    match name {
27
96963
        "QUOTE" => control::quote(args),
28
96831
        "DEFUN" => binding::defun(symbols, args),
29
93783
        "LAMBDA" => lambda::lambda(args),
30
93387
        "FUNCTION" => lambda::function_form(symbols, args),
31
93343
        "DEFVAR" => binding::defvar(symbols, args),
32
93079
        "DEFPARAMETER" => binding::defparameter(symbols, args),
33
92991
        "DESCRIBE" => compile_eval::describe(symbols, args),
34
92991
        "FUNCALL" => lambda::funcall(symbols, args),
35
92991
        "APPLY" => lambda::apply(symbols, args),
36
92771
        "BEGIN" => control::begin_form(symbols, args),
37
92593
        "AND" => control::and_form(symbols, args),
38
90851
        "OR" => control::or_form(symbols, args),
39
90851
        "IF" => control::if_form(symbols, args),
40
90057
        "COND" => control::cond_form(symbols, args),
41
89655
        "LET" => binding::let_form(symbols, args),
42
86975
        "LET*" => binding::let_star(symbols, args),
43
86573
        "DO" => iteration::do_form(symbols, args),
44
84519
        "DO*" => iteration::do_star_form(symbols, args),
45
84519
        "DEFMACRO" => macros::defmacro(symbols, args),
46
75015
        "MACROEXPAND-1" => macros::macroexpand_1(symbols, args),
47
74971
        "MACROEXPAND" => macros::macroexpand(symbols, args),
48
74971
        "COMPILE" => compile_eval::compile_form(symbols, args),
49
74971
        "EVAL" => compile_eval::eval_form(symbols, args),
50
74883
        "LABELS" => labels::labels_form(symbols, args),
51
74883
        "DOLIST" => iteration::dolist_form(symbols, args),
52
73593
        "DEFSTRUCT" => structure::defstruct(symbols, args),
53
44
        "SETF" => structure::setf(symbols, args),
54
        _ => Err(Error::Compile(format!(
55
            "special form '{name}' not yet implemented"
56
        ))),
57
    }
58
96963
}
59

            
60
14522
pub(super) fn compile(
61
14522
    ctx: &mut CompileContext,
62
14522
    emit: &mut FunctionEmitter,
63
14522
    symbols: &mut SymbolTable,
64
14522
    name: &str,
65
14522
    args: &[Expr],
66
14522
) -> Result<()> {
67
14522
    debug!(special_form = %name, args = args.len(), "compiling special form");
68
14522
    match name {
69
14522
        "QUOTE" => control::compile_quote(ctx, emit, args),
70
14434
        "DEFUN" => binding::compile_defun(ctx, emit, symbols, args),
71
14344
        "LAMBDA" => lambda::compile_lambda_form(ctx, emit, args),
72
14300
        "FUNCTION" => lambda::compile_function_form(ctx, emit, symbols, args),
73
14300
        "DEFVAR" => binding::compile_defvar(ctx, emit, symbols, args),
74
14300
        "DEFPARAMETER" => binding::compile_defparam(ctx, emit, symbols, args),
75
14300
        "DESCRIBE" => compile_eval::compile_describe(ctx, emit, symbols, args),
76
14168
        "FUNCALL" => lambda::compile_funcall(ctx, emit, symbols, args),
77
13948
        "APPLY" => lambda::compile_apply_form(ctx, emit, symbols, args),
78
13860
        "BEGIN" => control::compile_begin(ctx, emit, symbols, args),
79
13772
        "AND" => control::compile_and(ctx, emit, symbols, args),
80
13684
        "OR" => control::compile_or(ctx, emit, symbols, args),
81
13640
        "IF" => control::compile_if(ctx, emit, symbols, args),
82
12056
        "COND" => control::compile_cond(ctx, emit, symbols, args),
83
11660
        "LET" => binding::compile_let(ctx, emit, symbols, args),
84
11000
        "LET*" => binding::compile_let_star(ctx, emit, symbols, args),
85
10428
        "DO" => iteration::compile_do(ctx, emit, symbols, args),
86
9724
        "DO*" => iteration::compile_do_star(ctx, emit, symbols, args),
87
9504
        "DEFMACRO" => macros::compile_defmacro_form(ctx, emit, symbols, args),
88
616
        "MACROEXPAND-1" => macros::compile_macroexpand_1_form(ctx, emit, symbols, args),
89
528
        "MACROEXPAND" => macros::compile_macroexpand_form(ctx, emit, symbols, args),
90
484
        "COMPILE" => compile_eval::compile_compile_form(ctx, emit, symbols, args),
91
440
        "EVAL" => compile_eval::compile_eval_form(ctx, emit, symbols, args),
92
220
        "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
14522
}
101

            
102
1160
pub(super) fn compile_for_effect(
103
1160
    ctx: &mut CompileContext,
104
1160
    emit: &mut FunctionEmitter,
105
1160
    symbols: &mut SymbolTable,
106
1160
    name: &str,
107
1160
    args: &[Expr],
108
1160
) -> Result<()> {
109
1160
    match name {
110
1160
        "DO" => iteration::compile_do_for_effect(ctx, emit, symbols, args),
111
1160
        "DO*" => iteration::compile_do_star_for_effect(ctx, emit, symbols, args),
112
1160
        "DOLIST" => iteration::compile_dolist_for_effect(ctx, emit, symbols, args),
113
402
        "LET" => binding::compile_let_for_effect(ctx, emit, symbols, args),
114
402
        "LET*" => binding::compile_let_star_for_effect(ctx, emit, symbols, args),
115
134
        "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
1160
}
121

            
122
3214
pub(super) fn compile_for_stack(
123
3214
    ctx: &mut CompileContext,
124
3214
    emit: &mut FunctionEmitter,
125
3214
    symbols: &mut SymbolTable,
126
3214
    name: &str,
127
3214
    args: &[Expr],
128
3214
) -> Result<WasmType> {
129
3214
    match name {
130
3214
        "IF" => control::compile_if_for_stack(ctx, emit, symbols, args),
131
3126
        "AND" => control::compile_and_for_stack(ctx, emit, symbols, args),
132
1920
        "OR" => control::compile_or_for_stack(ctx, emit, symbols, args),
133
1920
        "DO" => iteration::compile_do_for_stack(ctx, emit, symbols, args),
134
1072
        "DO*" => iteration::compile_do_star_for_stack(ctx, emit, symbols, args),
135
1072
        "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
3214
}