Lines
46.32 %
Functions
20 %
Branches
100 %
use super::super::context::CompileContext;
use super::super::emit::FunctionEmitter;
use super::super::expr::{compile_expr, compile_for_stack, eval_value, format_expr};
use crate::ast::{Expr, WasmType};
use crate::error::{Error, Result};
use crate::runtime::SymbolTable;
pub(super) fn upcase_string(symbols: &mut SymbolTable, args: &[Expr]) -> Result<Expr> {
if args.len() != 1 {
return Err(Error::Arity {
name: "UPCASE-STRING".to_string(),
expected: 1,
actual: args.len(),
});
}
let arg = eval_value(symbols, &args[0])?;
match arg {
Expr::String(s) => Ok(Expr::String(s.to_uppercase())),
other => Err(Error::Compile(format!(
"UPCASE-STRING: expected string, got {}",
format_expr(&other)
))),
pub(super) fn compile_upcase_string(
ctx: &mut CompileContext,
emit: &mut FunctionEmitter,
symbols: &mut SymbolTable,
args: &[Expr],
) -> Result<()> {
let result = upcase_string(symbols, args)?;
compile_expr(ctx, emit, symbols, &result)
pub(super) fn string_eq(symbols: &mut SymbolTable, args: &[Expr]) -> Result<Expr> {
if args.len() != 2 {
name: "STRING=".to_string(),
expected: 2,
let a = eval_value(symbols, &args[0])?;
let b = eval_value(symbols, &args[1])?;
// Constant fold if both are compile-time strings
if let (Expr::String(sa), Expr::String(sb)) = (&a, &b) {
return Ok(Expr::Bool(sa == sb));
Ok(Expr::WasmRuntime(WasmType::I32))
pub(super) fn compile_string_eq_to_stack(
) -> Result<WasmType> {
// Constant fold
emit.i32_const(i32::from(sa == sb));
return Ok(WasmType::I32);
// Compile both args to stack as StringRef
compile_string_arg_to_stack(ctx, emit, symbols, &args[0], &a)?;
compile_string_arg_to_stack(ctx, emit, symbols, &args[1], &b)?;
emit.call(ctx.func("string_eq"));
Ok(WasmType::I32)
fn compile_string_arg_to_stack(
arg: &Expr,
resolved: &Expr,
if let Expr::String(s) = resolved {
let data_idx = ctx.add_data(s.as_bytes());
emit.i32_const(0);
emit.i32_const(s.len() as i32);
emit.array_new_data(ctx.type_idx("i8_array"), data_idx);
} else {
let ty = compile_for_stack(ctx, emit, symbols, arg)?;
if ty != WasmType::StringRef {
return Err(Error::Compile(format!(
"STRING= arguments must be strings, got {ty}"
)));
Ok(())
pub(super) fn compile_string_eq(
let ty = compile_string_eq_to_stack(ctx, emit, symbols, args)?;
super::super::expr::serialize_stack_to_output(ctx, emit, ty);