sml

SML { ❄ }

中文 EN

Chapter 10: Complete Reference to Features

Chapter 10: Complete Reference to Features

The design principle of SML is “from minimalism to richness, with customizable functions” - the basic seven piece set is enabled by default; Complex abilities are disabled by default and can be explicitly enabled using @feature enable when needed.

This chapter is an authoritative reference for each feature: opening methods, syntax, error messages, and relationships with other features.

10.1 How to turn on/off features

At the beginning of the file, use the @feature command:

@version v1
@feature enable glob regex
@feature disable ext-rewrite

-enable name list: separated by spaces.

-disable name list: Same as above.

-It can appear multiple times and take effect by overlapping in the order of appearance.

-Write after @version and before other content.

After activation, the corresponding capabilities can be used within this file (or included subfiles); Different files can be declared independently.

10.2 Built in feature list

include (default enabled)

The most basic “file insertion” ability.

ItemValue
StatusDefault enabled, unable to disable
Grammarinclude "path.sml"
FunctionInsert the content of the target file as it is
Path benchmarkThe directory containing the file itself
Nesting limit32 layers (over limit error)
Circular referenceError (not silent)

Error codes: include.circular, include.depth-exceeded, include.not-found.

namespace (default enabled)

as namespace, pointwise path, macro/contract isolation.

ItemValue
StatusDefault On
Grammarinclude "x" as a.b.c
FunctionPackage content into a { b { c { ... } } } nested blocks
Macro IsolationYes - @name/@contract is also isolated by namespace
External reference syntaxa.b.c.MacroName (qualified name)
Internal reference syntaxMacroName (local name, parser automatically adds prefix)

Error codes: ns.invalid-path, ns.duplicate-symbol, ns.unresolved-prefix.

implicit-ns (default enabled)

include without extension is automatically used as a namespace.

ItemValue
StatusDefault On
Grammarinclude "ui" Equivalent include "ui.sml" as ui
Implicit namespace namefile name (without extension)
Explicit as CoverageExplicit as foo takes precedence over implicit

Close it: @feature disable implicit-ns - Afterwards, include "ui" must have an extension.

multi (default off)

Include multiple targets and import aliases at once.

ItemValue
StatusDefault Off
Open@feature enable multi
Grammarinclude "a.sml", "b.sml" as y, "c"
Alias formatimport ui.buttons, admin.panel
Same name conflictError (not silent)

Error codes: multi.dup-name, multi.empty.

glob (default off)

* is compatible with multiple files in the matching directory.

ItemValue
StatusDefault Off
Open@feature enable glob
Grammarinclude "widgets/*.sml"
Wildcard* (one character, not crossing /), ? (single character)
SortDictionary order determined, consistent across platforms
Implicit asApplicable - include "widgets/*"as widgets

Error code: glob.not-found (if 0 matches) glob.malformed

regex (default off)

re://.../ prefix triggers regular matching.

ItemValue
StatusDefault Off
Open@feature enable regex
Grammarinclude "re:^v[0-9]+\\.sml$" as versions
Regular subset. * + ? ^ $ [a-z]\\. \\d \\w
PerformanceHandwritten recursive backtracking, O (n · m) sufficient file name short string
AttentionUse \\. as the path delimiter (\ also needs to be double written in md)

Complete regularization features (lookahead, backref) not supported - deliberately kept simple, for complex matching, please use shell universal+glob.

ext-rewrite (default off)

Parse files with any suffix as .sml.

ItemValue
StatusDefault Off
Open@feature enable ext-rewrite
Grammarinclude "*.json" -> .sml, include "conf" -> .sml
Typical usageRewrite .json/.yaml/.conf and process with SML parser
RiskIncorrect parsing of binary files as SMLs can cause stack explosion; Suggest adding globe restrictions

contract (default enabled)

@contract/@is verification and backfilling.

ItemValue
StatusDefault On
Grammar@contract Name [loose] { field: type [default v] [min n] [max n] [enum(a,b)] [?] [required] }
Reference typestr int num bool XQZ array[T] enum(...) or another contract name
Strictnessdefault strictness; loose allows undeclared fields
NestedInfinite; Recursive contract detects loops when referenced
Wrong positionAccurate to rows and columns

Error codes: contract.required-missing, contract.type-mismatch, contract.enum-invalid, contract.out-of-range, contract.unknown-field, contract.recursive.

env (default enabled)

$env.VAR environment variable injection.

ItemValue
StatusDefault On
Grammar$env.VAR_NAME
Missing behaviorReplace with empty string (no error reported)
TypeAlways a string (numbers should also be quoted)
Escape_ . - is available in the name; The first character must be a letter or _
Nested$env cannot write $env anymore

Error code: env.bad-name.

escape (default enabled)

Escaping within a quoted string.

ItemValue
StatusDefault On
Support\n \t \r \\ \" \' \0 \u{XXXX} \uXXXX
Not supportedOctal \077, hexadecimal naked \x41 (to avoid ambiguity)
ScopeQuotation string only; Naked words do not escape

fragment (default enabled)

@name/&name fragment inheritance.

ItemValue
StatusDefault On
GrammarDefine @name { ... }, Reference key: &name
ScopeFollow namespace (when @feature enable namespace)
ConflictSame Scope Duplicate @name Error

top-array (default enabled)

The top level of the file allows for arrays (not objects).

ItemValue
StatusDefault On
Grammar[{...} {...} ...] (top layer is array)
Typical scenarioConfiguration items are sequential tables (such as monitoring rules, routing tables)

bareword-str (default enabled)

Naked words are automatically recognized as strings.

ItemValue
StatusDefault On
Close@feature disable bareword-str - all strings must be quoted afterwards
TriggerWhen version v.strict-strings() is set

10.3 Compatibility Matrix

Features ↓→with namespacewith multiwith globewith regex
include✅ Direct combination
namespace
multi⚠️ See Note 1⚠️
glob✅ (Implicit as)⚠️❌ Exclusive see Note 2
regex⚠️❌ Mutual exclusion-
ext-rewrite
contract✅ (Reference contract with restricted name)

Note 1: The “comma separated” syntax of include "a, b" as y is used together with multi, and a single target in the list cannot contain , (even inside quotation marks - commas inside quotation marks are considered literal).

Note 2: include "re:^.*\\.sml$" has already covered all. sml, there is no need to use include "*.sml" again. Simultaneously using what may be interpreted as “glob priority” or “regex priority” may result in different cross implementation behaviors - SML specifies explicit prefix priority: re: follows regex; *.sml takes the globe.

10.4 Implementation Layer of Features (Architecture Tips)

SML parser runs according to “feature bitmask”:

FeatureSet = (include | namespace | implicit-ns | contract | env | escape
              | fragment | top-array | bareword-str
              | multi | glob | regex | ext-rewrite)

-Core layer (default enabled) 7 bits default=1.

-Entering the hierarchy (default off) 4 bits default=0.

-The parser directly rejects the corresponding syntax for unopened features (parsing error, not silently skipping).

This is the implementation foundation of ‘customizable functionality, don’t fall into the same path as YAML’.

10.5 Performance and Portability

FeaturesImpact on parsing timeCross platform differences
includeO (total file size)Path delimiter normalization (/) ↔ \
namespaceExtremely small (path compiled once)None
multiLinear superpositionNone
globO (n) file enumerationhidden files (.foo) default not included
regexO (n · m) short stringNone
ext-rewriteSize of file to be rewrittenContent encoding assumed UTF-8
contractLinear with field numberRecursive contract needs to be memoize

10.6 Future Features (Roadmap)

The following has not yet been implemented and is only a roadmap preview to avoid readers’ misuse:

-@import once (remove duplicate include to avoid the same file being included multiple times)

-feature from "another.sml" (Inherit feature settings from another file)

-with contract=loose (block level relaxation, override file level settings)

-? ternary abbreviation (semantics of a ? b : c at value position) - Currently, ? is an optional tag

10.7 Give it a try with your hands

Write an features.sml for your project:

@version v1
@feature enable glob multi
@feature disable ext-rewrite

include "modules/*.sml" as modules
import modules.auth, modules.billing

Use commands such as sml check features.sml (refer to [ch07 Multilingual](/en/book/ch07 languages)) to run parsing and contract verification.

Appendix: Comparison and Investigation

Hands on practice

After reading this chapter, directly modify SML in the editor below and click “Run” to immediately see the parsing results or validation errors - having output is necessary for efficient learning.

✍ 动手练习 include 把多个子文件装入各自命名空间:include "auth.sml" as authinclude "billing.sml" as billing。每个子文件用 @is Module 并含 name 字段。验证 auth 与 billing 命名空间都被正确装入。
💡 提示:include ... as auth / as billing 把不同文件装入相互隔离的命名空间,避免字段冲突。
虚拟文件(可在 include 中引用)
auth.sml
@contract Module { name: str }
@is Module
name: auth
billing.sml
@contract Module { name: str }
@is Module
name: billing
✍ 自测考题:第 10 章自测:feature 参考 得分 0 / 4
Q1. 开启 glob 通配 include 用哪个 feature?
Q2. 判断:不声明 @feature,SML 基础语法(键值/块/数组/契约)仍全部可用。
Q3. 下面哪个属于 feature 控制的扩展能力?
Q4. @feature 写错(如拼错名字)通常会?