Skip to content

Commit 041f59c

Browse files
committed
add embedding docs
1 parent b258392 commit 041f59c

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ See [`docs/sandbox-and-security.md`](docs/sandbox-and-security.md) for the full
109109
- [`docs/supported-types.md`](docs/supported-types.md)
110110
- [`docs/function-annotations.md`](docs/function-annotations.md)
111111
- [`docs/external-functions.md`](docs/external-functions.md)
112+
- [`docs/embedding-fscript-language.md`](docs/embedding-fscript-language.md)
112113
- [`docs/sandbox-and-security.md`](docs/sandbox-and-security.md)
113114
- [`docs/fsharp-ocaml-differences.md`](docs/fsharp-ocaml-differences.md)
114115
- [`docs/assemblies-and-roles.md`](docs/assemblies-and-roles.md)

docs/embedding-fscript-language.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Embedding `FScript.Language`
2+
3+
This document describes the host-facing interface of `FScript.Language`:
4+
- running the interpreter pipeline,
5+
- discovering script functions,
6+
- invoking functions,
7+
- supported host-visible types and values.
8+
9+
## Namespace and entry points
10+
11+
Reference `MagnusOpera.FScript.Language` and use namespace `FScript.Language`.
12+
13+
Primary entry points are in module `FScript`:
14+
15+
- `FScript.parse : string -> Program`
16+
- `FScript.infer : Program -> TypeInfer.TypedProgram`
17+
- `FScript.inferWithExterns : ExternalFunction list -> Program -> TypeInfer.TypedProgram`
18+
- `FScript.eval : TypeInfer.TypedProgram -> Value`
19+
- `FScript.evalWithExterns : ExternalFunction list -> TypeInfer.TypedProgram -> Value`
20+
- `FScript.run : string -> Value` (parse + infer + eval without externs)
21+
22+
## Running scripts
23+
24+
```fsharp
25+
open FScript.Language
26+
27+
let source = "let inc x = x + 1\ninc 41"
28+
let result = FScript.run source
29+
30+
match result with
31+
| VInt n -> printfn "Result: %d" n
32+
| other -> printfn "Unexpected value: %s" (Pretty.valueToString other)
33+
```
34+
35+
## Running with external functions
36+
37+
Use `inferWithExterns` and `evalWithExterns` when the script needs host functions.
38+
39+
```fsharp
40+
open FScript.Language
41+
42+
let toUpperExtern =
43+
{ Name = "toUpper"
44+
Scheme = Forall([], TFun(TString, TString))
45+
Arity = 1
46+
Impl =
47+
function
48+
| [ VString s ] -> VString (s.ToUpperInvariant())
49+
| _ -> raise (EvalException { Message = "toUpper expects string"; Span = Span.mk (Span.pos 0 0) (Span.pos 0 0) }) }
50+
51+
let source = "toUpper \"fscript\""
52+
let program = FScript.parse source
53+
let typed = FScript.inferWithExterns [ toUpperExtern ] program
54+
let result = FScript.evalWithExterns [ toUpperExtern ] typed
55+
```
56+
57+
## Getting function metadata
58+
59+
After inference, function descriptors can be produced with `Descriptor.describeFunctions`.
60+
61+
```fsharp
62+
open FScript.Language
63+
64+
let src = "let add x y = x + y\nlet rec fact n = if n = 0 then 1 else n * fact (n - 1)"
65+
let typed = src |> FScript.parse |> FScript.infer
66+
67+
let functions =
68+
Descriptor.describeFunctions typed Map.empty
69+
70+
for f in functions do
71+
let args = f.Parameters |> List.map Types.typeToString |> String.concat " -> "
72+
printfn "%s : %s -> %s" f.Name args (Types.typeToString f.ReturnType)
73+
```
74+
75+
`FunctionDescriptor` exposes:
76+
- `Name`
77+
- `Parameters` (`Type list`)
78+
- `ReturnType` (`Type`)
79+
- `Scheme` (`Scheme option`)
80+
- `IsRecursive`
81+
- `Span`
82+
83+
## Invoking functions
84+
85+
Function invocation is expression-based: evaluate a script where the target function is called.
86+
87+
```fsharp
88+
open FScript.Language
89+
90+
let src = "let add x y = x + y\nadd 1 2"
91+
let value = FScript.run src
92+
```
93+
94+
You can also evaluate to a function value:
95+
96+
```fsharp
97+
open FScript.Language
98+
99+
let value = FScript.run "let add1 x = x + 1\nadd1"
100+
101+
match value with
102+
| VClosure _ -> printfn "Function value returned"
103+
| _ -> printfn "Not a function"
104+
```
105+
106+
## Supported types
107+
108+
Host-visible static types are represented by `Type`:
109+
110+
- `TUnit`
111+
- `TInt`
112+
- `TFloat`
113+
- `TBool`
114+
- `TString`
115+
- `TList of Type`
116+
- `TTuple of Type list`
117+
- `TRecord of Map<string, Type>`
118+
- `TStringMap of Type`
119+
- `TOption of Type`
120+
- `TFun of Type * Type`
121+
- `TNamed of string`
122+
- `TUnion of string * Map<string, Type option>`
123+
- `TTypeToken`
124+
- `TVar of int`
125+
126+
Use `Types.typeToString` for display/diagnostics.
127+
128+
## Runtime values
129+
130+
Evaluation returns `Value`:
131+
132+
- `VUnit`
133+
- `VInt of int64`
134+
- `VFloat of float`
135+
- `VBool of bool`
136+
- `VString of string`
137+
- `VList of Value list`
138+
- `VTuple of Value list`
139+
- `VRecord of Map<string, Value>`
140+
- `VStringMap of Map<string, Value>`
141+
- `VOption of Value option`
142+
- `VUnionCase of string * string * Value option`
143+
- `VUnionCtor of string * string`
144+
- `VTypeToken of Type`
145+
- `VClosure of string * Expr * Env ref`
146+
- `VExternal of ExternalFunction * Value list`
147+
148+
Use `Pretty.valueToString` for a readable string form.
149+
150+
## Errors
151+
152+
`FScript.Language` raises typed exceptions with source spans:
153+
154+
- `ParseException` (`ParseError`)
155+
- `TypeException` (`TypeError`)
156+
- `EvalException` (`EvalError`)
157+
158+
Each error contains:
159+
- `Message`
160+
- `Span` (`Line`/`Column` information)

0 commit comments

Comments
 (0)