Contributors

How Nerdamer works

This is a short tour of the current codebase: where a call enters, how notation becomes a symbolic object, where algebra and calculus take over, and how the result becomes text or TeX.

Start with one call

nerdamer('factor(x^2-1)') enters through the package root. The callable export is thin: it forwards notation to Parser.parse().

src/index.ts
Then follow the object

The parser can return more than an Expression. Equations, vectors, matrices, collections, sets, and dictionaries all participate in the same package.

src/core/types.ts
Internal implementation guide. These pages explain how the current source is organized. Internal classes and file paths can change independently of the supported package API.

One expression through the engine

The root entry point assembles the full package, but notation still flows through one central parser pipeline. Once a parser entity exists, higher-level algorithms can work with that object directly rather than converting back through strings.

From notation to outputHigh-level execution flow
flowchart TD A["nerdamer(input)"] --> B["src/index.ts"] B --> C["Parser.parse(input, values)"] C --> D["normalize input"] D --> E["tokenize"] E --> F["toRPN"] F --> G["parseRPN"] G --> H{"ParserEntity"} H --> I["Expression"] H --> J["Equation"] H --> K["Vector / Matrix"] H --> L["Collection / Set / Dictionary"] I --> M["algebra / calculus / math / solve"] J --> M K --> M L --> M M --> N["Converter"] N --> O["text"] N --> P["TeX"]

Three layers to keep in mind

1

Package assembly

src/index.ts is the full-package entry point. It imports the domain modules, exposes the callable nerdamer function, and adds selected chainable operations to the core object model.

2

Core symbolic engine

src/core contains the parser, Expression, equations, vectors, matrices, rationals, dispatch, converters, settings, and the shared operations that hold the symbolic representation together.

3

Mathematical domains

algebra, calculus, math, and solve operate on those core objects. They contain the higher-level algorithms rather than a second expression system.

The entry point is small

function nerdamer(e: ExpressionInput, values?: ParserValuesObject): ParserEntity {
  return Parser.parse(e, values);
}

The package root does much more assembly around this function, but the notation-to-object handoff itself is direct.

This split is useful when reading the code. If the problem is “what does this string mean?”, start with the parser. If the parser produced the right object and the mathematics is wrong afterward, move into the relevant algebra, calculus, math, or solver module.

How buildFunction() compiles expressions

buildFunction() does not pass raw input directly to JavaScript. The input is first parsed into the library's expression representation, then emitted from that parsed, canonicalized expression as JavaScript-number code. Function calls are limited to registered numerical implementations, and unsupported symbolic operations are rejected rather than inserted into the generated function.

The final compilation step uses new Function(...) to create the callable JavaScript function. Normal parsing, simplification, solving, evaluation, and symbolic manipulation do not use eval() or new Function.

return new Function(...functionArgs, functionDef);
Content Security Policy. Because the final compilation step uses new Function, buildFunction() may be unavailable under a CSP that blocks dynamic code generation. This restriction applies to the compilation mechanism; the library does not evaluate the original input string as arbitrary JavaScript.

What can come back from the parser?

ParserEntity is the common result family. Ordinary symbolic notation usually produces an Expression, but syntax and functions can produce structured entities as well.

Expressionscalar symbolic value
Equationleft and right sides
Vectorordered parser values
Matrixrow/column structure
Collectionordered collection
ValuesSetfinite set semantics
Dictionarykeyed parser values

Where to go next