https://github.com/magnusopera/fscript
Functional language interpreter - F#/ML inspired
https://github.com/magnusopera/fscript
Last synced: 3 months ago
JSON representation
Functional language interpreter - F#/ML inspired
- Host: GitHub
- URL: https://github.com/magnusopera/fscript
- Owner: MagnusOpera
- License: mit
- Created: 2026-02-06T17:07:39.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-02-10T22:55:47.000Z (4 months ago)
- Last Synced: 2026-02-11T00:28:54.243Z (4 months ago)
- Language: F#
- Homepage:
- Size: 491 KB
- Stars: 9
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Support: docs/supported-types.md
Awesome Lists containing this project
README

# FScript
[](https://github.com/MagnusOpera/FScript/actions/workflows/ci-main.yml)
[](https://www.nuget.org/packages/MagnusOpera.FScript.Language)
[](https://www.nuget.org/packages/MagnusOpera.FScript.Runtime)
FScript is a lightweight, embeddable interpreter with an F#/ML-style language.
It is designed for host applications that need:
- a concise functional scripting language,
- strong static checks (Hindley-Milner type inference),
- controlled host extensibility,
- and a clear sandbox/security boundary.
## Why FScript
- **F#/ML lineage**: immutable data, expressions-first style, pattern matching, `let`/`fun`, algebraic modeling.
- **Interpreter pipeline**: lexer -> parser -> type inference -> evaluator.
- **Host-first extensibility**: add external functions with explicit type schemes and runtime implementations.
- **Security-aware embedding**: script capabilities are defined by what the host exposes.
## Language Snapshot
FScript currently includes:
- bindings and functions: `let`, `let rec`, `and` mutual recursion, lambdas,
- control flow: `if/elif/else`, `match`, `for ... in ... do`,
- data: list, option, tuple, map, record, discriminated unions,
- pattern matching: list, option, tuple, record, union cases,
- optional type annotations on parameters,
- type declarations: records and unions (including recursive forms),
- interpolation, pipeline operator, `typeof` type tokens, and `nameof` identifier tokens for host workflows.
- unified brace literals for records/maps (`{ Field = value }`, `{ [key] = value }`, `{}` for empty map), with map keys typed as `string`.
## Getting Started Tutorial
If you are new to FScript, start with the progressive tutorial:
- [`docs/guides/getting-started-tutorial.md`](docs/guides/getting-started-tutorial.md)
It covers installation, syntax basics, flow control, collections, pattern matching, stdlib usage, includes, and host/export concepts.
## Installation
### CLI via Homebrew
```bash
brew install magnusopera/tap/fscript
```
### Embeddable language via NuGet
- `MagnusOpera.FScript.Language`
- `MagnusOpera.FScript.Runtime`
## VS Code Extension
FScript has a first-party VS Code extension with syntax highlighting and Language Server features (diagnostics, completion, hover, symbols, go-to-definition, references, rename, semantic tokens, inlay hints).
- VS Code Marketplace: `https://marketplace.visualstudio.com/items?itemName=MagnusOpera.fscript`
- Open VSX: `https://open-vsx.org/extension/MagnusOpera/fscript`
The extension uses automatic .NET runtime acquisition via `.NET Install Tool` and falls back to `dotnet` from `PATH` when needed.
Source lives in [`vscode-fscript/`](vscode-fscript/).
## Repository Development
### Build
```bash
make build
```
### Test
```bash
make test
```
### Run a script
```bash
dotnet run --project src/FScript -- samples/types-showcase.fss
```
Run a script with script arguments (after `--`):
```bash
dotnet run --project src/FScript -- samples/fibonacci.fss -- 10
```
Optional sandbox root override:
```bash
dotnet run --project src/FScript -- --root /tmp/sandbox samples/types-showcase.fss
```
Disable default runtime externs (`Registry.all`):
```bash
dotnet run --project src/FScript -- --no-default-externs samples/types-showcase.fss
```
Load user extern providers from an assembly (repeatable):
```bash
dotnet run --project src/FScript -- --extern-assembly ./MyExterns.dll samples/types-showcase.fss
```
Run a script from stdin:
```bash
cat samples/types-showcase.fss | dotnet run --project src/FScript -- -r .
```
Run stdin mode with script arguments:
```bash
cat samples/types-showcase.fss | dotnet run --project src/FScript -- -r . -- foo bar
```
Show CLI version:
```bash
dotnet run --project src/FScript -- version
```
In CLI execution modes, scripts get:
- stdlib `type Environment = { ScriptName: string option; Arguments: string list }`
- CLI-injected `let Env = ...`
Start REPL:
```bash
dotnet run --project src/FScript --
```
Useful samples:
- [`samples/types-showcase.fss`](samples/types-showcase.fss)
- [`samples/patterns-and-collections.fss`](samples/patterns-and-collections.fss)
- [`samples/quicksort.fss`](samples/quicksort.fss)
- [`samples/tree.fss`](samples/tree.fss)
- [`samples/mutual-recursion.fss`](samples/mutual-recursion.fss)
- [`samples/imports-and-exports.fss`](samples/imports-and-exports.fss)
## Interpreter Architecture
The core engine lives in `src/FScript.Language` and runs in four stages:
1. **Lexing**: indentation-aware tokenization.
2. **Parsing**: AST construction with expression/layout rules.
3. **Type inference**: Hindley-Milner inference + unification + optional annotations.
4. **Evaluation**: typed AST evaluation with immutable values and pattern matching.
Host integration lives in `src/FScript.Runtime`.
## Extensibility Model
FScript is extended through host-provided externs.
Each extern declares:
- a public name (for script calls),
- a type scheme,
- arity,
- implementation.
Built-in host extern families include `Fs.*`, `Json.*`, `Xml.*`, `Regex.*`, hashing, GUIDs, and `print`.
`List.*`, `Map.*`, and `Option.*` are provided by the embedded stdlib prelude.
For details and extension workflow, see [`docs/specs/external-functions.md`](docs/specs/external-functions.md).
## Sandbox and Security
FScript runs in-process. Security is capability-based:
- scripts can only do what exposed externs allow,
- core language evaluation is deterministic over in-memory values,
- side effects and external I/O are controlled at host extern boundaries.
Operational controls (timeouts, cancellation, resource limits, process/container isolation) are host responsibilities.
See [`docs/specs/sandbox-and-security.md`](docs/specs/sandbox-and-security.md) for the full model and checklist.
## Documentation
- Documentation website: `https://magnusopera.github.io/FScript/`
- Documentation portal: [`docs/README.md`](docs/README.md)
- Tutorial: [`docs/guides/getting-started-tutorial.md`](docs/guides/getting-started-tutorial.md)
- Specifications index: [`docs/specs/README.md`](docs/specs/README.md)
- Architecture index: [`docs/architecture/README.md`](docs/architecture/README.md)
- FScript vs F# / OCaml: [`docs/guides/fsharp-ocaml-differences.md`](docs/guides/fsharp-ocaml-differences.md)
Website development commands:
```bash
make website-install
make website-build
make website-serve
make website-version version=X.Y.Z
```
## Changelog
- [`CHANGELOG.md`](CHANGELOG.md)
## License
This project is licensed under the MIT License.
See [`LICENSE`](LICENSE).