sxript treats programs as expressions that can be reduced, inspected, extended, and executed. Its bracket forms distinguish ordinary grouping, text, vectors, executable code, and environment lookup without separating them into unrelated syntaxes. Programs can be developed in the browser workbench or run directly from the command line.
block({
func(square,{[x]*[x]}):
let(values,<1,2,3,4,5>):
print_apply(square,[values])
})
Quick start
Run the test suite, start the interactive prompt, or execute a program directly:
npm test
npm run repl
npm run run -- examples/newtonator.txt
To use the browser workbench, serve the project directory locally:
python -m http.server 8000
Then open http://localhost:8000.
The language
Each bracket form has a distinct and consistent role:
| Form | Role |
|---|---|
(x) |
Grouping and application |
`x' |
Quoted text |
<x> |
Vector data |
{x} |
Occult code |
[x] |
Environment lookup |
Values are typed internally while their syntax remains composable. A program can construct a partial expression, preserve it as data, and supply the missing context later. Occult code can likewise be stored, examined, transformed, and executed.
let(job,{print_`hello'})
block([job])
func(increment,{[x]+1})
report(increment)
Functions
Named functions use func; anonymous functions use $. Their arguments occupy [x], [y], [z], [t], [u], and [v].
func(square,{[x]*[x]})
$({[x]-cos([x])})
Function names resolve through the caller’s environment. This caller-scoped model allows a function to work directly with the definitions and state of the expression that invokes it.
Scope
block evaluates within a shared environment. sub inherits surrounding values but gives writes a private boundary. Together they provide an explicit distinction between shared and local state.
block({let(answer,42):print_[answer]})
sub({let(answer,0):print_[answer]})
print_ is a return channel rather than an early exit. A procedural expression may print several values, continue evaluating, and combine those values in order.
Code that constructs code
Generated syntax is a first-class part of sxript. Partial forms such as 5+ and e? remain available for composition until surrounding syntax completes them. This makes direct combinator constructions possible alongside ordinary function calls.
Within constructed occult code, {name} embeds the current value of name. Definitions can therefore be assembled from computed names and bodies:
let(name,counter)
unoccult({func({name},{0})})
A function body is structured occult code. Operations such as report, elem, replace, and unoccult allow functions to inspect and redefine their own visible structure. Stateful constructions can therefore live in inspectable definitions instead of hidden closure frames.
Exact decimal arithmetic
The large-number primitives preserve decimal source exactly throughout a calculation:
largeadd largesub largemul largediv
largeabs largesci largeunsci
The companion largenum-prg.txt module builds powers, factorials, Fibonacci numbers, comparisons, and precision control in sxript itself. The example library extends the same foundation to square roots, the golden ratio, Pascal’s triangle, and digits of π.
Procedures and modules
The procedural layer provides for, counted do...loop, anchors, jumps, and conditional jumps. These forms sequence actions while leaving the expression model intact.
Modules are ordinary sxript programs. include executes a module in the current environment and leaves its definitions available. run executes behind a private write boundary and exposes only the module’s printed result.
include(`linalg-prg.txt')
determinant(<<1,2>,<3,4>>)
The browser discovers the available programs and modules from the examples/ and prg/ directory listings. Source files are fetched only when selected or required, and loaded dependencies are cached for the rest of the page session.
prg/. Complete demonstrations and applications live in examples/.