Глава I.2
Source and normalization
Source text, tokens, literals, and the normalized form of a Lispex rule.
Непереведённый текст показан на английском языке
Scope
Write a rule as UTF-8 source and supply its input separately. Preparation reads the source and resolves its names before evaluation begins.
UTF-8 source
Source text is the UTF-8 spelling supplied for a module. Decoded characters use Unicode scalar values. Source identity retains the original bytes. The resolved program has its separate program identity. Values and text defines the text values that a rule can return.
2.1 Preserve source spelling
Source reading applies the raw Unicode rule to names and string literals. The resulting spellings determine source identifiers and literal text.
Why
Distinct decoded scalar sequences remain distinct across products. A host locale or compiler table must not silently rename a binding or alter data.
Keep two Unicode spellings distinct
lispex.example.v2.source.distinct-name-spellings · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(let ((|é| 1) (|é| 2))
(list |é| |é|))))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
(1 2)Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "list",
"items": [
{
"kind": "integer",
"value": "1"
},
{
"kind": "integer",
"value": "2"
}
]
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The two names denote different bindings and the result is the list of exact integers 1 and 2. Product invocation awaits its 2.0 adapter.
The first name contains one scalar. The second contains an e followed by a combining accent. Normalizing the names would merge distinct bindings.
Preserve text inside a string
lispex.example.v2.source.literal-text · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
"A (; B)"))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
"A (; B)"Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "string",
"value": "A (; B)"
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The rule returns the exact string A followed by a space, an opening parenthesis, a semicolon, a space, B, and a closing parenthesis. Product invocation awaits its 2.0 adapter.
Delimiters and a comment marker inside the quoted text belong to the string value.
2.2 Decode exact UTF-8 source bytes
Each module must satisfy the byte grammar before reading starts. Reject every malformed UTF-8 sequence. Decoding never inserts a replacement scalar. A byte order mark has no special treatment. A leading mark therefore fails the reader grammar. The same scalar is permitted inside a string, a quoted identifier, or a comment.
Why
Exact decoding keeps the submitted bytes and their meaning reproducible. Repair and automatic marker removal would silently change an input.
Reject malformed source octets
lispex.example.v2.source.invalid-utf8 · ред. 2
{
"notation": "documentation-reader-cases",
"cases": [
{
"case": "overlong",
"sourceOctetsHex": "c080",
"moduleName": "main",
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
},
{
"case": "surrogate",
"sourceOctetsHex": "eda080",
"moduleName": "main",
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
},
{
"case": "out-of-range",
"sourceOctetsHex": "f4908080",
"moduleName": "main",
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
},
{
"case": "stray-continuation",
"sourceOctetsHex": "80",
"moduleName": "main",
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
},
{
"case": "truncated",
"sourceOctetsHex": "e282",
"moduleName": "main",
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
},
{
"case": "invalid-leading-byte",
"sourceOctetsHex": "ff",
"moduleName": "main",
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
},
{
"case": "decode-before-reader",
"sourceOctetsHex": "29ff",
"moduleName": "main",
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}
]
}
Запрос и файлы
{
"notation": "documentation-request",
"source": "invalid-utf8.json",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"caseInput": "submit-each-listed-source-independently"
}
source.encodingПодробности результата
{
"case": "overlong",
"kind": "prepare-failure",
"stage": "decode",
"valueCount": 0,
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}source.encodingПодробности результата
{
"case": "surrogate",
"kind": "prepare-failure",
"stage": "decode",
"valueCount": 0,
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}source.encodingПодробности результата
{
"case": "out-of-range",
"kind": "prepare-failure",
"stage": "decode",
"valueCount": 0,
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}source.encodingПодробности результата
{
"case": "stray-continuation",
"kind": "prepare-failure",
"stage": "decode",
"valueCount": 0,
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}source.encodingПодробности результата
{
"case": "truncated",
"kind": "prepare-failure",
"stage": "decode",
"valueCount": 0,
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}source.encodingПодробности результата
{
"case": "invalid-leading-byte",
"kind": "prepare-failure",
"stage": "decode",
"valueCount": 0,
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}source.encodingПодробности результата
{
"case": "decode-before-reader",
"kind": "prepare-failure",
"stage": "decode",
"valueCount": 0,
"diagnostic": {
"phase": "decode",
"code": "source.encoding",
"data": {
"reason": "invalid-utf8"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false,
"replacementScalarsInserted": false
}Вызов продукта
Ожидаемый результат
Every byte sequence is rejected during decoding. The final case does not reach its earlier unmatched parenthesis. Product invocation awaits its 2.0 adapter.
The text fixture lists independent source inputs. Hex octets describe exact submitted bytes. This notation is not a public input codec.
Preserve a mark inside literal text
lispex.example.v2.source.literal-byte-order-mark · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
"")))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
""Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "string",
"value": ""
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The result contains the literal U+FEFF scalar. Product invocation awaits its 2.0 adapter.
The UTF-8 decoder preserves the mark as a scalar. The string grammar admits it as data.
Tokens
Tokens distinguish identifiers, literal data, and the delimiters of a form. Reading produces syntax for preparation. Evaluation uses the lexical binding selected during preparation. Quotation uses the decoded name as data. The complete grammar below fixes token boundaries and escapes.
2.3 Read one fixed syntax
The complete reader grammar below determines every source token and datum. Bare identifiers use ASCII characters. Vertical bars admit every Unicode scalar sequence through literal characters or escapes. Identifiers compare by their decoded scalar sequence. Spelling escapes do not create a different name. Only the listed separators end tokens. Block comments nest. A datum comment reads and discards the next datum. Discarded data must satisfy the reader grammar but undergo no normalization. Reader directives and unlisted token prefixes are rejected.
Why
Explicit character sets avoid host locale and Unicode classification differences. Quoted names retain arbitrary text without adding invisible token boundaries. Nested comments remain readable while discarded syntax receives the same finite reading checks.
Read exact names with bars and escapes
lispex.example.v2.source.identifier-spellings · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(let ((|caf\u{e9}| 1) (|café| 2)) (list |café| |café| '|a b| '|| '|1|)))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
(1 2 a b 1)Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "list",
"items": [
{
"kind": "integer",
"value": "1"
},
{
"kind": "integer",
"value": "2"
},
{
"kind": "symbol",
"value": "a b"
},
{
"kind": "symbol",
"value": ""
},
{
"kind": "symbol",
"value": "1"
}
]
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The escaped and literal spellings of café select the same binding. The decomposed name remains distinct. Product invocation awaits its 2.0 adapter.
A numeric spelling inside bars denotes a symbol. The empty barred spelling also denotes a symbol.
Read nested comments and discard complete data
lispex.example.v2.source.nested-and-datum-comments · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(list 1#| outer #| nested |# end |#2 #;#;(ignored) (set! input 9) 3))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
(1 2 3)Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "list",
"items": [
{
"kind": "integer",
"value": "1"
},
{
"kind": "integer",
"value": "2"
},
{
"kind": "integer",
"value": "3"
}
]
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The rule returns the exact integers 1, 2, and 3 in order. Product invocation awaits its 2.0 adapter.
The inner datum comment discards its datum. The outer datum comment then discards the mutation form before normalization.
Reject unlisted source syntax
lispex.example.v2.source.reader-rejections · ред. 2
{
"notation": "documentation-reader-cases",
"cases": [
{
"case": "bare-nonascii",
"source": "café",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
},
{
"case": "nbsp-separator",
"source": "a b",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
},
{
"case": "lone-carriage-return",
"source": "a\rb",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
},
{
"case": "leading-mark",
"source": "(define x 1)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unexpected-source-scalar"
}
}
},
{
"case": "double-mark",
"source": "",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unexpected-source-scalar"
}
}
},
{
"case": "case-directive",
"source": "#!fold-case",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "language-directive",
"source": "#lang lispex",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "shebang",
"source": "#!/usr/bin/lispex",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "unterminated-block",
"source": "#| outer #| inner |#",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-end"
}
}
},
{
"case": "missing-discard",
"source": "#;",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-end"
}
}
},
{
"case": "invalid-discard",
"source": "#; (",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-end"
}
}
},
{
"case": "datum-label",
"source": "#0=(a . #0#)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "alternate-brackets",
"source": "[1 2]",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
},
{
"case": "quasiquote",
"source": "`x",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
},
{
"case": "empty-dotted-list",
"source": "(. a)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "improper-form"
}
}
},
{
"case": "extra-dotted-tail",
"source": "(a . b c)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "improper-form"
}
}
},
{
"case": "vector-dot",
"source": "#(a . b)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "improper-form"
}
}
},
{
"case": "wrong-boolean",
"source": "#true",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
}
]
}
Запрос и файлы
{
"notation": "documentation-request",
"source": "reader-rejections.json",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"caseInput": "submit-each-listed-source-independently"
}
source.tokenПодробности результата
{
"case": "bare-nonascii",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
}source.tokenПодробности результата
{
"case": "nbsp-separator",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
}source.tokenПодробности результата
{
"case": "lone-carriage-return",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
}source.tokenПодробности результата
{
"case": "leading-mark",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unexpected-source-scalar"
}
}
}source.tokenПодробности результата
{
"case": "double-mark",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unexpected-source-scalar"
}
}
}source.tokenПодробности результата
{
"case": "case-directive",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.tokenПодробности результата
{
"case": "language-directive",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.tokenПодробности результата
{
"case": "shebang",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.delimiterПодробности результата
{
"case": "unterminated-block",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-end"
}
}
}source.delimiterПодробности результата
{
"case": "missing-discard",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-end"
}
}
}source.delimiterПодробности результата
{
"case": "invalid-discard",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-end"
}
}
}source.tokenПодробности результата
{
"case": "datum-label",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.tokenПодробности результата
{
"case": "alternate-brackets",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
}source.tokenПодробности результата
{
"case": "quasiquote",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
}source.delimiterПодробности результата
{
"case": "empty-dotted-list",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "improper-form"
}
}
}source.delimiterПодробности результата
{
"case": "extra-dotted-tail",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "improper-form"
}
}
}source.delimiterПодробности результата
{
"case": "vector-dot",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "improper-form"
}
}
}source.tokenПодробности результата
{
"case": "wrong-boolean",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-token"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
Each source fails reading before normalization begins. Product invocation awaits its 2.0 adapter.
The text fixture lists independent source inputs. Hex octets describe exact submitted bytes. This notation is not a public input codec.
2.4 Separate tokens outside literals
Use the token and literal boundaries in the reader grammar. A comment marker is recognized outside String, BarredIdentifier, and Character tokens. A semicolon inside an admitted literal remains part of that literal.
Why
Explicit separators make a source file independent of a host tokenizer. Keeping comments outside literals preserves the data written inside a string.
Token boundaries specify separators and line comments.
Ignore a comment between forms
lispex.example.v2.source.separators-and-comment · ред. 2
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(+ input ; the supplied value
1)))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "41"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
42Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "integer",
"value": "42"
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The comment and separators leave an addition that returns the exact integer 42. Product invocation awaits its 2.0 adapter.
The tab separates two tokens. The line comment ends before the second operand.
Complete reader grammar
SourceBytes = { Utf8Scalar } ;
Utf8Scalar = "00" .. "7F" | "C2" .. "DF" Continuation | "E0" "A0" .. "BF" Continuation | "E1" .. "EC" Continuation Continuation | "ED" "80" .. "9F" Continuation | "EE" .. "EF" Continuation Continuation | "F0" "90" .. "BF" Continuation Continuation | "F1" .. "F3" Continuation Continuation Continuation | "F4" "80" .. "8F" Continuation Continuation ;
Continuation = "80" .. "BF" ;
Document = Gap { Datum Gap } End ;
Datum = List | Vector | Bytevector | Abbreviation | String TokenEnd | Character TokenEnd | Boolean TokenEnd | Number TokenEnd | Identifier TokenEnd ;
List = "(" Gap [ Datum Gap { Datum Gap } [ "." TokenEnd Gap Datum Gap ] ] ")" ;
Vector = "#(" Gap { Datum Gap } ")" ;
Bytevector = "#u8(" Gap { Number TokenEnd Gap } ")" ;
Abbreviation = "'" Gap Datum ;
Gap = { White | LineComment | BlockComment | DatumComment } ;
White = "U+0020" | "U+0009" | LineEnd ;
LineEnd = "U+000A" | "U+000D" "U+000A" ;
LineComment = ";" { !LineEnd Scalar } [ LineEnd ] ;
BlockComment = "#|" { BlockComment | BlockScalar } "|#" ;
BlockScalar = !( "#|" | "|#" ) Scalar ;
DatumComment = "#;" Gap Datum ;
Delimiter = White | "(" | ")" | "'" | "U+0022" | ";" | "#|" | "#;" ;
TokenEnd = &( Delimiter | End ) ;
End = "end-of-input" ;
Identifier = BareIdentifier | BarredIdentifier ;
BareIdentifier = ( Initial { Subsequent } ) - NumericCandidate - ReservedNumber - "." ;
Initial = "A" .. "Z" | "a" .. "z" | "!" | "$" | "%" | "&" | "*" | "/" | ":" | "<" | "=" | ">" | "?" | "^" | "_" | "~" | "+" | "-" | "." | "@" ;
Subsequent = Initial | DecimalDigit ;
NumericCandidate = [ Sign ] ( DecimalDigit { Subsequent } | "." DecimalDigit { Subsequent } ) ;
ReservedNumber = InexactWord | "+i" | "-i" ;
InexactWord = "+inf.0" | "-inf.0" | "+nan.0" | "-nan.0" ;
BarredIdentifier = "|" { BarredScalar | IdentifierEscape } "|" ;
BarredScalar = Scalar - Control - "|" - "U+005C" ;
IdentifierEscape = "U+005C" ( "|" | "U+005C" | ScalarEscape ) ;
String = "U+0022" { StringScalar | StringEscape } "U+0022" ;
StringScalar = Scalar - Control - "U+0022" - "U+005C" ;
StringEscape = "U+005C" ( "U+0022" | "U+005C" | "n" | "r" | "t" | ScalarEscape ) ;
ScalarEscape = "u{" HexDigits "}" ;
HexDigits = HexDigit [ HexDigit [ HexDigit [ HexDigit [ HexDigit [ HexDigit ] ] ] ] ] ;
Character = "#" "U+005C" ( CharacterName | ScalarEscape | CharacterScalar ) ;
CharacterName = "space" | "newline" | "tab" | "return" | "null" ;
CharacterScalar = Scalar - Control - "U+0020" ;
Boolean = "#t" | "#f" ;
Number = [ Sign ] DecimalMagnitude | "#d" [ Sign ] DecimalMagnitude | "#b" [ Sign ] BinaryMagnitude | "#o" [ Sign ] OctalMagnitude | "#x" [ Sign ] HexMagnitude ;
Sign = "+" | "-" ;
DecimalMagnitude = DecimalInteger [ "/" DecimalInteger ] | DecimalInteger "." [ DecimalInteger ] [ Exponent ] | "." DecimalInteger [ Exponent ] | DecimalInteger Exponent ;
Exponent = ( "e" | "E" ) [ Sign ] DecimalInteger ;
DecimalInteger = DecimalDigit { DecimalDigit } ;
BinaryMagnitude = BinaryInteger [ "/" BinaryInteger ] ;
BinaryInteger = BinaryDigit { BinaryDigit } ;
OctalMagnitude = OctalInteger [ "/" OctalInteger ] ;
OctalInteger = OctalDigit { OctalDigit } ;
HexMagnitude = HexInteger [ "/" HexInteger ] ;
HexInteger = HexDigit { HexDigit } ;
BinaryDigit = "0" | "1" ;
OctalDigit = "0" .. "7" ;
DecimalDigit = "0" .. "9" ;
HexDigit = DecimalDigit | "a" .. "f" | "A" .. "F" ;
Control = "U+0000" .. "U+001F" | "U+007F" .. "U+009F" ;
Scalar = "U+0000" .. "U+D7FF" | "U+E000" .. "U+10FFFF" ;
| Notation | Meaning |
|---|---|
SourceBytes | Match all submitted octets before scalar decoding |
Hex pairs in Utf8Scalar and Continuation | One octet or an inclusive octet range |
U+ terminals | The indicated scalar value or inclusive scalar range |
| Other quoted terminals | Literal scalar sequences |
end-of-input | A zero width test for the end of the decoded module |
& and ! | Positive and negative lookahead without consumption |
- | Exclude the right operand from the language on the left |
Use the longest complete atomic token. A token beginning with a decimal digit is numeric. A sign or dot followed by decimal digits also starts a numeric candidate. Radix prefixes commit to their numeric grammar. A malformed candidate cannot fall back to an identifier. The standalone dot is permitted only in a nonempty list before its single tail datum. Parentheses pair exactly. Brackets and braces have no alternate list meaning.
| Input form | Decoded meaning or restriction |
|---|---|
\n, \r, \t in a string | Line feed, carriage return, tab |
\u{...} | The hexadecimal scalar value |
| A scalar escape in the surrogate range or above U+10FFFF | Reader failure |
| Literal control scalars in strings or barred identifiers | Use an escape instead |
|| | The empty identifier name |
#\space, #\newline, #\tab, #\return, #\null | U+0020, U+000A, U+0009, U+000D, U+0000 |
A direct character scalar after #\ | Exactly one scalar followed by a token boundary |
#b, #o, #d, #x | Lowercase radix prefixes with a following optional sign |
| A numeric rational | An unsigned nonzero denominator in the selected radix |
| Decimal leading zeroes and hexadecimal letter case | Preserve the same exact numeric value |
#e, #i, +inf.0, -inf.0, +nan.0, -nan.0, +i, -i | Reader failure |
| Complex tokens that begin as numeric candidates | Reader failure |
#!, #lang, a shebang, datum labels, backquote, comma | Reader failure outside literal text or comments |
| A leading or repeated byte order mark | Reader failure |
| Other whitespace and a lone carriage return | Reader failure outside literal text or comments |
An escaped identifier and a literal identifier with the same decoded scalar sequence name the same binding. A barred numeric spelling is an identifier. It is not a number. Comment and radix prefixes are ordinary text where the literal grammar admits their characters. Block comment delimiters nest even when their surrounding comment text contains quote characters. A datum comment skips trivia before reading its one discarded datum. This includes nested datum comments. An unfinished comment, escape, string, list, or quoted datum fails reading. Syntax inside a discarded datum must still be complete.
The quote prefix becomes the ordinary quote form during normalization. Lists, pairs, vectors, and bytevectors retain their element order. Decimal fractions and exponents reduce to the exact values defined by Exact numbers. The reader creates no cyclic datum.
The reader checks an escape when its final scalar is read. It checks literal control scalars when they are read. Atomic token grammar and numeric value checks occur at the completed token. A bytevector element receives its integer and octet range checks before the next element is read. A malformed numeric token fails before its value checks. A zero denominator fails before a bytevector range check. If reading reaches source end, its end test reserves one read-step.
Literals and surface forms
A literal denotes an immutable value. Quoted names are symbols. Quoted lists are data. Decimal spelling denotes an exact number. Exact numbers defines its arithmetic and rounding contracts. Datum defines the data allowed at the rule boundary.
2.5 Read numeric literals exactly
Numeric literals follow the exact arithmetic rule and the exact-only rule. Reading a decimal spelling uses the decimal value contract.
Why
The same source must denote the same value on every architecture. Decimal notation must retain the value that the author wrote.
Add exact decimal literals
lispex.example.v2.source.exact-decimal · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(= (+ 0.1 0.2) 3/10)))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
#tПодробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "boolean",
"value": true
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The exact decimal sum equals three tenths and the rule returns true. Product invocation awaits its 2.0 adapter.
The comparison checks exact arithmetic. Decimal representation and codec bytes remain separate contracts.
Reject an inexact literal
lispex.example.v2.source.inexact-literal · ред. 3
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
#i0.1))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
source.tokenПодробности результата
{
"kind": "prepare-failure",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
Preparation rejects the explicitly inexact literal and the entry is not evaluated. Product invocation awaits its 2.0 adapter.
The reader mapping uses read and source.token with reason unsupported-reader-prefix. Rejection does not convert this spelling to a supported float.
2.6 Give literals exact values
Strings and quoted identifiers use only the listed escapes. A scalar escape must name a Unicode scalar value. Every numeric token denotes an exact integer or a reduced rational. A decimal exponent scales by an exact power of ten. A rational denominator must be nonzero. Radix prefixes select the digit alphabet in the grammar. Numeric candidates that fail that grammar are errors. They cannot become identifiers. Bytevector elements must denote exact integers from 0 through 255.
Why
One lexical interpretation prevents malformed numbers from becoming accidental names. Exact literals give every product the same data before arithmetic or admission begins.
Read escaped scalars and delimiters
lispex.example.v2.source.scalar-escapes · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(list "line\n\u{1F642}\\\"" #\u{1F642} '|a\|b|))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
("line\n🙂\\\"" #\🙂 a|b)Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "list",
"items": [
{
"kind": "string",
"value": "line\n🙂\\\""
},
{
"kind": "character",
"value": "🙂"
},
{
"kind": "symbol",
"value": "a|b"
}
]
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The result preserves the decoded newline, supplementary scalar, quote, backslash, and barred name. Product invocation awaits its 2.0 adapter.
Escapes name Unicode scalar values. They do not normalize or case fold the result.
Read exact values in every radix
lispex.example.v2.source.radix-and-decimal-values · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(list #b101 #o17 #x-ff #d+12 0.125 12e-1 #xA/F .5 1.))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
(5 15 -255 12 1/8 6/5 2/3 1/2 1)Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "list",
"items": [
{
"kind": "integer",
"value": "5"
},
{
"kind": "integer",
"value": "15"
},
{
"kind": "integer",
"value": "-255"
},
{
"kind": "integer",
"value": "12"
},
{
"kind": "rational",
"numerator": "1",
"denominator": "8"
},
{
"kind": "rational",
"numerator": "6",
"denominator": "5"
},
{
"kind": "rational",
"numerator": "2",
"denominator": "3"
},
{
"kind": "rational",
"numerator": "1",
"denominator": "2"
},
{
"kind": "integer",
"value": "1"
}
]
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
Every spelling becomes its stated exact integer or reduced rational. Product invocation awaits its 2.0 adapter.
The source scale and radix do not become observable numeric state.
Read pair tails, vectors, and bytevectors
lispex.example.v2.source.compound-datum · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
'((a . b) #(1 #t) #u8(0 255)))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
((a . b) #(1 #t) #u8(0 255))Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "list",
"items": [
{
"kind": "pair",
"car": {
"kind": "symbol",
"value": "a"
},
"cdr": {
"kind": "symbol",
"value": "b"
}
},
{
"kind": "vector",
"items": [
{
"kind": "integer",
"value": "1"
},
{
"kind": "boolean",
"value": true
}
]
},
{
"kind": "bytevector",
"bytes": [
0,
255
]
}
]
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The quote returns its ordered pair, vector, and bytevector data. Product invocation awaits its 2.0 adapter.
A dot denotes one list tail. Vectors and bytevectors have no dotted tail syntax.
Reject malformed literal values
lispex.example.v2.source.literal-rejections · ред. 2
{
"notation": "documentation-reader-cases",
"cases": [
{
"case": "unknown-string-escape",
"source": "\"\\q\"",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-escape"
}
}
},
{
"case": "unknown-identifier-escape",
"source": "|a\\n|",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-escape"
}
}
},
{
"case": "surrogate-escape",
"source": "\"\\u{d800}\"",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
},
{
"case": "out-of-range-escape",
"source": "#\\u{110000}",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
},
{
"case": "too-long-escape",
"source": "\"\\u{0000000}\"",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
},
{
"case": "raw-newline",
"source": "\"a\nb\"",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
},
{
"case": "binary-digit",
"source": "#b102",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
},
{
"case": "uppercase-prefix",
"source": "#Xff",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "radix-decimal",
"source": "#x1.2",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
},
{
"case": "zero-denominator",
"source": "1/0",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "zero-denominator"
}
}
},
{
"case": "signed-denominator",
"source": "1/-2",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
},
{
"case": "unfinished-exponent",
"source": "1e+",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
},
{
"case": "numeric-name",
"source": "+12abc",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
},
{
"case": "inexact-prefix",
"source": "#i1.0",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "exactness-prefix",
"source": "#e1",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "infinity",
"source": "+inf.0",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "inexact-number"
}
}
},
{
"case": "nan",
"source": "-nan.0",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "inexact-number"
}
}
},
{
"case": "complex",
"source": "1+2i",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
},
{
"case": "octet-range",
"source": "#u8(256)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
},
{
"case": "octet-fraction",
"source": "#u8(1/2)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
},
{
"case": "invalid-discard-number",
"source": "#; #i1.0",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
},
{
"case": "unit-imaginary",
"source": "+i",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
},
{
"case": "octet-before-later-token",
"source": "#u8(256 #b2)",
"moduleName": "main",
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
}
]
}
Запрос и файлы
{
"notation": "documentation-request",
"source": "literal-rejections.json",
"rootModule": "main",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"caseInput": "submit-each-listed-source-independently"
}
source.tokenПодробности результата
{
"case": "unknown-string-escape",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-escape"
}
}
}source.tokenПодробности результата
{
"case": "unknown-identifier-escape",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-escape"
}
}
}source.tokenПодробности результата
{
"case": "surrogate-escape",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
}source.tokenПодробности результата
{
"case": "out-of-range-escape",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
}source.tokenПодробности результата
{
"case": "too-long-escape",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
}source.tokenПодробности результата
{
"case": "raw-newline",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "invalid-scalar"
}
}
}source.numberПодробности результата
{
"case": "binary-digit",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
}source.tokenПодробности результата
{
"case": "uppercase-prefix",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.numberПодробности результата
{
"case": "radix-decimal",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
}source.numberПодробности результата
{
"case": "zero-denominator",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "zero-denominator"
}
}
}source.numberПодробности результата
{
"case": "signed-denominator",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
}source.numberПодробности результата
{
"case": "unfinished-exponent",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
}source.numberПодробности результата
{
"case": "numeric-name",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
}source.tokenПодробности результата
{
"case": "inexact-prefix",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.tokenПодробности результата
{
"case": "exactness-prefix",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.numberПодробности результата
{
"case": "infinity",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "inexact-number"
}
}
}source.numberПодробности результата
{
"case": "nan",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "inexact-number"
}
}
}source.numberПодробности результата
{
"case": "complex",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.number",
"data": {
"reason": "invalid-number"
}
}
}source.tokenПодробности результата
{
"case": "octet-range",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
}source.tokenПодробности результата
{
"case": "octet-fraction",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
}source.tokenПодробности результата
{
"case": "invalid-discard-number",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-reader-prefix"
}
}
}source.tokenПодробности результата
{
"case": "unit-imaginary",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
}source.tokenПодробности результата
{
"case": "octet-before-later-token",
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.token",
"data": {
"reason": "unsupported-literal"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
Each malformed literal is rejected. No token is reinterpreted as an identifier. Product invocation awaits its 2.0 adapter.
The text fixture lists independent source inputs. Hex octets describe exact submitted bytes. This notation is not a public input codec.
Normalization
Normalization follows the canonical source construction. That table defines the admitted rewrites and preserved semantic nodes. Preparation resolves their references to lexical bindings. A normalizer preserves quoted data and follows the evaluation rules. Source maps retain source positions for display.
2.7 Preserve meaning through normalization
Normalization preserves lexical bindings, literal values, evaluation order, and the first observable failure. A generated binding cannot capture a source reference.
Why
Surface syntax is a way to write the rule. Changing its spelling must not give the normalizer permission to change the rule being evaluated.
Read both quotation forms as data
lispex.example.v2.source.quote-forms · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(equal? '(a b) (quote (a b)))))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
#tПодробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "boolean",
"value": true
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The two quoted lists have equal data and the rule returns true. Product invocation awaits its 2.0 adapter.
Quotation preserves the symbols a and b as data. These spellings do not look up procedure bindings.
Preserve a binding through conditional sugar
lispex.example.v2.source.conditional-sugar · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(let ((saved input))
(cond (#f 0)
(else saved)))))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "42"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
42Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "integer",
"value": "42"
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Вызов продукта
Ожидаемый результат
The conditional reads the surrounding saved binding and returns the exact integer 42. Product invocation awaits its 2.0 adapter.
Lowering the conditional must preserve the surrounding lexical scope.
2.8 Resolve only submitted source
Source submission follows the closed-bundle rule. Reading or normalization cannot add a dependency outside that submitted bundle.
Why
A rule must use the source and library identities fixed by its request. Runtime discovery would introduce an unstated input and an external authority.
Reject runtime source loading
lispex.example.v2.source.runtime-load · ред. 3
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(load "other.scm")))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
library.referenceПодробности результата
{
"kind": "failure",
"valueCount": 0,
"diagnostic": {
"phase": "resolve",
"code": "library.reference",
"data": {
"name": "load",
"reason": "removed-operation"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"externalAccess": {
"filesystem": false,
"network": false
},
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
The runtime load request fails without reading a file or accessing a network. Product invocation awaits its 2.0 adapter.
The string names no granted capability. The source bundle determines which dependencies preparation can resolve.
Preparation failures
Reader and normalization failures use source-bound preparation reports. Preparation and modules defines the closed bundle. The entry runs only after preparation succeeds. The preparation diagnostic mapping gives each failure its catalog identity and typed fields.
2.9 Reject invalid source before evaluation
A reader or normalization failure stops preparation before entry. Record it under the source-bound preparation report rule.
Why
An invalid source cannot provide a valid program identity. Keeping the failure with its source preserves a useful diagnostic without inventing an evaluation.
Reject an unfinished source form
lispex.example.v2.source.unclosed-form · ред. 3
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
input)
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
source.delimiterПодробности результата
{
"kind": "prepare-failure",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-end"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"failureIdentity": {
"basis": "submitted-source",
"validProgramIdentity": false
},
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
The unfinished form fails preparation and produces no rule result. Product invocation awaits its 2.0 adapter.
The definition is complete. The enclosing module is unfinished, so reading fails before preparation can continue.
2.10 Account for preparation separately
Source decoding, reading, and normalization use the preparation account defined by Resources. The finite-limit rule applies before any entry evaluation.
Why
Deep or large source can require work before any rule runs. A finite evaluation budget alone cannot bound that work.
Stop when preparation has insufficient budget
lispex.example.v2.source.prepare-exhaustion · ред. 3
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
input))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite limits below a required preparation reservation",
"evaluate": "finite values sufficient for the identity rule"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
resource-stopПодробности результата
{
"kind": "resource-stop",
"phase": "prepare",
"valueCount": 0,
"terminal": true,
"diagnosticIdentity": {
"phase": "prepare",
"code": "resource.exhausted"
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
An insufficient preparation budget causes a terminal resource stop before entry evaluation. Product invocation awaits its 2.0 adapter.
The request describes a relation to a required reservation. It does not freeze a numeric tariff or a default limit.
2.11 Check a binding group before its children
Preparation follows the complete reading order. Normalization visits forms in source order. It checks a binding group when that traversal reaches the group. The shallow checks finish before any initializer or body in that group is normalized. Each required check reserves its event before inspecting syntax. A refused reservation stops before that inspection. An observed error stops before any later reservation. The event and check tables below fix this order. The reservation axis rule applies within each event.
Why
A complete group check gives each binding one static meaning. Local prechecks preserve the order of unrelated forms. Reservations bound the work needed to discover an error without moving a later event before that error.
| Event | Next operation | Order |
|---|---|---|
prepare.decode-step | Decode the next UTF-8 scalar or confirm source end | Complete the module before reading |
prepare.read-step | Inspect the next decoded scalar or confirm source end | Left to right with each scalar inspected once |
prepare.read-enter | Enter a list, vector, bytevector, quote, block comment, or datum comment | After its opening marker and before its contents |
prepare.read-node | Validate and construct a completed datum | Children before their containing datum |
prepare.normalize-node | Inspect the next source form | Source order with children after their parent checks |
prepare.binding-check | Inspect the group envelope or the next member check | Before that inspection |
prepare.binding-publish | Record a checked lexical binding | Member order after all group checks |
Reading completes before normalization starts. Reader lookahead reuses scalars already inspected and adds no second read event. A nested marker selects its enter event before any child event. A closing marker is read before its completed datum event. A block comment has enter events and scalar events but no datum node. A completed atomic token reserves its node event before token and numeric value checks. Its bytevector element checks finish before reading the next element. Datum comments retain every event of their discarded datum. Each event reserves all required axes before its effect. Reader enter events include required frame capacity. These events follow the grammar rather than implementation scanner loops. A comment or discarded datum still requires its reading events. The resource model names the requirements for each event. Its coefficients and finite defaults follow the cost model freeze.
| Check | Failure selection |
|---|---|
| Group envelope | Reject a malformed group before visiting a member |
| Member shape | Reject the first malformed binding or parameter |
| Identifier | Reject a binding position that is not an identifier |
| Duplicate | Reject a repeated name in the same binding scope |
| Recursive lambda head | Require the lambda head where recursive bindings require it |
Run these member checks from left to right. Skip the lambda check for a nonrecursive binding. Stop at the first failed check. Parameter lists include their rest parameter in the same duplicate check. A parallel let, named let, letrec, or recursive definition group checks all members before descending. Each let* binding forms its own nested group. Its initializer is normalized before the next binding group.
Publishing a binding records its identity. The lexical scope rules determine where that binding is visible. A parallel let initializer and a named let initializer retain their enclosing scope. All checks finish during preparation. They execute no guest initializer.
Find a duplicate before an initializer error
lispex.example.v2.source.group-before-initializer · ред. 2
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(let ((x (set! input 1)) (x 2)) x))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
binding.duplicateПодробности результата
{
"kind": "prepare-failure",
"stage": "normalization",
"valueCount": 0,
"binding": "x",
"check": "duplicate",
"initializerVisited": false,
"diagnostic": {
"phase": "normalize",
"code": "binding.duplicate",
"data": {
"name": "x",
"scope": "let"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
The duplicate x is rejected before normalization enters the first initializer. Product invocation awaits its 2.0 adapter.
The expected meaning is authored for Lispex 2.0. Product execution remains not-run.
Check every recursive initializer head first
lispex.example.v2.source.recursive-group-before-body · ред. 2
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(letrec ((f (lambda (x) (set! x 0))) (g 1)) f))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
binding.initializerПодробности результата
{
"kind": "prepare-failure",
"stage": "normalization",
"valueCount": 0,
"binding": "g",
"earlierLambdaBodyVisited": false,
"diagnostic": {
"phase": "normalize",
"code": "binding.initializer",
"data": {
"form": "letrec",
"name": "g",
"expected": "lambda"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
The initializer of g is rejected before normalization enters the body of f. Product invocation awaits its 2.0 adapter.
The expected meaning is authored for Lispex 2.0. Product execution remains not-run.
Keep an earlier form ahead of a later group
lispex.example.v2.source.earlier-form-before-group · ред. 2
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(begin (set! input 1) (let ((x 1) (x 2)) x)))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
binding.immutableПодробности результата
{
"kind": "prepare-failure",
"stage": "normalization",
"valueCount": 0,
"form": "set!",
"laterGroupInspected": false,
"diagnostic": {
"phase": "normalize",
"code": "binding.immutable",
"data": {
"name": "input"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
The earlier mutation form is rejected before the later binding group is inspected. Product invocation awaits its 2.0 adapter.
The expected meaning is authored for Lispex 2.0. Product execution remains not-run.
Reserve only the next required check
lispex.example.v2.source.precheck-reservation-order · ред. 3
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(let ((x (set! input 1)) (x 2)) x))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"reservationCases": [
{
"case": "refuse-required-duplicate-check",
"limits": "the work reservation for the second x duplicate check is refused"
},
{
"case": "permit-error-check-refuse-later-work",
"limits": "all group checks fit but the first initializer normalization would be refused"
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
resource.exhaustedПодробности результата
{
"case": "refuse-required-duplicate-check",
"kind": "resource-stop",
"stage": "normalization",
"axis": "work",
"event": "prepare.binding-check",
"check": "duplicate",
"binding": "x",
"duplicateObserved": false,
"eventCommitted": false,
"earlierChargesRetained": true,
"valueCount": 0,
"phase": "prepare",
"terminal": true,
"diagnostic": {
"phase": "prepare",
"code": "resource.exhausted",
"data": {
"stage": "normalize",
"axis": "work",
"event": "prepare.binding-check"
}
}
}binding.duplicateПодробности результата
{
"case": "permit-error-check-refuse-later-work",
"kind": "prepare-failure",
"stage": "normalization",
"binding": "x",
"laterReservationAttempted": false,
"valueCount": 0,
"diagnostic": {
"phase": "normalize",
"code": "binding.duplicate",
"data": {
"name": "x",
"scope": "let"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
A refused check stops before discovering the duplicate. A discovered duplicate prevents every later reservation. Product invocation awaits its 2.0 adapter.
The fixture selects symbolic reservation boundaries. It assigns no tariff coefficient or finite default.
Keep sequential bindings in separate scopes
lispex.example.v2.source.sequential-group-scopes · ред. 1
(module main
(import)
(export rule)
(entry rule)
(define rule (lambda (input)
(let* ((x 1) (x (+ x 1))) x))))
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient for the stated checks",
"evaluate": "finite values sufficient for the stated calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
2Подробности результата
{
"kind": "value",
"valueCount": 1,
"datum": {
"kind": "integer",
"value": "2"
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"bindingGroups": "distinct-nested-scopes"
}Вызов продукта
Ожидаемый результат
Each x belongs to a separate nested scope and the rule returns the exact integer 2. Product invocation awaits its 2.0 adapter.
The expected meaning is authored for Lispex 2.0. Product execution remains not-run.
2.12 Read the complete module before normalization
For one module, preparation decodes UTF-8 before reading syntax. Reading completes before normalization starts. A reader failure takes precedence over a normalization failure in that module. Normalization checks source forms in their written order.
Why
A fixed phase order makes the first failure reproducible. An earlier form with invalid meaning cannot hide a later reader failure in an unread part of the module.
Each module follows a fixed preparation order.
Finish reading before checking recursive bindings
lispex.example.v2.source.read-before-normalization-error · ред. 4
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(letrec ((x 1)) x)))
)
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
source.delimiterПодробности результата
{
"kind": "prepare-failure",
"stage": "reader",
"valueCount": 0,
"diagnostic": {
"phase": "read",
"code": "source.delimiter",
"data": {
"reason": "unexpected-close"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
The trailing closing parenthesis causes the reader failure before normalization can reject the recursive binding. Product invocation awaits its 2.0 adapter.
The first form is readable but its letrec initializer is not a lambda. The later reader failure takes precedence. The diagnostic catalog gives this failure its phase, code, and typed reason.
Check recursive forms in source order
lispex.example.v2.source.normalization-source-order · ред. 4
(module main
(import)
(export rule)
(entry rule)
(define rule
(lambda (input)
(begin
(letrec ((x 1)) x)
(letrec ((y 2)) y))))
)
Запрос и файлы
{
"notation": "documentation-request",
"source": "source.scm",
"semantics": {
"language": "Lispex 2.0",
"standardLibrary": "one fixed library identity",
"unicode": "one fixed Unicode semantics version",
"resourceModel": "one fixed finite resource model"
},
"limits": {
"prepare": "finite values sufficient to prepare this source",
"evaluate": "finite values sufficient for the stated finite calculation"
},
"requests": [
{
"input": {
"kind": "integer",
"value": "0"
}
}
],
"rootModule": "main",
"moduleSources": [
{
"name": "main",
"source": "source.scm"
}
]
}
binding.initializerПодробности результата
{
"kind": "prepare-failure",
"stage": "normalization",
"valueCount": 0,
"binding": "x",
"diagnostic": {
"phase": "normalize",
"code": "binding.initializer",
"data": {
"form": "letrec",
"name": "x",
"expected": "lambda"
}
}
}Результат по спецификации. Запуски продукта ожидают адаптера 2.0.
Подробности семантики
{
"entryEvaluated": false,
"canonicalOutcomeProduced": false,
"evaluationReceiptEligible": false
}Вызов продукта
Ожидаемый результат
Normalization rejects the initializer of x before it reaches the initializer of y. Product invocation awaits its 2.0 adapter.
Both forms violate the lambda requirement. The first form determines this failure. Finite preparation limits are sufficient to reach the stated checks.