Lines
88.46 %
Functions
32 %
Branches
100 %
//! `APROPOS` — search the symbol table for names containing a
//! substring (case-insensitive), return a sorted quoted list of
//! matching symbols. Powers `nomisync-help` completion in emacs and
//! the REPL's tab-completion.
use crate::ast::{Expr, WasmType};
use crate::compiler::context::CompileContext;
use crate::compiler::emit::FunctionEmitter;
use crate::compiler::expr::{compile_expr, format_expr};
use crate::error::{Error, Result};
use crate::runtime::SymbolTable;
use super::compile_static_result_for_stack;
pub(super) fn apropos(symbols: &mut SymbolTable, args: &[Expr]) -> Result<Expr> {
if args.len() != 1 {
return Err(Error::Arity {
name: "APROPOS".to_string(),
expected: 1,
actual: args.len(),
});
}
let needle = match &args[0] {
Expr::String(s) => s.clone(),
Expr::Quote(inner) => match inner.as_ref() {
Expr::Symbol(s) => s.clone(),
other => {
return Err(Error::Compile(format!(
"APROPOS: argument must be a string, got quoted {}",
format_expr(other)
)));
},
"APROPOS: argument must be a string, got {}",
};
let needle_uc = needle.to_uppercase();
let mut matches: Vec<String> = symbols
.iter()
.filter(|(name, _)| name.to_uppercase().contains(&needle_uc))
.map(|(name, _)| name.clone())
.collect();
matches.sort();
let elems = matches.into_iter().map(Expr::Symbol).collect();
Ok(Expr::Quote(Box::new(Expr::List(elems))))
pub(super) fn compile_apropos(
ctx: &mut CompileContext,
emit: &mut FunctionEmitter,
symbols: &mut SymbolTable,
args: &[Expr],
) -> Result<()> {
let result = apropos(symbols, args)?;
compile_expr(ctx, emit, symbols, &result)
pub(super) fn compile_apropos_for_stack(
) -> Result<WasmType> {
compile_static_result_for_stack(ctx, emit, symbols, &result)