modules/lang/lisp/eval.zzm

lang-lisp-0.0.3 documentation

Package

Name
lang-lisp
Version
0.0.3
Uploaded
2026-06-07 11:22:43
Repository
https://github.com/tobyink/zuzu-lang-lisp
Dependencies
Metadata
zuzu-distribution.json
Archive
Download .tar.gz

NAME

lang/lisp/eval - Evaluate Lisp/Scheme S-expressions.

SYNOPSIS

  from lang/lisp/eval import lisp_eval, lisp_eval_all, standard_env;
  from lang/lisp/parser import parse_sexpr, sym;

  let env := standard_env();
  say( lisp_eval( parse_sexpr("(+ 1 2 3)"), env ) );  // 6
  say( lisp_eval( [ sym("+"), 1, 2, 3 ], env ) );      // 6

  env.define_callback( "raw", function ( call ) {
      return call[1].get_name();
  } );
  say( lisp_eval( parse_sexpr("(raw unevaluated)"), env ) );

DESCRIPTION

This module evaluates the S-expression values produced by lang/lisp/parser, or equivalent nested Zuzu arrays built by callers. Symbols must be LispSymbol objects, normally constructed with sym(name).

The evaluator implements a small Scheme-style language with lexical environments, first-class closures, host callbacks, a practical syntax-rules macro subset, quasiquote, and trampoline-based tail evaluation. standard_env() loads a Lisp-source prelude; core_env() returns only native core primitives.

Arguments to ordinary procedures are evaluated before dispatch. Raw callbacks receive the raw call list before operand evaluation; procedure callbacks receive evaluated operands.

LANGUAGE SUPPORT

The following special forms are supported:

  • quote, quasiquote, unquote, and unquote-splicing;
  • if, begin, cond, and, and or;
  • define, function-style define, and set!;
  • lambda;
  • let, named let, let*, letrec, and do;
  • guard and error;
  • case, delay, and force;
  • define-library, import, and include;
  • define-syntax with a syntax-rules subset.

The standard environment includes:

  • arithmetic and numeric predicates:

    +, -, *, /, =, <, >, <=, >=, zero?, positive?, negative?, even?, odd?, modulo, abs, min, and max;

  • equality and predicates:

    eq?, equal?, not, null?, pair?, list?, vector?, symbol?, number?, string?, boolean?, and procedure?;

  • list and higher-order helpers:

    list, cons, car, cdr, length, append, apply, map, for-each, filter, fold-left, and fold-right;

  • vector helpers:

    vector, vector-length, vector-ref, vector-set!, list-vector>, and vector-list>;

  • symbol and string helpers:

    symbol-string>, string-symbol>, string-append, string-length, substring, and string=?;

  • association and membership helpers:

    assoc, assq, member, and memq;

  • file loading and errors:

    load and error.

  • characters, bytevectors, hash tables, paths, regexps, and

    Scheme-style file ports.

CALLBACKS

LispEnv.define_callback(name, callback) binds a Zuzu callback into the environment. When Lisp code calls the name, the callback receives the raw call S-expression array, including the operator symbol. Arguments are not evaluated before callback dispatch.

  let env := standard_env();
  env.define_callback( "foo", function ( call ) {
      return call.length();
  } );

  lisp_eval( parse_sexpr("(foo 1 2 3)"), env );  // 4

The callback receives a list like:

  [ sym("foo"), 1, 2, 3 ]

This makes callbacks suitable for host integrations, custom special-form behaviour, or controlled inspection of unevaluated Lisp input.

LispEnv.define_proc_callback(name, callback) is for ordinary procedure-like host functions. Lisp evaluates operands first, then calls the callback with an Array of argument values.

LispEnv.define_env_callback(name, callback) is like define_callback, but calls the Zuzu function with both the raw call list and the current LispEnv.

LOADING

load_lisp(target, env?) and the Lisp load builtin parse and evaluate Lisp files. Relative nested loads are resolved from the currently loading file. LispEnv.add_load_path(path) adds extra search directories for load.

If a relative string target ending .lizp is not found on the filesystem, load also tries an installable Zuzu wrapper module under lang/lisp/module. For example, (load "helper.lizp") tries to import LISP_SOURCE from lang/lisp/module/helper. Wrapper modules are intended for packaged Lisp libraries that need to survive zuzuzoo installation.

LIBRARIES

define-library and import provide a small R7RS-shaped library system. Library names such as (scheme base) resolve to scheme/base inside configured Lisp library paths, then to wrapper modules such as lang/lisp/module/scheme/base. Import modifiers only, except, prefix, and rename are supported.

DIAGNOSTICS

Runtime failures are reported as LispRuntimeError values with source locations and Lisp stack frames where available. Use lisp_error_report(error) to format a human-readable report.

EXPORTS

Functions

  • standard_env()

    Returns a new LispEnv populated with core builtins and the Lisp prelude. Each call returns a separate environment.

  • core_env()

    Returns a new LispEnv populated with native core primitives only.

  • lisp_eval(expr, env?)

    Evaluates one S-expression. expr may be parsed source output or a direct nested-array expression. If env is omitted, a new standard environment is used.

  • lisp_eval_all(Array exprs, env?)

    Evaluates expressions from left to right and returns the final result. This is useful with parse_sexprs when source text contains definitions followed by an expression.

  • load_lisp(target, env?)

    Loads, parses, and evaluates a Lisp file. target may be a String or std/io Path. If env is omitted, a new standard environment is used. Throws when the file cannot be resolved or when a recursive load is detected.

  • load_library(name, env?)

    Loads and returns a LispLibrary.

  • import_library(spec, env?)

    Imports a library or import modifier expression into env.

  • expand(expr, env?)

    Expands macro calls visible in env and returns the expanded S-expression. Non-list values are returned unchanged.

  • lisp_repr(value)

    Formats a Lisp value as Lisp-readable text for display. It recognises symbols, strings, booleans, lists, dotted pairs, and vectors.

  • lisp_error_message(error)

    Formats the main diagnostic message for a Lisp error.

  • lisp_error_report(error)

    Formats the main diagnostic plus Lisp stack frames.

Classes

  • LispEnv

    Lexical environment for evaluation.

    • env.define(LispSymbol name, value)

      Binds value to name in the current environment and returns the value.

    • env.define_name(String name, value)

      Binds value to a plain string name in the current environment and returns the value.

    • env.define_callback(String name, Function callback)

      Binds a raw host callback and returns the created LispCallback.

    • env.define_proc_callback(String name, Function callback)

      Binds a procedure callback that receives evaluated argument values.

    • env.define_env_callback(String name, Function callback)

      Binds a raw callback that also receives the current LispEnv.

    • env.get(LispSymbol name)

      Looks up name through the lexical parent chain. Throws if it is unbound.

    • env.set_value(LispSymbol name, value)

      Updates an existing binding through the lexical parent chain. Throws if name is unbound.

    • env.get_bindings()

      Returns the current frame's binding dictionary.

    • env.base_dir(value?)

      Gets or sets the base directory used while resolving nested load calls.

    • env.base_module(value?)

      Gets or sets the wrapper module prefix used while resolving nested load calls from packaged Lisp source.

    • env.load_stack()

      Returns the load stack used for recursive-load detection.

    • env.load_paths()

      Returns the mutable array of configured load paths.

    • env.add_load_path(path)

      Adds a String or Path load path and returns env.

  • LispCallback

    Host callback wrapper created by the callback definition methods.

    • callback.get_name()

      Returns the callback binding name.

    • callback.get_callback()

      Returns the wrapped Zuzu function.

    • callback.get_kind()

      Returns raw, proc, or env.

    • callback.call_raw(Array expr, env)

      Calls a raw or environment callback with the raw S-expression call list.

    • callback.call_args(Array args)

      Calls a procedure callback with evaluated argument values.

  • LispClosure

    Callable Lisp closure created by lambda or function-style define. It retains its parameter list, body, and lexical environment. Methods params(), body(), and env() return those values.

  • LispMacro

    Macro object created by define-syntax. The supported syntax-rules subset recognises literal identifiers, _ wildcard patterns, and ... repetition in list patterns and templates.

    Methods name(), set_name(value), literals(), and rules() expose the macro metadata.

  • LispLibrary, LispStackFrame, LispPromise

    Library, diagnostic stack-frame, and delayed-expression values.

  • LispHashTable, LispPath, LispRegexp

    Host-backed data wrappers exposed to Lisp code.

  • LispInputPort, LispOutputPort

    Scheme-style text input and output ports.

  • LispInterpreter

    Small stateful wrapper around an environment.

    • interpreter.get_env()

      Returns the interpreter environment.

    • interpreter.eval(expr)

      Evaluates one already-parsed or direct S-expression in the interpreter environment.

    • interpreter.eval_string(String source)

      Parses one S-expression from source and evaluates it in the interpreter environment.

LIMITATIONS

The macro system is a useful syntax-rules subset, not a complete Scheme standard implementation. It does not provide full hygiene, syntax-case, phase separation, or a complete report-level library system.

COPYRIGHT AND LICENCE

lang/lisp/eval is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under the terms of either the Artistic License 1.0 or the GNU General Public License version 2.