CMInterpreter
Creates an interpreter without scopes. initScopes() or the first lookup creates the top-level scope.
Languages
An extensible interpreter for Microcosm expression and statement nodes.
#include <mc/CMInterpreter.h>The template argument supplies the concrete interpreter used for dispatch. run() evaluates an AST; the named node methods implement that AST’s operations.
Node handlers generally receive expressions and evaluate their operands with run(). The c-prefixed utility handlers and math helpers accept evaluated values; their output parameters may still be mutable cvar references.
template<class I> class CMInterpreter : public CExecutorCreates an interpreter without scopes. initScopes() or the first lookup creates the top-level scope.
virtual ~CMInterpreter();
Reports an unclean shutdown if scopes remain. Call shutdown() explicitly before destruction; the destructor does not perform that cleanup.
void initScopes();
Creates the top-level scope if none exists. Repeated calls preserve existing bindings.
void shutdown();
Releases the top-level scope and clears the scope stack. Finish active calls and scope guards first, and stop using objects, lambdas, or references that depend on this interpreter.
Evaluates an expression in the current scopes. Symbols resolve to reference-valued cvar objects, functions dispatch to the concrete interpreter, and ordinary values are copied; an unbound symbol throws CError.
Resolves symbols and follows references without executing function expressions. The returned reference borrows either an existing binding or the supplied value.
Looks up a symbol using the current scope boundaries, returning a borrowed pointer or nullptr when absent. The pointer remains valid only while its binding remains alive.
Evaluates the operand and applies cvar logical negation. None propagates as None, objects dispatch Not, and unsupported types throw CError.
Evaluates the operand and applies dynamic numeric negation. Unsupported value types throw CError.
Evaluates both operands and applies cvar addition, including the supported numeric, string, and container cases.
Evaluates both operands and applies cvar subtraction. The operand types determine which operation is supported.
Evaluates both operands and applies cvar multiplication, including supported vector arithmetic.
Evaluates both operands and uses cvar::Div() for checked division, including None propagation and a zero-divisor check.
Evaluates both operands and applies dynamic remainder; unsupported types throw CError.
Evaluates both operands and tests whether the left is less than the right. Uses the corresponding cvar comparison method, preserving its None propagation.
Evaluates both operands and tests whether the left is greater than the right. Uses the corresponding cvar comparison method, preserving its None propagation.
Evaluates both operands and tests whether the left is less than or equal to the right. Uses the corresponding cvar comparison method, preserving its None propagation.
Evaluates both operands and tests whether the left is greater than or equal to the right. Uses the corresponding cvar comparison method, preserving its None propagation.
Evaluates both operands and tests whether the left is unequal the right. Uses the corresponding cvar comparison method, preserving its None propagation.
Evaluates both operands and tests whether the left is equal the right. Uses the corresponding cvar comparison method, preserving its None propagation.
Evaluates the left operand first and evaluates the right only if the left is false. Returns the logical result as a cvar boolean.
Evaluates the left operand first and evaluates the right only if the left is true. Returns the logical result as a cvar boolean.
Evaluates the base and exponent and computes dynamic exponentiation.
Evaluates both sides and assigns through the left reference, copying the dereferenced right value. Use VarSet() to introduce a binding in the current scope.
Evaluates both operands and applies addition to the left target in place. A reference-valued left operand updates the original binding.
Evaluates both operands and applies subtraction to the left target in place. A reference-valued left operand updates the original binding.
Evaluates both operands and applies multiplication to the left target in place. A reference-valued left operand updates the original binding.
Evaluates both operands and applies remainder to the left target in place. A reference-valued left operand updates the original binding.
Evaluates both operands and applies division to the left target in place. A reference-valued left operand updates the original binding. Uses checked DivBy() division.
Evaluates and increments the target, returning the updated value. A symbol target is updated through its resolved reference.
Evaluates and decrements the target, returning the updated value. A symbol target is updated through its resolved reference.
Evaluates and increments the target, returning its value before the change.
Evaluates and decrements the target, returning its value before the change.
Evaluates the initializer and installs its dereferenced value under the symbol in the current scope. An existing binding in that scope is replaced.
Runs a declaration template once for each symbol, substituting that symbol into the first argument. The template must contain that argument slot.
cvar Block(const cargs& v);
Evaluates nodes in order and returns the last result, or None for an empty block. Scope creation is handled by the enclosing operation.
void Print(const cvar& x);
Evaluates a value and prints it with a newline. Function expressions use CSON formatting; other values use toStr().
void Output(const cvar& x);
Evaluates a value and writes its string form without a trailing newline.
void Assert(const cvar& x);
Evaluates the condition and throws CError when its truth value is false.
void Break();
Raises the interpreter’s break signal for an enclosing loop. It is a control-flow handler, not a standalone loop-management call.
void Continue();
Raises the interpreter’s continue signal so an enclosing loop advances to its next iteration.
void Ret();
void Ret(const cvar& v);
Returns from an interpreted function by raising its internal return signal. The value overload evaluates and dereferences its operand; the empty overload returns None.
void For(const cvar& count, const cvar& body);
void For(const cvar& init, const cvar& cond, const cvar& step, const cvar& body);
Runs a loop in a statement scope. The count overload iterates [0,n), using a numeric count or a collection’s size and binding __ to the index; the other overload evaluates initialization once, tests before each iteration, and runs the step after the body, including after Continue().
void Forever(const cvar& body);
Repeats the body in a statement scope until Break() or another escaping control signal or error ends the loop.
Runs the first body in a statement scope and, on CError, runs the catch body in a fresh scope. Loop and return signals are not caught as errors.
void Pass();
Performs no operation; this is the handler for an empty statement.
void Comment(const cvar&);
Accepts a preserved block-comment node without executing its contents.
void LineComment(const cvar&);
Accepts a preserved line-comment node without executing its contents.
Evaluates a vector or map and runs the body in a statement scope for each entry. Vectors bind a copy of the element; maps bind an iterator used by Key() and Val(). Sets are not supported by this handler.
const cstr& Key();
Borrows the current map-iteration key from the iterator bound to __. Use only inside the corresponding map loop.
cvar Val();
Returns a reference-valued cvar for the current map-iteration value. The reference depends on the loop’s map and iterator remaining valid.
Tests the condition before each iteration and runs the body in a statement scope. Handles the interpreter’s break and continue signals.
void If(const cvar& cond, const cvar& body);
void If(const cvar& cond, const cvar& body, const cvar& elseBody);
Evaluates the condition, then runs only the selected body in a statement scope. The two-argument form does nothing when the condition is false.
Evaluates the condition and returns only the selected expression’s result. The false branch defaults to None.
Converts the evaluated selector to its string form and looks it up in the cases map. Runs that case, or the default, in a statement scope without fallthrough.
Evaluates the receiver and tests for a map key named by the supplied symbol. The key symbol itself is not looked up as a variable.
Evaluates the receiver and index, then selects a vector/function position or a map key. A reference-valued receiver yields a reference to the element; a temporary receiver yields a copy.
Selects an evaluated receiver’s element for assignment, inserting a missing map key. Numeric indices must identify an existing position; reference results require a reference-valued receiver.
Looks up an evaluated map key, requiring it to exist. Returns an element reference when the receiver is a reference, otherwise a copy.
Evaluates both operands, appends the item through the receiver’s cvar interface, and returns the receiver.
Evaluates both operands. For vectors and sets, inserts the right value into the left collection; for integers, performs a bit shift.
Dispatches a named interpreted function, evaluating arguments as required by the call. Native class construction initializes the built-in factories automatically. The receiver overload dispatches built-in value methods or an object’s method handler.
Dispatches a zero-argument method on the evaluated receiver using the symbol as its method name.
Evaluates a callable expression and each argument, then invokes the resulting wrapped lambda.
Builds a vector, map, or set by evaluating its elements or values and storing dereferenced results. Other inputs are evaluated and dereferenced directly.
Creates a class prototype, runs its body in an object scope, and binds it under the class name. The prototype receives default superclass and destructor bindings.
Registers a constructor’s signature, flags, and body in the class scope and makes construction available to the enclosing scope.
Object* New(const cfunc& f);
Copies a registered class prototype, evaluates constructor arguments, and invokes its constructor. Returns an instance pointer intended for ownership by a cvar object value.
Registers the interpreted destructor body for the current class.
Registers a function signature, flags, and body in the current scope. Later calls resolve it by the function’s dispatch hash.
Evaluates the operand and moves out of its dereferenced value. A reference to a variable therefore consumes that variable’s current contents.
Evaluates the operand and applies cvar::Star() dereferencing behavior, including the value’s reference flag.
Evaluates the operand and sets its reference flag so subsequent dereferencing preserves the reference when required by the interpreter.
Returns a reference to a named map field, creating a missing field. The symbol supplies a literal field name rather than a variable lookup.
Reads a named map field; the required-field overload throws if it is absent. The fallback overload evaluates its default argument before lookup, even when the field exists.
Returns the function expression as data without executing it.
Returns the symbol as data without resolving a variable binding.
void Error(const cvar& msg);
Evaluates the message and raises CError with that value as its message.
Creates a wrapped callable for a parsed lambda with up to 15 parameters. Calls enter a statement scope and handle interpreted returns; keep the originating interpreter alive while the lambda can be invoked.
void NP(const cvar& n);
Evaluates an expression and prints its source line, expression, and result for tracing.
Finds the active interpreted object or throws CError outside an object context. The symbol overload returns a reference to that object’s named binding and requires it to exist.
Evaluates the object and value, then dispatches an Apply call to the object.
void PrivateModule(const cstr& module);
Sets the current module name with the private-module suffix. This records the module context; it does not load a file.
void Module(const cstr& module);
Sets the current module context without loading or executing a module.
void Import(const cstr& module);
Initializes the built-in factories, constructs a module, executes its top-level entry, and binds the resulting object. Unknown modules throw CError; custom modules must have a registered factory. The object is released if its entry throws.
Formats the supplied value as a string through the framework’s stream formatter. It does not evaluate a symbol or function expression.
double cNow();
Returns Unix wall-clock seconds.
cstr cHost();
Returns the initial alphanumeric part of the hostname. Use cHostName() for the full hostname.
Returns the process environment variable’s value, or an empty string when it is absent.
Sets a variable in the process environment. With redefine=false, an existing value is retained; changes do not update the parent shell.
bool cExists(const cstr& path);
Tests whether the path resolves to an existing filesystem object. Follows symbolic links, so a dangling link reports false.
bool cIsDir(const cstr& path);
Tests whether the path resolves to a directory, following symbolic links.
bool cIsFile(const cstr& path);
Tests whether the path resolves to a regular file, following symbolic links.
cstr cCurrentDir();
Returns the process’s current working directory.
Returns the names of all immediate directory entries, including hidden entries and subdirectories. Results are not sorted.
void cSleep(double dt);
Blocks the current thread for the requested number of seconds. Scheduling can delay wakeup beyond that interval.
Reads the complete file into a string, preserving its bytes and line endings. Throws CError when the file cannot be opened or read.
void cCreateDir(const cstr& path);
Creates one directory and throws if creation fails, including when it already exists. cCreateDirs() creates missing parents and tolerates existing directories.
Renames or moves a filesystem entry using the platform’s rename semantics. Cross-filesystem moves can fail; this is not a copy-and-delete operation.
Joins the input elements with the requested separator.
bool cIsLower(const cstr& c);
Tests the first byte of a nonempty string for a lowercase letter using C character classification. This is byte-oriented rather than Unicode-aware.
bool cIsUpper(const cstr& c);
Tests the first byte of a nonempty string for a uppercase letter using C character classification. This is byte-oriented rather than Unicode-aware.
bool cIsDigit(const cstr& c);
Tests the first byte of a nonempty string for a digit using C character classification. This is byte-oriented rather than Unicode-aware.
bool cIsAlpha(const cstr& c);
Tests the first byte of a nonempty string for a letter using C character classification. This is byte-oriented rather than Unicode-aware.
bool cIsAlphaNum(const cstr& c);
Tests the first byte of a nonempty string for a letter or digit using C character classification. This is byte-oriented rather than Unicode-aware.
bool cIsSymbol(const cstr& s);
Tests whether the complete string is a valid Catalyst symbol spelling. It does not resolve the symbol or look up a variable.
cstr cConcise(double n, int p);
Formats a number in fixed notation with p digits after the decimal point. Trailing zeros are retained.
void cExit(int status);
Convenience wrapper for CProgram::exit(). Runs coordinated resource shutdown and registered exit callbacks, then terminates with the supplied status. This function does not return.
void cOption(const cstr& names, const cvar& def, const cstr& description = "", bool required = false, bool multi = false);
Convenience wrapper for CProgram::option(). Registers option aliases separated by :. The default determines value conversion; required and multi control validation and repeated values.
void cSetUsage(const cstr& usage);
Convenience wrapper for CProgram::setUsage(). Sets the introductory usage text. usage() appends the registered option descriptions and defaults.
cstr cUsage();
Convenience wrapper for CProgram::usage(). Builds usage text from the program name, custom introduction, and registered options. It returns text rather than printing or exiting.
const cstr& cHome();
Convenience wrapper for CProgram::home(). Returns the resolved framework home directory after initialization, including any MC_HOME selection.
size_t cThreads();
Convenience wrapper for CProgram::threads(). Returns the process-wide worker-count default derived from the available hardware, with at least one thread.
const cvar& cArgs();
Convenience wrapper for CProgram::args(). Returns the resolved, process-wide argument/configuration value. The reference is borrowed; coordinate access with reconfiguration, which replaces its contents.
void cReconfigure();
Convenience wrapper for CProgram::configure(). Loads and resolves the program configuration using the current process-wide arguments.
Sorts the referenced vector in place. Without a comparator it uses cvar ordering; the comparator overload evaluates and unwraps a two-argument lambda.
Computes Euclidean distance from corresponding numeric elements. Supply vectors of compatible lengths.
Returns a below the lower bound, b above the upper bound, or x within the inclusive interval. Supply ordered, compatible bounds.
Loads CSV text from a file and returns parsed rows. Writes the header vector through the supplied cvar output reference.
cvar cGridSize();
Throws CError: GPU grid size is unavailable during interpreted execution.
Converts a numeric value to a floating-point cvar using f8().
Updates the referenced four-component quaternion using three rotation angles in radians. Computation uses the float4 quaternion helper.
Formats the supplied value as JSON through CJSONGenerator; values outside its supported JSON representations throw.
Returns the numeric absolute value through the framework’s cvar helper.
Computes e raised to the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the natural logarithm of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the base-10 logarithm of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the square root of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes sine for an angle in radians. Converts the input to double and returns the result as a floating-point cvar.
Computes cosine for an angle in radians. Converts the input to double and returns the result as a floating-point cvar.
Computes tangent for an angle in radians. Converts the input to double and returns the result as a floating-point cvar.
Computes inverse sine, returning an angle in radians. Converts the input to double and returns the result as a floating-point cvar.
Computes inverse cosine, returning an angle in radians. Converts the input to double and returns the result as a floating-point cvar.
Computes the hyperbolic sine of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the hyperbolic cosine of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the hyperbolic tangent of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the inverse hyperbolic sine of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the inverse hyperbolic cosine of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Computes the inverse hyperbolic tangent of the numeric argument. Converts the input to double and returns the result as a floating-point cvar.
Rounds toward positive infinity. Converts the input to double and returns the result as a floating-point cvar.
Rounds toward negative infinity. Converts the input to double and returns the result as a floating-point cvar.
Rounds to the nearest integer value, with halfway cases rounded away from zero. Converts the input to double and returns the result as a floating-point cvar.
Returns the larger numeric value after converting the right operand to the left operand’s numeric type. An integer left operand therefore converts a floating right operand to an integer.
Returns the smaller numeric value after converting the right operand to the left operand’s numeric type. An integer left operand therefore converts a floating right operand to an integer.
Writes the one-based day-of-year and weekday through the supplied value references. Sunday is 1 and Saturday is 7.
Converts a one-based day-of-year into month and day, writing through the output references. Accounts for leap years and rejects invalid day numbers.
uint64_t cMakeTime(int64_t year, int month = 1, int day = 1, int hour = 0, int min = 0, int sec = 0);
Constructs seconds on the cosmic calendar timeline.
void cUnmakeTime(uint64_t t, const cvar& year, const cvar& month, const cvar& day, const cvar& hour, const cvar& min, const cvar& sec);
Splits cosmic seconds into calendar fields, writing each field through its supplied value reference.
double cEpochMake(int year, int month = 1, int day = 1, int hour = 0, int min = 0, double seconds = 0.0);
Constructs a Unix timestamp in seconds from local calendar fields.
uint64_t cMakeNano(uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t min, uint32_t sec, uint64_t nsec = 0);
Constructs Unix nanoseconds from local calendar fields and a nanosecond fraction.
void cEpochUnmake(double t, const cvar& year, const cvar& month, const cvar& day, const cvar& hour, const cvar& min, const cvar& sec);
void cEpochUnmake(double t, const cvar& year, const cvar& month, const cvar& day, const cvar& dayOfWeek, const cvar& hour, const cvar& min, const cvar& sec);
Splits Unix seconds into local calendar fields, writing through the supplied value references. Fractional seconds are discarded; the extended overload also writes the weekday.
Formats Unix seconds in the local time zone.
Formats the current wall-clock time in the local time zone. The default format includes the date, hour, and minute.
Parses local calendar text and returns Unix nanoseconds.
Performs an HTTP request in JSON mode, using the argument head as the URL and an optional headers vector. Returns the parsed response.
Posts the required body in JSON mode to the URL stored in the argument head. Optional headers and fields supply additional request configuration; returns the parsed response.
struct Scopestatic constexpr uint8_t Limiting = 0b01;
static constexpr uint8_t Stable = 0b10;
static constexpr uint8_t Top = (1 << 2) | Stable;
static constexpr uint8_t Func = (2 << 2) | Limiting;
static constexpr uint8_t Stmt = 3 << 2;
static constexpr uint8_t Obj = (4 << 2) | Stable;
ScopeMap m;
uint8_t type;
int stableIndex;
Scope(const Scope& s);
Scope(uint8_t type);
Creates an empty scope of the given type. Copy construction copies bindings after dereferencing their values, together with the scope type and stable lookup boundary.
virtual ~Scope();
void clear();
Removes all bindings from this scope. References to those bindings become invalid.
void dump();
Prints the stored values to standard output for diagnostic inspection; hash-map order is unspecified.
bool limiting();
Reports whether lookup skips intervening scopes and resumes at this scope’s stable boundary. Function scopes use this to avoid resolving unrelated caller locals.
class StmtScopeStmtScope(CMInterpreter* i);
Pushes a statement scope on the supplied interpreter for the lifetime of this guard. The interpreter must outlive the guard.
~StmtScope();
Pops the statement scope unless pop() has already removed it.
Scope& scope();
Borrows the statement scope held by this guard, allowing local bindings to be installed.
void pop();
Removes the scope early and disables the destructor’s pop. Call at most once, while this guard’s scope is the active one.
struct Object : public CObject, public ScopeCMInterpreter* interpreter;
bool master;
Object(CMInterpreter* interpreter);
Object(const Object& o);
Creates a class prototype associated with the interpreter. Copy construction produces an instance with copied bindings; the interpreter must outlive both prototypes and instances.
bool release() override;
Runs the interpreted destructor for an instance and returns true to allow deletion through CObject. Prototypes do not run that destructor.
Runs a method with this object as the active scope. On CError, it attempts dispatch through an object-valued super binding; without such a superclass, the failure propagates.
class ObjectScopeObjectScope(CMInterpreter* i, Object* o);
Temporarily pushes an existing object’s scope for method execution. Both the interpreter and object must outlive this guard.
~ObjectScope();
Restores the previous scope unless pop() has already done so.
void pop();
Restores the previous scope early. Call at most once, while this object scope is active.