Skip to content

Commit 038e255

Browse files
committed
add nameof
1 parent 2c7a365 commit 038e255

21 files changed

+201
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ FScript currently includes:
2727
- pattern matching: list, option, tuple, record, union cases,
2828
- optional type annotations on parameters,
2929
- type declarations: records and unions (including recursive forms),
30-
- interpolation, pipeline operator, and `typeof` type tokens for host workflows.
30+
- interpolation, pipeline operator, `typeof` type tokens, and `nameof` identifier tokens for host workflows.
3131

3232
## Quick Start
3333

docs/embedding-fscript-language.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ match value with
103103
| _ -> printfn "Not a function"
104104
```
105105

106+
## Using `nameof` for exported capability keys
107+
108+
`nameof` returns the bound identifier name as a string and type-checks that the identifier exists.
109+
110+
```fsharp
111+
open FScript.Language
112+
113+
let src = "let run_step x = x\nnameof run_step"
114+
let value = FScript.run src
115+
// value = VString "run_step"
116+
```
117+
106118
## Supported types
107119

108120
Host-visible static types are represented by `Type`:

docs/external-functions.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ Current runtime-handled groups include:
3333

3434
### Filesystem
3535
- `Fs.readText : string -> string option`
36+
- `Fs.combinePath : string -> string -> string`
37+
- `Fs.parentDirectory : string -> string option`
38+
- `Fs.extension : string -> string option`
39+
- `Fs.fileNameWithoutExtension : string -> string`
3640
- `Fs.glob : string -> string list option`
41+
- `Fs.enumerateFiles : string -> string -> string list option`
3742

3843
### Regex
3944
- `Regex.matchGroups : string -> string -> string list option`

docs/language-choices.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ let x =
4949
- Language core stays minimal.
5050
- Host capabilities are exposed through explicit extern functions.
5151
- Typed decoding workflows use `typeof Name` tokens with host externs.
52+
- Capability maps can use `nameof identifier` for stable script-side function keys.
5253

5354
## Formatting and layout choices
5455
- `match` case columns align.

docs/sandbox-and-security.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ This document defines the security model for running FScript programs with host
1515
- The CLI allows overriding root with `--root <path>` (or `-r <path>`).
1616

1717
Filesystem extern behavior:
18-
- `Fs.readText` and `Fs.glob` resolve candidate paths through `HostCommon.tryResolvePath`.
18+
- `Fs.readText` and `Fs.enumerateFiles` resolve candidate paths through `HostCommon.tryResolvePath`.
19+
- `Fs.glob` evaluates patterns under `RootDirectory`.
1920
- Access is granted for paths within `RootDirectory` (or exactly equal to it).
2021
- Out-of-bound paths return `None`.
2122

docs/supported-types.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,5 @@ This document specifies the value and type system used by the interpreter.
7272

7373
## Reflection
7474
- `typeof Name` yields a type token.
75+
- `nameof identifier` yields the bound identifier name as `string`.
7576
- Type tokens are consumed by host externs (for example JSON/XML decoding).

docs/syntax-and-indentation.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ This document describes the concrete syntax accepted by the interpreter and the
4949
- Other:
5050
- `raise "message"`
5151
- `typeof Name`
52+
- `nameof identifier`
5253
- interpolated strings `$"hello {name}"`
5354

5455
## Operator precedence

samples/types-showcase.fss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ let updated = { user with Tags = user.Tags @ ["mathematician"] }
4040
// Inline structural annotation: any record with matching fields is accepted.
4141
let format_address (address: { City: string; Zip: int }) = $"{address.City} ({address.Zip})"
4242

43+
// Name exposure for host capability maps.
44+
let capabilities =
45+
Map.empty ""
46+
|> Map.add (nameof format_address) "address formatting"
47+
|> Map.add (nameof make_office_address) "office address constructor"
48+
4349

4450
let city =
4551
match updated.Address with
@@ -60,6 +66,7 @@ let monthlyPrice =
6066
| Free -> 0
6167
| Premium amount -> amount
6268

69+
let missing = "missing"
6370

6471
print $"User: {updated.Name}"
6572
print $"City: {city}"
@@ -72,6 +79,7 @@ print $"Subscription price: {monthlyPrice}"
7279
// - value created through another named record type (OfficeAddress)
7380
print $"Structural address from literal: {format_address parisAddress}"
7481
print $"Structural address from OfficeAddress: {format_address officeAddress}"
82+
print $"Capability for format_address: {Map.tryFind (nameof format_address) capabilities |> Option.defaultValue missing}"
7583

7684

7785
updated.Tags |> List.iter print

src/FScript.Language/Ast.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ and Expr =
6161
| ESome of Expr * Span
6262
| ENone of Span
6363
| ETypeOf of string * Span
64+
| ENameOf of string * Span
6465
| EInterpolatedString of InterpolatedPart list * Span
6566

6667
and InterpolatedPart =
@@ -114,4 +115,5 @@ module Ast =
114115
| ESome (_, s) -> s
115116
| ENone s -> s
116117
| ETypeOf (_, s) -> s
118+
| ENameOf (_, s) -> s
117119
| EInterpolatedString (_, s) -> s

src/FScript.Language/Eval.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,11 @@ module Eval =
470470
match typeDefs.TryFind name with
471471
| Some t -> VTypeToken t
472472
| None -> raise (EvalException { Message = $"Unknown type '{name}'"; Span = span })
473+
| ENameOf (name, span) ->
474+
if env.ContainsKey name then
475+
VString name
476+
else
477+
raise (EvalException { Message = $"Unbound variable '{name}'"; Span = span })
473478
| EInterpolatedString (parts, span) ->
474479
let sb = System.Text.StringBuilder()
475480
for part in parts do

0 commit comments

Comments
 (0)