Lines
84.82 %
Functions
45 %
Branches
100 %
mod binding;
mod compile_eval;
mod control;
mod iteration;
mod labels;
mod lambda;
mod macros;
mod structure;
use tracing::debug;
use crate::ast::Expr;
use crate::error::{Error, Result};
use crate::runtime::SymbolTable;
use crate::ast::WasmType;
use super::context::CompileContext;
use super::emit::FunctionEmitter;
pub(in crate::compiler) use control::is_truthy;
pub(in crate::compiler) use structure::set_place as setf_set_place;
pub fn call(symbols: &mut SymbolTable, name: &str, args: &[Expr]) -> Result<Expr> {
debug!(special_form = %name, args = args.len(), "calling special form");
match name {
"QUOTE" => control::quote(args),
"DEFUN" => binding::defun(symbols, args),
"LAMBDA" => lambda::lambda(args),
"FUNCTION" => lambda::function_form(symbols, args),
"DEFVAR" => binding::defvar(symbols, args),
"DEFPARAMETER" => binding::defparameter(symbols, args),
"DESCRIBE" => compile_eval::describe(symbols, args),
"FUNCALL" => lambda::funcall(symbols, args),
"APPLY" => lambda::apply(symbols, args),
"BEGIN" => control::begin_form(symbols, args),
"AND" => control::and_form(symbols, args),
"OR" => control::or_form(symbols, args),
"IF" => control::if_form(symbols, args),
"COND" => control::cond_form(symbols, args),
"LET" => binding::let_form(symbols, args),
"LET*" => binding::let_star(symbols, args),
"DO" => iteration::do_form(symbols, args),
"DO*" => iteration::do_star_form(symbols, args),
"DEFMACRO" => macros::defmacro(symbols, args),
"MACROEXPAND-1" => macros::macroexpand_1(symbols, args),
"MACROEXPAND" => macros::macroexpand(symbols, args),
"COMPILE" => compile_eval::compile_form(symbols, args),
"EVAL" => compile_eval::eval_form(symbols, args),
"LABELS" => labels::labels_form(symbols, args),
"DOLIST" => iteration::dolist_form(symbols, args),
"DEFSTRUCT" => structure::defstruct(symbols, args),
"SETF" => structure::setf(symbols, args),
_ => Err(Error::Compile(format!(
"special form '{name}' not yet implemented"
))),
}
pub(super) fn compile(
ctx: &mut CompileContext,
emit: &mut FunctionEmitter,
symbols: &mut SymbolTable,
name: &str,
args: &[Expr],
) -> Result<()> {
debug!(special_form = %name, args = args.len(), "compiling special form");
"QUOTE" => control::compile_quote(ctx, emit, args),
"DEFUN" => binding::compile_defun(ctx, emit, symbols, args),
"LAMBDA" => lambda::compile_lambda_form(ctx, emit, args),
"FUNCTION" => lambda::compile_function_form(ctx, emit, symbols, args),
"DEFVAR" => binding::compile_defvar(ctx, emit, symbols, args),
"DEFPARAMETER" => binding::compile_defparam(ctx, emit, symbols, args),
"DESCRIBE" => compile_eval::compile_describe(ctx, emit, symbols, args),
"FUNCALL" => lambda::compile_funcall(ctx, emit, symbols, args),
"APPLY" => lambda::compile_apply_form(ctx, emit, symbols, args),
"BEGIN" => control::compile_begin(ctx, emit, symbols, args),
"AND" => control::compile_and(ctx, emit, symbols, args),
"OR" => control::compile_or(ctx, emit, symbols, args),
"IF" => control::compile_if(ctx, emit, symbols, args),
"COND" => control::compile_cond(ctx, emit, symbols, args),
"LET" => binding::compile_let(ctx, emit, symbols, args),
"LET*" => binding::compile_let_star(ctx, emit, symbols, args),
"DO" => iteration::compile_do(ctx, emit, symbols, args),
"DO*" => iteration::compile_do_star(ctx, emit, symbols, args),
"DEFMACRO" => macros::compile_defmacro_form(ctx, emit, symbols, args),
"MACROEXPAND-1" => macros::compile_macroexpand_1_form(ctx, emit, symbols, args),
"MACROEXPAND" => macros::compile_macroexpand_form(ctx, emit, symbols, args),
"COMPILE" => compile_eval::compile_compile_form(ctx, emit, symbols, args),
"EVAL" => compile_eval::compile_eval_form(ctx, emit, symbols, args),
"LABELS" => labels::compile_labels(ctx, emit, symbols, args),
"DOLIST" => iteration::compile_dolist(ctx, emit, symbols, args),
"DEFSTRUCT" => structure::compile_defstruct(ctx, emit, symbols, args),
"SETF" => structure::compile_setf(ctx, emit, symbols, args),
pub(super) fn compile_for_effect(
"DO" => iteration::compile_do_for_effect(ctx, emit, symbols, args),
"DO*" => iteration::compile_do_star_for_effect(ctx, emit, symbols, args),
"DOLIST" => iteration::compile_dolist_for_effect(ctx, emit, symbols, args),
"LET" => binding::compile_let_for_effect(ctx, emit, symbols, args),
"LET*" => binding::compile_let_star_for_effect(ctx, emit, symbols, args),
"COND" => control::compile_cond_for_effect(ctx, emit, symbols, args),
"AND" => control::compile_and_for_effect(ctx, emit, symbols, args),
"OR" => control::compile_or_for_effect(ctx, emit, symbols, args),
_ => compile(ctx, emit, symbols, name, args),
pub(super) fn compile_for_stack(
) -> Result<WasmType> {
"IF" => control::compile_if_for_stack(ctx, emit, symbols, args),
"AND" => control::compile_and_for_stack(ctx, emit, symbols, args),
"OR" => control::compile_or_for_stack(ctx, emit, symbols, args),
"DO" => iteration::compile_do_for_stack(ctx, emit, symbols, args),
"DO*" => iteration::compile_do_star_for_stack(ctx, emit, symbols, args),
"LET" => binding::compile_let_for_stack(ctx, emit, symbols, args),
"LET*" => binding::compile_let_star_for_stack(ctx, emit, symbols, args),
"BEGIN" => control::compile_begin_for_stack(ctx, emit, symbols, args),
"special form '{name}' cannot produce stack value"