Logos (Logos v0.2.0)

Copy Markdown

Top-level end-to-end API: text --[Reader]--> Logos.Form.t() --[Macroexpand]--> Logos.Form.t() --[Eval]--> value.

Logos.Runtime owns namespaces and Vars: def interns into the current namespace of a Logos.Runtime, not a bare global table. Logos.Env is threaded alongside it purely as lexical scope (let/fn params) and carries no top-level def visibility at all -- that visibility comes entirely from runtime.

new_runtime/1 is a one-call convenience: a fresh Logos.Runtime.new/1 with Logos.Stdlib.load!/1 (real priv/stdlib/*.logos dogfooding) already applied, ready to eval_string against.

Summary

Functions

Reads exactly one top-level form from source, macroexpands it, and evaluates it against runtime (a fresh new_runtime/0 if omitted) and lexical env (a fresh empty Logos.Env if omitted). Returns {:ok, value, env} on success -- env is returned so callers can thread it into a subsequent eval_string/3 call for lexical continuity (e.g. a REPL that wants top-level let-like behavior); ordinary def visibility across calls comes from runtime, not env.

Reads every top-level form from source and evaluates them in order against runtime (a fresh new_runtime/0 if omitted), threading env forward from one form to the next. Returns {:ok, last_value, env}, or the first {:error, _} encountered (later forms are not evaluated once one fails).

A fresh Logos.Runtime, bootstrapped with the Elixir-implemented primitives and priv/stdlib/*.logos (the Lisp-level standard library built on top of those primitives) already loaded into logos.core, starting in namespace user.

Functions

eval_string(source, runtime \\ nil, env \\ Env.new())

@spec eval_string(String.t(), Logos.Runtime.t() | nil, Logos.Env.t()) ::
  {:ok, term(), Logos.Env.t()} | {:error, term()}

Reads exactly one top-level form from source, macroexpands it, and evaluates it against runtime (a fresh new_runtime/0 if omitted) and lexical env (a fresh empty Logos.Env if omitted). Returns {:ok, value, env} on success -- env is returned so callers can thread it into a subsequent eval_string/3 call for lexical continuity (e.g. a REPL that wants top-level let-like behavior); ordinary def visibility across calls comes from runtime, not env.

eval_string_sequence(source, runtime \\ nil, env \\ Env.new())

@spec eval_string_sequence(String.t(), Logos.Runtime.t() | nil, Logos.Env.t()) ::
  {:ok, term(), Logos.Env.t()} | {:error, term()}

Reads every top-level form from source and evaluates them in order against runtime (a fresh new_runtime/0 if omitted), threading env forward from one form to the next. Returns {:ok, last_value, env}, or the first {:error, _} encountered (later forms are not evaluated once one fails).

new_runtime(opts \\ [])

@spec new_runtime(keyword()) :: Logos.Runtime.t()

A fresh Logos.Runtime, bootstrapped with the Elixir-implemented primitives and priv/stdlib/*.logos (the Lisp-level standard library built on top of those primitives) already loaded into logos.core, starting in namespace user.