TOML
Canonical source:
protos/lib/toml/TOML.protosat locked revisione99b712ecf658a527b1fe82c8beba2c1286d8dc9.
// THE LICENSED WORK IS PROVIDED UNDER THE TERMS OF THE ADAPTIVE PUBLIC LICENSE// ("LICENSE") AS FIRST COMPLETED BY: Guillermo Adriรกn Molina. ANY USE, PUBLIC// DISPLAY, PUBLIC PERFORMANCE, REPRODUCTION OR DISTRIBUTION OF, OR PREPARATION OF// DERIVATIVE WORKS BASED ON, THE LICENSED WORK CONSTITUTES RECIPIENT'S ACCEPTANCE// OF THIS LICENSE AND ITS TERMS, WHETHER OR NOT SUCH RECIPIENT READS THE TERMS OF// THE LICENSE. "LICENSED WORK" AND "RECIPIENT" ARE DEFINED IN THE LICENSE. A COPY// OF THE LICENSE IS LOCATED IN THE TEXT FILE ENTITLED "LICENSE.TXT" ACCOMPANYING// THE CONTENTS OF THIS FILE. IF A COPY OF THE LICENSE DOES NOT ACCOMPANY THIS// FILE, A COPY OF THE LICENSE MAY ALSO BE OBTAINED AT THE FOLLOWING WEB SITE:// https://github.com/guillermomolina/protos//// Software distributed under the License is distributed on an "AS IS" basis,// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for// the specific language governing rights and limitations under the License.
//! TOML node trees and whole-document parsing and encoding. Nodes are objects with//! `kind` and `value` slots.
/// Answers a fresh TOML string node; `value` must be a String.string: (value) => { String.recognizes(value).ifFalse(() => { Error().signal() })
{ kind: "string" value: value }}
/// Answers a fresh TOML integer node; `value` must be an Integer.integer: (value) => { Integer.recognizes(value).ifFalse(() => { Error().signal() })
{ kind: "integer" value: value }}
/// Answers a fresh TOML float node; `value` must be a Float.float: (value) => { Float.recognizes(value).ifFalse(() => { Error().signal() })
{ kind: "float" value: value }}
/// Answers a fresh TOML boolean node; `value` must be canonical `true` or `false`.boolean: (value) => { valid: value === true (value === false).ifTrue(() => { valid = true }) valid.ifFalse(() => { Error().signal() })
{ kind: "boolean" value: value }}
/// Answers a fresh TOML local-date node. Validates the year (1..9999), month, and day/// against the proleptic Gregorian calendar.localDate: (year, month, day) => { ignoredYearValidation: 0 + year ignoredMonthValidation: 0 + month ignoredDayValidation: 0 + day
((year < 1) || (year > 9999)).ifTrue(() => { Error().signal() }) ((month < 1) || (month > 12)).ifTrue(() => { Error().signal() })
maxDay: 31 ((month == 4) || (month == 6) || (month == 9) || (month == 11)).ifTrue(() => { maxDay = 30 }) (month == 2).ifTrue(() => { leap: false (year.mod(4) == 0).ifTrue(() => { leap = true }) (year.mod(100) == 0).ifTrue(() => { leap = false }) (year.mod(400) == 0).ifTrue(() => { leap = true }) maxDay = 28 leap.ifTrue(() => { maxDay = 29 }) })
((day < 1) || (day > maxDay)).ifTrue(() => { Error().signal() })
date: { year: year month: month day: day }
{ kind: "localDate" value: date }}
/// Answers a fresh TOML local-time node. Validates hour (0..23), minute (0..59), and/// second (0..60); the fraction is `fractionCoefficient` over `fractionDigits` decimal/// digits.localTime: (hour, minute, second, fractionCoefficient, fractionDigits) => { ignoredHourValidation: 0 + hour ignoredMinuteValidation: 0 + minute ignoredSecondValidation: 0 + second ignoredFractionCoefficientValidation: 0 + fractionCoefficient ignoredFractionDigitsValidation: 0 + fractionDigits
((hour < 0) || (hour > 23)).ifTrue(() => { Error().signal() }) ((minute < 0) || (minute > 59)).ifTrue(() => { Error().signal() }) ((second < 0) || (second > 60)).ifTrue(() => { Error().signal() }) (fractionCoefficient < 0).ifTrue(() => { Error().signal() }) (fractionDigits < 0).ifTrue(() => { Error().signal() })
(fractionDigits == 0).ifTrue(() => { (fractionCoefficient != 0).ifTrue(() => { Error().signal() }) }) (fractionDigits > 0).ifTrue(() => { limit: 1 index: 0 (() => index < fractionDigits).whileTrue(() => { limit = limit * 10 index = index + 1 }) (fractionCoefficient >= limit).ifTrue(() => { Error().signal() }) })
fraction: { coefficient: fractionCoefficient digits: fractionDigits } time: { hour: hour minute: minute second: second fraction: fraction }
{ kind: "localTime" value: time }}
/// Answers a fresh TOML local-date-time node./// Validates the year (1..9999), month, and day against the proleptic Gregorian/// calendar./// Validates hour (0..23), minute (0..59), and second (0..60); the fraction is/// `fractionCoefficient` over `fractionDigits` decimal digits.localDateTime: ( year, month, day, hour, minute, second, fractionCoefficient, fractionDigits) => { ignoredYearValidation: 0 + year ignoredMonthValidation: 0 + month ignoredDayValidation: 0 + day ignoredHourValidation: 0 + hour ignoredMinuteValidation: 0 + minute ignoredSecondValidation: 0 + second ignoredFractionCoefficientValidation: 0 + fractionCoefficient ignoredFractionDigitsValidation: 0 + fractionDigits
((year < 1) || (year > 9999)).ifTrue(() => { Error().signal() }) ((month < 1) || (month > 12)).ifTrue(() => { Error().signal() })
maxDay: 31 ((month == 4) || (month == 6) || (month == 9) || (month == 11)).ifTrue(() => { maxDay = 30 }) (month == 2).ifTrue(() => { leap: false (year.mod(4) == 0).ifTrue(() => { leap = true }) (year.mod(100) == 0).ifTrue(() => { leap = false }) (year.mod(400) == 0).ifTrue(() => { leap = true }) maxDay = 28 leap.ifTrue(() => { maxDay = 29 }) }) ((day < 1) || (day > maxDay)).ifTrue(() => { Error().signal() })
((hour < 0) || (hour > 23)).ifTrue(() => { Error().signal() }) ((minute < 0) || (minute > 59)).ifTrue(() => { Error().signal() }) ((second < 0) || (second > 60)).ifTrue(() => { Error().signal() }) (fractionCoefficient < 0).ifTrue(() => { Error().signal() }) (fractionDigits < 0).ifTrue(() => { Error().signal() })
(fractionDigits == 0).ifTrue(() => { (fractionCoefficient != 0).ifTrue(() => { Error().signal() }) }) (fractionDigits > 0).ifTrue(() => { limit: 1 index: 0 (() => index < fractionDigits).whileTrue(() => { limit = limit * 10 index = index + 1 }) (fractionCoefficient >= limit).ifTrue(() => { Error().signal() }) })
fraction: { coefficient: fractionCoefficient digits: fractionDigits } dateTime: { year: year month: month day: day hour: hour minute: minute second: second fraction: fraction }
{ kind: "localDateTime" value: dateTime }}
/// Answers a fresh TOML offset-date-time node./// Validates the year (1..9999), month, and day against the proleptic Gregorian/// calendar./// Validates hour (0..23), minute (0..59), and second (0..60); the fraction is/// `fractionCoefficient` over `fractionDigits` decimal digits./// `offsetMinutes` must lie in -1439..1439.offsetDateTime: ( year, month, day, hour, minute, second, fractionCoefficient, fractionDigits, offsetMinutes) => { ignoredYearValidation: 0 + year ignoredMonthValidation: 0 + month ignoredDayValidation: 0 + day ignoredHourValidation: 0 + hour ignoredMinuteValidation: 0 + minute ignoredSecondValidation: 0 + second ignoredFractionCoefficientValidation: 0 + fractionCoefficient ignoredFractionDigitsValidation: 0 + fractionDigits ignoredOffsetValidation: 0 + offsetMinutes
((year < 1) || (year > 9999)).ifTrue(() => { Error().signal() }) ((month < 1) || (month > 12)).ifTrue(() => { Error().signal() })
maxDay: 31 ((month == 4) || (month == 6) || (month == 9) || (month == 11)).ifTrue(() => { maxDay = 30 }) (month == 2).ifTrue(() => { leap: false (year.mod(4) == 0).ifTrue(() => { leap = true }) (year.mod(100) == 0).ifTrue(() => { leap = false }) (year.mod(400) == 0).ifTrue(() => { leap = true }) maxDay = 28 leap.ifTrue(() => { maxDay = 29 }) }) ((day < 1) || (day > maxDay)).ifTrue(() => { Error().signal() })
((hour < 0) || (hour > 23)).ifTrue(() => { Error().signal() }) ((minute < 0) || (minute > 59)).ifTrue(() => { Error().signal() }) ((second < 0) || (second > 60)).ifTrue(() => { Error().signal() }) (fractionCoefficient < 0).ifTrue(() => { Error().signal() }) (fractionDigits < 0).ifTrue(() => { Error().signal() })
(fractionDigits == 0).ifTrue(() => { (fractionCoefficient != 0).ifTrue(() => { Error().signal() }) }) (fractionDigits > 0).ifTrue(() => { limit: 1 index: 0 (() => index < fractionDigits).whileTrue(() => { limit = limit * 10 index = index + 1 }) (fractionCoefficient >= limit).ifTrue(() => { Error().signal() }) })
((offsetMinutes < -1439) || (offsetMinutes > 1439)).ifTrue(() => { Error().signal() })
fraction: { coefficient: fractionCoefficient digits: fractionDigits } dateTime: { year: year month: month day: day hour: hour minute: minute second: second fraction: fraction offsetMinutes: offsetMinutes }
{ kind: "offsetDateTime" value: dateTime }}
/// Answers a fresh TOML array node whose elements are `nodes`, in order./// Each element must be a TOML node: this constructor checks only each element's/// immediate envelope, namely that its `kind` names one of the ten TOML semantic/// kinds and that it carries a `value`; otherwise it signals an Error./// Success does not establish that an arbitrarily constructed tree is recursively/// valid TOML; `TOML.encode` rejects any tree that cannot be validly encoded.array: (...nodes) => { validateNode: (node) => { kind: node.kind valid: kind === "string" (kind === "integer").ifTrue(() => { valid = true }) (kind === "float").ifTrue(() => { valid = true }) (kind === "boolean").ifTrue(() => { valid = true }) (kind === "offsetDateTime").ifTrue(() => { valid = true }) (kind === "localDateTime").ifTrue(() => { valid = true }) (kind === "localDate").ifTrue(() => { valid = true }) (kind === "localTime").ifTrue(() => { valid = true }) (kind === "array").ifTrue(() => { valid = true }) (kind === "table").ifTrue(() => { valid = true }) valid.ifFalse(() => { Error().signal() }) ignoredValue: node.value }
nodes.each((node) => { validateNode(node) })
{ kind: "array" value: nodes }}
/// Answers a fresh TOML table node from alternating `name, node` arguments, in/// order. Each name must be a String, names must not repeat, and every name must/// be followed by its node; otherwise it signals an Error./// Each node is checked only for its immediate envelope, namely that its `kind`/// names one of the ten TOML semantic kinds and that it carries a `value`./// Success does not establish that arbitrarily constructed descendants are/// recursively valid TOML; `TOML.encode` retains full encodability validation.table: (...nameNodePairs) => { validateNode: (node) => { kind: node.kind valid: kind === "string" (kind === "integer").ifTrue(() => { valid = true }) (kind === "float").ifTrue(() => { valid = true }) (kind === "boolean").ifTrue(() => { valid = true }) (kind === "offsetDateTime").ifTrue(() => { valid = true }) (kind === "localDateTime").ifTrue(() => { valid = true }) (kind === "localDate").ifTrue(() => { valid = true }) (kind === "localTime").ifTrue(() => { valid = true }) (kind === "array").ifTrue(() => { valid = true }) (kind === "table").ifTrue(() => { valid = true }) valid.ifFalse(() => { Error().signal() }) ignoredValue: node.value }
result: Map() pendingName: null expectingName: true
nameNodePairs.each((entry) => { wasExpectingName: expectingName
wasExpectingName.ifTrue(() => { String.recognizes(entry).ifFalse(() => { Error().signal() }) pendingName = entry expectingName = false })
wasExpectingName.ifFalse(() => { validateNode(entry) result.containsKey(pendingName).ifTrue(() => { Error().signal() }) result[pendingName] = entry pendingName = null expectingName = true }) })
expectingName.ifFalse(() => { Error().signal() })
{ kind: "table" value: result }}
/// Encodes the table node `rootTable` as TOML document text; a root that is not/// a table node or a tree that cannot be encoded signals an Error.encode: (rootTable) => { output: Encoding.UTF8.encode("")
emitText: (text) => { String.recognizes(text).ifFalse(() => { Error().signal() }) Encoding.UTF8.encode(text).each((octet) => { output.add(octet) }) }
emitHexNibble: (digit) => { (digit < 10).ifTrue(() => { output.add(48 + digit) }) (digit >= 10).ifTrue(() => { output.add(55 + digit) }) }
emitBasicString: (text) => { String.recognizes(text).ifFalse(() => { Error().signal() })
output.add(34) Encoding.UTF8.encode(text).each((octet) => { handled: false
(octet == 34).ifTrue(() => { output.add(92) output.add(34) handled = true }) (octet == 92).ifTrue(() => { output.add(92) output.add(92) handled = true })
handled.ifFalse(() => { control: octet < 32 (octet == 127).ifTrue(() => { control = true }) control.ifTrue(() => { output.add(92) output.add(117) output.add(48) output.add(48) emitHexNibble(octet.div(16)) emitHexNibble(octet.mod(16)) handled = true }) })
handled.ifFalse(() => { output.add(octet) }) }) output.add(34) }
integerText: (value) => { Integer.recognizes(value).ifFalse(() => { Error().signal() })
negative: value < 0 magnitude: value negative.ifTrue(() => { magnitude = 0 - value })
reversed: Encoding.UTF8.encode("") (magnitude == 0).ifTrue(() => { reversed.add(48) }) (() => magnitude > 0).whileTrue(() => { reversed.add(48 + magnitude.mod(10)) magnitude = magnitude.div(10) })
result: Encoding.UTF8.encode("") negative.ifTrue(() => { result.add(45) })
index: reversed.size() - 1 (() => index >= 0).whileTrue(() => { result.add(reversed[index]) index = index - 1 })
Encoding.UTF8.decode(result) }
repeatZero: (count) => { result: "" remaining: count (() => remaining > 0).whileTrue(() => { result = result + "0" remaining = remaining - 1 }) result }
powerInteger: (base, exponent) => { (exponent < 0).ifTrue(() => { fail() })
result: 1 factor: base remaining: exponent
(() => remaining > 0).whileTrue(() => { (remaining.mod(2) == 1).ifTrue(() => { result = result * factor }) remaining = remaining.div(2) (remaining > 0).ifTrue(() => { factor = factor * factor }) })
result }
absoluteInteger: (value) => { result: value (result < 0).ifTrue(() => { result = 0 - result }) result }
decimalToken: (coefficient, decimalExponent) => { digits: integerText(coefficient) digitCount: digits.size()
fixed: "" (decimalExponent >= 0).ifTrue(() => { fixed = digits + repeatZero(decimalExponent) + ".0" })
(decimalExponent < 0).ifTrue(() => { point: digitCount + decimalExponent
(point <= 0).ifTrue(() => { fixed = "0." + repeatZero(0 - point) + digits })
(point > 0).ifTrue(() => { result: "" index: 0 (() => index < digitCount).whileTrue(() => { (index == point).ifTrue(() => { result = result + "." }) result = result + digits[index] index = index + 1 }) fixed = result }) })
scientificExponent: decimalExponent + digitCount - 1 scientific: digits[0]
(digitCount > 1).ifTrue(() => { scientific = scientific + "." index: 1 (() => index < digitCount).whileTrue(() => { scientific = scientific + digits[index] index = index + 1 }) })
scientific = scientific + "e" + integerText(scientificExponent)
result: fixed (scientific.size() < fixed.size()).ifTrue(() => { result = scientific }) result }
floatText: (value) => { Float.recognizes(value).ifFalse(() => { Error().signal() })
positiveInfinity: 1.0 / 0.0 negativeInfinity: 0.0 - positiveInfinity
result: null handled: false
(value == value).ifFalse(() => { result = "nan" handled = true })
handled.ifFalse(() => { (value == positiveInfinity).ifTrue(() => { result = "inf" handled = true }) })
handled.ifFalse(() => { (value == negativeInfinity).ifTrue(() => { result = "-inf" handled = true }) })
handled.ifFalse(() => { (value == 0.0).ifTrue(() => { result = "0.0" ((1.0 / value) == negativeInfinity).ifTrue(() => { result = "-0.0" }) handled = true }) })
handled.ifFalse(() => { negative: value < 0.0 magnitude: value negative.ifTrue(() => { magnitude = 0.0 - value })
normalized: magnitude binaryExponent: 0
(() => normalized >= 2.0).whileTrue(() => { normalized = normalized / 2.0 binaryExponent = binaryExponent + 1 })
(() => normalized < 1.0).whileTrue(() => { normalized = normalized * 2.0 binaryExponent = binaryExponent - 1 })
significand: Integer(normalized * 4503599627370496.0) binaryShift: binaryExponent - 52
numerator: significand denominator: 1
(binaryShift >= 0).ifTrue(() => { numerator = numerator * powerInteger(2, binaryShift) })
(binaryShift < 0).ifTrue(() => { denominator = powerInteger(2, 0 - binaryShift) })
decimalExponent: 0
(numerator >= denominator).ifTrue(() => { threshold: denominator * 10 (() => numerator >= threshold).whileTrue(() => { decimalExponent = decimalExponent + 1 threshold = threshold * 10 }) })
(numerator < denominator).ifTrue(() => { decimalExponent = -1 scaledNumerator: numerator * 10 (() => scaledNumerator < denominator).whileTrue(() => { decimalExponent = decimalExponent - 1 scaledNumerator = scaledNumerator * 10 }) })
coefficient: null coefficientExponent: 0 significantDigits: 1
(() => (coefficient === null) && (significantDigits <= 17)).whileTrue(() => { candidateExponent: decimalExponent - significantDigits + 1 scaledNumerator: numerator scaledDenominator: denominator
(candidateExponent >= 0).ifTrue(() => { scaledDenominator = scaledDenominator * powerInteger(10, candidateExponent) })
(candidateExponent < 0).ifTrue(() => { scaledNumerator = scaledNumerator * powerInteger(10, 0 - candidateExponent) })
quotient: scaledNumerator.div(scaledDenominator) remainder: scaledNumerator.mod(scaledDenominator) rounded: quotient twiceRemainder: remainder * 2
(twiceRemainder > scaledDenominator).ifTrue(() => { rounded = rounded + 1 })
(twiceRemainder == scaledDenominator).ifTrue(() => { (rounded.mod(2) == 1).ifTrue(() => { rounded = rounded + 1 }) })
bestCandidate: null bestDistance: null
roundTrips: (candidate) => { candidateFloat: null
(candidateExponent >= 0).ifTrue(() => { candidateFloat = Float(candidate * powerInteger(10, candidateExponent)) })
(candidateExponent < 0).ifTrue(() => { candidateFloat = candidate / powerInteger(10, 0 - candidateExponent) })
candidateFloat == magnitude }
consider: (candidate) => { (candidate > 0).ifTrue(() => { roundTrips(candidate).ifTrue(() => { distance: absoluteInteger( scaledNumerator - candidate * scaledDenominator )
better: bestCandidate === null
(bestCandidate === null).ifFalse(() => { (distance < bestDistance).ifTrue(() => { better = true })
(distance == bestDistance).ifTrue(() => { candidateEven: candidate.mod(2) == 0 bestOdd: bestCandidate.mod(2) == 1 (candidateEven && bestOdd).ifTrue(() => { better = true }) }) })
better.ifTrue(() => { bestCandidate = candidate bestDistance = distance }) }) }) }
consider(rounded) consider(rounded - 1) consider(rounded + 1)
(bestCandidate === null).ifFalse(() => { coefficient = bestCandidate coefficientExponent = candidateExponent })
significantDigits = significantDigits + 1 })
(coefficient === null).ifTrue(() => { fail() })
(() => coefficient.mod(10) == 0).whileTrue(() => { coefficient = coefficient.div(10) coefficientExponent = coefficientExponent + 1 })
result = decimalToken(coefficient, coefficientExponent) negative.ifTrue(() => { result = "-" + result }) })
result }
paddedIntegerText: (value, width) => { text: integerText(value) result: text (() => result.size() < width).whileTrue(() => { result = "0" + result }) result }
fractionText: (fraction) => { coefficient: fraction.coefficient digits: fraction.digits
Integer.recognizes(coefficient).ifFalse(() => { Error().signal() }) Integer.recognizes(digits).ifFalse(() => { Error().signal() })
result: "" (digits > 0).ifTrue(() => { raw: Encoding.UTF8.encode(integerText(coefficient)) buffer: Encoding.UTF8.encode(".") padding: digits - raw.size() (() => padding > 0).whileTrue(() => { buffer.add(48) padding = padding - 1 }) raw.each((octet) => { buffer.add(octet) }) result = Encoding.UTF8.decode(buffer) }) result }
dateText: (value) => { ignoredValidation: localDate(value.year, value.month, value.day) paddedIntegerText(value.year, 4) + "-" + paddedIntegerText(value.month, 2) + "-" + paddedIntegerText(value.day, 2) }
timeText: (value) => { ignoredValidation: localTime( value.hour, value.minute, value.second, value.fraction.coefficient, value.fraction.digits )
paddedIntegerText(value.hour, 2) + ":" + paddedIntegerText(value.minute, 2) + ":" + paddedIntegerText(value.second, 2) + fractionText(value.fraction) }
localDateTimeText: (value) => { ignoredValidation: localDateTime( value.year, value.month, value.day, value.hour, value.minute, value.second, value.fraction.coefficient, value.fraction.digits )
datePart: { year: value.year month: value.month day: value.day }
timePart: { hour: value.hour minute: value.minute second: value.second fraction: value.fraction }
dateText(datePart) + "T" + timeText(timePart) }
offsetDateTimeText: (value) => { ignoredValidation: offsetDateTime( value.year, value.month, value.day, value.hour, value.minute, value.second, value.fraction.coefficient, value.fraction.digits, value.offsetMinutes )
datePart: { year: value.year month: value.month day: value.day }
timePart: { hour: value.hour minute: value.minute second: value.second fraction: value.fraction }
offsetText: "Z" (value.offsetMinutes == 0).ifFalse(() => { sign: "+" magnitude: value.offsetMinutes (magnitude < 0).ifTrue(() => { sign = "-" magnitude = 0 - magnitude })
offsetText = sign + paddedIntegerText(magnitude.div(60), 2) + ":" + paddedIntegerText(magnitude.mod(60), 2) })
dateText(datePart) + "T" + timeText(timePart) + offsetText }
active: IdentityMap() topFrame: null
snapshotTableEntries: (tableValue) => { entries: Map() count: 0
tableValue.each((name, child) => { String.recognizes(name).ifFalse(() => { Error().signal() }) entries[count] = { name: name child: child } count = count + 1 })
{ entries: entries count: count } }
pushValue: (node, parentFrame) => { kind: node.kind value: node.value handled: false
(kind === "string").ifTrue(() => { ignoredValidation: string(value) emitBasicString(value) handled = true })
(kind === "integer").ifTrue(() => { ignoredValidation: integer(value) emitText(integerText(value)) handled = true })
(kind === "float").ifTrue(() => { ignoredValidation: float(value) emitText(floatText(value)) handled = true })
(kind === "boolean").ifTrue(() => { ignoredValidation: boolean(value) (value === true).ifTrue(() => { emitText("true") }) (value === false).ifTrue(() => { emitText("false") }) handled = true })
(kind === "localDate").ifTrue(() => { emitText(dateText(value)) handled = true })
(kind === "localTime").ifTrue(() => { emitText(timeText(value)) handled = true })
(kind === "localDateTime").ifTrue(() => { emitText(localDateTimeText(value)) handled = true })
(kind === "offsetDateTime").ifTrue(() => { emitText(offsetDateTimeText(value)) handled = true })
(kind === "array").ifTrue(() => { active.containsKey(node).ifTrue(() => { fail() }) active[node] = true
output.add(91) topFrame = { frameKind: "array" parent: parentFrame node: node values: value count: value.size() index: 0 } handled = true })
(kind === "table").ifTrue(() => { active.containsKey(node).ifTrue(() => { fail() }) active[node] = true
snapshot: snapshotTableEntries(value) output.add(123) topFrame = { frameKind: "table" parent: parentFrame node: node entries: snapshot.entries count: snapshot.count index: 0 } handled = true })
handled.ifFalse(() => { fail() }) }
(rootTable.kind === "table").ifFalse(() => { fail() })
rootSnapshot: snapshotTableEntries(rootTable.value) active[rootTable] = true topFrame = { frameKind: "root" parent: null node: rootTable entries: rootSnapshot.entries count: rootSnapshot.count index: 0 }
running: true (() => running).whileTrue(() => { frame: topFrame frameKind: frame.frameKind
(frameKind == "root").ifTrue(() => { (frame.index >= frame.count).ifTrue(() => { (frame.count > 0).ifTrue(() => { output.add(10) }) active.remove(frame.node) running = false })
(frame.index < frame.count).ifTrue(() => { (frame.index > 0).ifTrue(() => { output.add(10) })
entry: frame.entries[frame.index] frame.index = frame.index + 1
emitBasicString(entry.name) emitText(" = ") pushValue(entry.child, frame) }) })
(frameKind == "array").ifTrue(() => { (frame.index >= frame.count).ifTrue(() => { output.add(93) active.remove(frame.node) topFrame = frame.parent })
(frame.index < frame.count).ifTrue(() => { (frame.index > 0).ifTrue(() => { emitText(", ") })
child: frame.values[frame.index] frame.index = frame.index + 1 pushValue(child, frame) }) })
(frameKind == "table").ifTrue(() => { (frame.index >= frame.count).ifTrue(() => { output.add(125) active.remove(frame.node) topFrame = frame.parent })
(frame.index < frame.count).ifTrue(() => { (frame.index > 0).ifTrue(() => { emitText(", ") })
entry: frame.entries[frame.index] frame.index = frame.index + 1
emitBasicString(entry.name) emitText(" = ") pushValue(entry.child, frame) }) }) })
Encoding.UTF8.decode(output)}
/// Parses one complete TOML document into its root table node using the TOML/// specification version named by `version`, either `"1.0"` or `"1.1"`; any other/// `version` or invalid text signals an Error. Both versions share one parser: TOML/// 1.0 additionally rejects the `\e` and `\xHH` escapes, inline tables that span/// lines or end with a trailing comma, and times without seconds.parseDialect: (text, version) => { String.recognizes(text).ifFalse(() => { Error().signal() }) String.recognizes(version).ifFalse(() => { Error().signal() }) toml11: version == "1.1" (toml11 || (version == "1.0")).ifFalse(() => { Error().signal() })
publicLocalDate: localDate publicLocalTime: localTime publicLocalDateTime: localDateTime publicOffsetDateTime: offsetDateTime
syntaxNode: (kind, value) => { result: { kind: kind value: value } result }
syntaxKeyPath: (text) => { String.recognizes(text).ifFalse(() => { Error().signal() }) source: Encoding.UTF8.encode(text) index: 0 length: source.size()
peek: () => { result: -1 (index < length).ifTrue(() => { result = source[index] }) result }
take: () => { (index >= length).ifTrue(() => { fail() }) result: source[index] index = index + 1 result }
skipSpaces: () => { scanning: true (() => scanning && (index < length)).whileTrue(() => { octet: source[index] whitespace: octet == 32 (octet == 9).ifTrue(() => { whitespace = true }) whitespace.ifTrue(() => { index = index + 1 }) whitespace.ifFalse(() => { scanning = false }) }) }
hexDigit: (octet) => { result: -1 (octet >= 48).ifTrue(() => { (octet <= 57).ifTrue(() => { result = octet - 48 }) }) (result < 0).ifTrue(() => { (octet >= 65).ifTrue(() => { (octet <= 70).ifTrue(() => { result = octet - 55 }) }) }) (result < 0).ifTrue(() => { (octet >= 97).ifTrue(() => { (octet <= 102).ifTrue(() => { result = octet - 87 }) }) }) result }
appendScalarUtf8: (buffer, scalar) => { invalid: scalar < 0 (scalar > 1114111).ifTrue(() => { invalid = true }) (scalar >= 55296).ifTrue(() => { (scalar <= 57343).ifTrue(() => { invalid = true }) }) invalid.ifTrue(() => { fail() })
handled: false (scalar <= 127).ifTrue(() => { buffer.add(scalar) handled = true }) handled.ifFalse(() => { (scalar <= 2047).ifTrue(() => { buffer.add(192 + scalar.div(64)) buffer.add(128 + scalar.mod(64)) handled = true }) }) handled.ifFalse(() => { (scalar <= 65535).ifTrue(() => { buffer.add(224 + scalar.div(4096)) buffer.add(128 + scalar.div(64).mod(64)) buffer.add(128 + scalar.mod(64)) handled = true }) }) handled.ifFalse(() => { buffer.add(240 + scalar.div(262144)) buffer.add(128 + scalar.div(4096).mod(64)) buffer.add(128 + scalar.div(64).mod(64)) buffer.add(128 + scalar.mod(64)) }) }
parseUnicodeEscape: (digits, buffer) => { scalar: 0 remaining: digits
consume: null consume = () => { (remaining > 0).ifTrue(() => { digit: hexDigit(take()) (digit < 0).ifTrue(() => { fail() }) scalar = scalar * 16 + digit remaining = remaining - 1 consume() }) }
consume() appendScalarUtf8(buffer, scalar) }
parseBasicKey: () => { (take() == 34).ifFalse(() => { fail() }) buffer: Encoding.UTF8.encode("") done: false
(() => done === false).whileTrue(() => { octet: take() (octet == 34).ifTrue(() => { done = true })
done.ifFalse(() => { (octet == 92).ifTrue(() => { escape: take() handled: false (escape == 98).ifTrue(() => { buffer.add(8) handled = true }) (escape == 116).ifTrue(() => { buffer.add(9) handled = true }) (escape == 110).ifTrue(() => { buffer.add(10) handled = true }) (escape == 102).ifTrue(() => { buffer.add(12) handled = true }) (escape == 114).ifTrue(() => { buffer.add(13) handled = true }) (toml11 && (escape == 101)).ifTrue(() => { buffer.add(27) handled = true }) (toml11 && (escape == 120)).ifTrue(() => { parseUnicodeEscape(2, buffer) handled = true }) (escape == 34).ifTrue(() => { buffer.add(34) handled = true }) (escape == 92).ifTrue(() => { buffer.add(92) handled = true }) (escape == 117).ifTrue(() => { parseUnicodeEscape(4, buffer) handled = true }) (escape == 85).ifTrue(() => { parseUnicodeEscape(8, buffer) handled = true }) handled.ifFalse(() => { fail() }) })
(octet == 92).ifFalse(() => { invalidControl: octet < 32 (octet == 127).ifTrue(() => { invalidControl = true }) (octet == 9).ifTrue(() => { invalidControl = false }) invalidControl.ifTrue(() => { fail() }) buffer.add(octet) }) }) }) Encoding.UTF8.decode(buffer) }
parseLiteralKey: () => { (take() == 39).ifFalse(() => { fail() }) buffer: Encoding.UTF8.encode("") done: false
(() => done === false).whileTrue(() => { octet: take() (octet == 39).ifTrue(() => { done = true }) done.ifFalse(() => { invalidControl: octet < 32 (octet == 127).ifTrue(() => { invalidControl = true }) (octet == 9).ifTrue(() => { invalidControl = false }) invalidControl.ifTrue(() => { fail() }) buffer.add(octet) }) }) Encoding.UTF8.decode(buffer) }
isBareKeyOctet: (octet) => { result: false (octet >= 48).ifTrue(() => { (octet <= 57).ifTrue(() => { result = true }) }) (octet >= 65).ifTrue(() => { (octet <= 90).ifTrue(() => { result = true }) }) (octet >= 97).ifTrue(() => { (octet <= 122).ifTrue(() => { result = true }) }) (octet == 95).ifTrue(() => { result = true }) (octet == 45).ifTrue(() => { result = true }) result }
parseBareKey: () => { buffer: Encoding.UTF8.encode("") scanning: true
(() => scanning && (index < length)).whileTrue(() => { octet: source[index] validBare: isBareKeyOctet(octet) validBare.ifTrue(() => { buffer.add(octet) index = index + 1 }) validBare.ifFalse(() => { scanning = false }) })
(buffer.size() == 0).ifTrue(() => { fail() }) Encoding.UTF8.decode(buffer) }
parsePart: () => { skipSpaces() first: peek() result: null
(first == 34).ifTrue(() => { result = parseBasicKey() }) (first == 39).ifTrue(() => { result = parseLiteralKey() }) (first == 34).ifFalse(() => { (first == 39).ifFalse(() => { result = parseBareKey() }) })
result }
pathEntries: Map() pathCount: 0
appendPathPart: (part) => { pathEntries[pathCount] = part pathCount = pathCount + 1 }
appendPathPart(parsePart()) more: true
(() => more).whileTrue(() => { skipSpaces()
(index < length).ifTrue(() => { (source[index] == 46).ifFalse(() => { fail() }) index = index + 1 appendPathPart(parsePart()) })
(index >= length).ifTrue(() => { more = false }) })
skipSpaces() (index == length).ifFalse(() => { fail() })
{ entries: pathEntries count: pathCount } }
syntaxValue: (text) => { String.recognizes(text).ifFalse(() => { Error().signal() }) source: Encoding.UTF8.encode(text) index: 0 length: source.size()
peek: () => { result: -1 (index < length).ifTrue(() => { result = source[index] }) result }
take: () => { (index >= length).ifTrue(() => { fail() }) result: source[index] index = index + 1 result }
isSpace: (octet) => { result: octet == 32 (octet == 9).ifTrue(() => { result = true }) result }
isNewlineStart: (octet) => { result: octet == 10 (octet == 13).ifTrue(() => { result = true }) result }
consumeNewline: () => { octet: take() valid: octet == 10 (octet == 13).ifTrue(() => { valid = true (peek() == 10).ifFalse(() => { fail() }) take() }) valid.ifFalse(() => { fail() }) }
skipSpaces: () => { scanning: true (() => scanning && (index < length)).whileTrue(() => { whitespace: isSpace(source[index]) whitespace.ifTrue(() => { index = index + 1 }) whitespace.ifFalse(() => { scanning = false }) }) }
skipComment: () => { scanning: true (() => scanning && (index < length)).whileTrue(() => { octet: source[index] newline: isNewlineStart(octet) newline.ifTrue(() => { scanning = false }) newline.ifFalse(() => { invalidControl: octet < 32 (octet == 127).ifTrue(() => { invalidControl = true }) (octet == 9).ifTrue(() => { invalidControl = false }) invalidControl.ifTrue(() => { fail() }) index = index + 1 }) }) }
skipArrayTrivia: () => { progressed: true (() => progressed).whileTrue(() => { progressed = false (index < length).ifTrue(() => { octet: source[index] isSpace(octet).ifTrue(() => { index = index + 1 progressed = true }) isNewlineStart(octet).ifTrue(() => { consumeNewline() progressed = true }) (octet == 35).ifTrue(() => { index = index + 1 skipComment() progressed = true }) }) }) }
// TOML 1.0 inline tables are single-line, so only spaces and tabs may // separate their tokens; TOML 1.1 also admits newlines and comments. skipInlineTableTrivia: () => { toml11.ifTrue(() => { skipArrayTrivia() }) toml11.ifFalse(() => { skipSpaces() }) }
hexDigit: (octet) => { result: -1 (octet >= 48).ifTrue(() => { (octet <= 57).ifTrue(() => { result = octet - 48 }) }) (result < 0).ifTrue(() => { (octet >= 65).ifTrue(() => { (octet <= 70).ifTrue(() => { result = octet - 55 }) }) }) (result < 0).ifTrue(() => { (octet >= 97).ifTrue(() => { (octet <= 102).ifTrue(() => { result = octet - 87 }) }) }) result }
appendScalarUtf8: (buffer, scalar) => { invalid: scalar < 0 (scalar > 1114111).ifTrue(() => { invalid = true }) (scalar >= 55296).ifTrue(() => { (scalar <= 57343).ifTrue(() => { invalid = true }) }) invalid.ifTrue(() => { fail() })
handled: false (scalar <= 127).ifTrue(() => { buffer.add(scalar) handled = true }) handled.ifFalse(() => { (scalar <= 2047).ifTrue(() => { buffer.add(192 + scalar.div(64)) buffer.add(128 + scalar.mod(64)) handled = true }) }) handled.ifFalse(() => { (scalar <= 65535).ifTrue(() => { buffer.add(224 + scalar.div(4096)) buffer.add(128 + scalar.div(64).mod(64)) buffer.add(128 + scalar.mod(64)) handled = true }) }) handled.ifFalse(() => { buffer.add(240 + scalar.div(262144)) buffer.add(128 + scalar.div(4096).mod(64)) buffer.add(128 + scalar.div(64).mod(64)) buffer.add(128 + scalar.mod(64)) }) }
parseUnicodeEscape: (digits, buffer) => { scalar: 0 remaining: digits
consume: null consume = () => { (remaining > 0).ifTrue(() => { digit: hexDigit(take()) (digit < 0).ifTrue(() => { fail() }) scalar = scalar * 16 + digit remaining = remaining - 1 consume() }) }
consume() appendScalarUtf8(buffer, scalar) }
parseBasicString: (multiline) => { multiline.ifFalse(() => { (take() == 34).ifFalse(() => { fail() }) })
multiline.ifTrue(() => { (take() == 34).ifFalse(() => { fail() }) (take() == 34).ifFalse(() => { fail() }) (take() == 34).ifFalse(() => { fail() }) isNewlineStart(peek()).ifTrue(() => { consumeNewline() }) })
buffer: Encoding.UTF8.encode("") done: false
countQuotes: (initial) => { count: initial (() => peek() == 34).whileTrue(() => { index = index + 1 count = count + 1 }) count }
skipContinuationWhitespace: () => { scanning: true (() => scanning && (index < length)).whileTrue(() => { octet: source[index] whitespace: isSpace(octet) isNewlineStart(octet).ifTrue(() => { whitespace = true })
whitespace.ifTrue(() => { isNewlineStart(octet).ifTrue(() => { consumeNewline() }) isNewlineStart(octet).ifFalse(() => { index = index + 1 }) }) whitespace.ifFalse(() => { scanning = false }) }) }
(() => done === false).whileTrue(() => { octet: take() ordinaryOctet: true
multiline.ifFalse(() => { (octet == 34).ifTrue(() => { done = true }) })
multiline.ifTrue(() => { (octet == 34).ifTrue(() => { ordinaryOctet = false quoteCount: countQuotes(1)
(quoteCount >= 3).ifTrue(() => { (quoteCount > 5).ifTrue(() => { fail() }) extra: quoteCount - 3 (extra > 0).ifTrue(() => { buffer.add(34) }) (extra > 1).ifTrue(() => { buffer.add(34) }) done = true })
(quoteCount < 3).ifTrue(() => { buffer.add(34) (quoteCount == 2).ifTrue(() => { buffer.add(34) }) }) }) })
done.ifFalse(() => { ordinaryOctet.ifTrue(() => { (octet == 92).ifTrue(() => { continuation: false
multiline.ifTrue(() => { look: index seeking: true sawNewline: false
(() => seeking && (look < length)).whileTrue(() => { candidate: source[look] candidateSpace: isSpace(candidate) candidateNewline: isNewlineStart(candidate)
candidateSpace.ifTrue(() => { look = look + 1 }) candidateNewline.ifTrue(() => { sawNewline = true seeking = false }) (candidateSpace || candidateNewline).ifFalse(() => { seeking = false }) }) (look >= length).ifTrue(() => { seeking = false }) sawNewline.ifTrue(() => { continuation = true }) })
continuation.ifTrue(() => { (() => isSpace(peek())).whileTrue(() => { index = index + 1 }) isNewlineStart(peek()).ifFalse(() => { fail() }) consumeNewline() skipContinuationWhitespace() })
continuation.ifFalse(() => { escape: take() handled: false
(escape == 98).ifTrue(() => { buffer.add(8) handled = true }) (escape == 116).ifTrue(() => { buffer.add(9) handled = true }) (escape == 110).ifTrue(() => { buffer.add(10) handled = true }) (escape == 102).ifTrue(() => { buffer.add(12) handled = true }) (escape == 114).ifTrue(() => { buffer.add(13) handled = true }) (toml11 && (escape == 101)).ifTrue(() => { buffer.add(27) handled = true }) (toml11 && (escape == 120)).ifTrue(() => { parseUnicodeEscape(2, buffer) handled = true }) (escape == 34).ifTrue(() => { buffer.add(34) handled = true }) (escape == 92).ifTrue(() => { buffer.add(92) handled = true }) (escape == 117).ifTrue(() => { parseUnicodeEscape(4, buffer) handled = true }) (escape == 85).ifTrue(() => { parseUnicodeEscape(8, buffer) handled = true })
handled.ifFalse(() => { fail() }) }) })
(octet == 92).ifFalse(() => { newline: isNewlineStart(octet)
newline.ifTrue(() => { multiline.ifFalse(() => { fail() }) index = index - 1 consumeNewline() buffer.add(10) })
newline.ifFalse(() => { invalidControl: octet < 32 (octet == 127).ifTrue(() => { invalidControl = true }) (octet == 9).ifTrue(() => { invalidControl = false }) invalidControl.ifTrue(() => { fail() }) buffer.add(octet) }) }) })
}) }) Encoding.UTF8.decode(buffer) }
parseLiteralString: (multiline) => { multiline.ifFalse(() => { (take() == 39).ifFalse(() => { fail() }) })
multiline.ifTrue(() => { (take() == 39).ifFalse(() => { fail() }) (take() == 39).ifFalse(() => { fail() }) (take() == 39).ifFalse(() => { fail() }) isNewlineStart(peek()).ifTrue(() => { consumeNewline() }) })
buffer: Encoding.UTF8.encode("") done: false
countQuotes: (initial) => { count: initial (() => peek() == 39).whileTrue(() => { index = index + 1 count = count + 1 }) count }
(() => done === false).whileTrue(() => { octet: take() ordinaryOctet: true
multiline.ifFalse(() => { (octet == 39).ifTrue(() => { done = true }) })
multiline.ifTrue(() => { (octet == 39).ifTrue(() => { ordinaryOctet = false quoteCount: countQuotes(1)
(quoteCount >= 3).ifTrue(() => { (quoteCount > 5).ifTrue(() => { fail() }) extra: quoteCount - 3 (extra > 0).ifTrue(() => { buffer.add(39) }) (extra > 1).ifTrue(() => { buffer.add(39) }) done = true })
(quoteCount < 3).ifTrue(() => { buffer.add(39) (quoteCount == 2).ifTrue(() => { buffer.add(39) }) }) }) })
done.ifFalse(() => { ordinaryOctet.ifTrue(() => { newline: isNewlineStart(octet)
newline.ifTrue(() => { multiline.ifFalse(() => { fail() }) index = index - 1 consumeNewline() buffer.add(10) })
newline.ifFalse(() => { invalidControl: octet < 32 (octet == 127).ifTrue(() => { invalidControl = true }) (octet == 9).ifTrue(() => { invalidControl = false }) invalidControl.ifTrue(() => { fail() }) buffer.add(octet) }) })
}) }) Encoding.UTF8.decode(buffer) }
isBareKeyOctet: (octet) => { result: false (octet >= 48).ifTrue(() => { (octet <= 57).ifTrue(() => { result = true }) }) (octet >= 65).ifTrue(() => { (octet <= 90).ifTrue(() => { result = true }) }) (octet >= 97).ifTrue(() => { (octet <= 122).ifTrue(() => { result = true }) }) (octet == 95).ifTrue(() => { result = true }) (octet == 45).ifTrue(() => { result = true }) result }
parseKeyPart: () => { skipSpaces() first: peek() result: null
(first == 34).ifTrue(() => { result = parseBasicString(false) }) (first == 39).ifTrue(() => { result = parseLiteralString(false) })
(first == 34).ifFalse(() => { (first == 39).ifFalse(() => { buffer: Encoding.UTF8.encode("")
gathering: true (() => gathering && (index < length)).whileTrue(() => { octet: source[index] bare: isBareKeyOctet(octet) bare.ifTrue(() => { buffer.add(octet) index = index + 1 }) bare.ifFalse(() => { gathering = false }) }) (buffer.size() == 0).ifTrue(() => { fail() }) result = Encoding.UTF8.decode(buffer) }) })
result }
parseKeyPath: () => { chunks: Map() maxLevel: -1
appendPart: (part) => { chunk: Array(part) level: 0 carrying: true
(() => carrying).whileTrue(() => { present: chunks.containsKey(level) present.ifTrue(() => { left: chunks[level] chunks.remove(level) chunk = Array(...left, ...chunk) level = level + 1 }) present.ifFalse(() => { chunks[level] = chunk (level > maxLevel).ifTrue(() => { maxLevel = level }) carrying = false }) }) }
appendPart(parseKeyPart()) more: true
(() => more).whileTrue(() => { skipSpaces() hasDot: peek() == 46 hasDot.ifTrue(() => { index = index + 1 appendPart(parseKeyPart()) }) hasDot.ifFalse(() => { more = false }) })
parts: Array() level: maxLevel (() => level >= 0).whileTrue(() => { chunks.containsKey(level).ifTrue(() => { parts = Array(...parts, ...chunks[level]) }) level = level - 1 }) parts }
// Only a table created by an earlier dotted key of the same inline // table may be extended; an inline-table value is already complete. putPath: (map, parts, dottedTables, valueNode) => { current: map position: 0
(() => position < parts.size()).whileTrue(() => { name: parts[position] last: position == parts.size() - 1
last.ifTrue(() => { current.containsKey(name).ifTrue(() => { fail() }) current[name] = valueNode position = parts.size() })
last.ifFalse(() => { child: null current.containsKey(name).ifTrue(() => { child = current[name] (child.kind == "table").ifFalse(() => { fail() }) dottedTables.containsKey(child).ifFalse(() => { fail() }) }) current.containsKey(name).ifFalse(() => { child = syntaxNode("table", Map()) current[name] = child dottedTables[child] = true }) current = child.value position = position + 1 }) }) }
carryFrameChunk: (frame, initialChunk, initialLevel) => { chunk: initialChunk level: initialLevel carrying: true (() => carrying).whileTrue(() => { present: frame.chunks.containsKey(level) present.ifTrue(() => { left: frame.chunks[level] frame.chunks.remove(level) chunk = Array(...left, ...chunk) level = level + 1 }) present.ifFalse(() => { frame.chunks[level] = chunk (level > frame.maxLevel).ifTrue(() => { frame.maxLevel = level }) carrying = false }) }) }
collectFrameChunks: (frame, initialLevel, initialResult) => { level: initialLevel result: initialResult (() => level >= 0).whileTrue(() => { frame.chunks.containsKey(level).ifTrue(() => { result = Array(...result, ...frame.chunks[level]) }) level = level - 1 }) result }
decimalDigit: (octet) => { result: -1 (octet >= 48).ifTrue(() => { (octet <= 57).ifTrue(() => { result = octet - 48 }) }) result }
radixDigit: (octet, base) => { result: -1 (base == 16).ifTrue(() => { result = hexDigit(octet) }) (base == 10).ifTrue(() => { result = decimalDigit(octet) }) (base == 8).ifTrue(() => { digit: decimalDigit(octet) (digit >= 0).ifTrue(() => { (digit <= 7).ifTrue(() => { result = digit }) }) }) (base == 2).ifTrue(() => { (octet == 48).ifTrue(() => { result = 0 }) (octet == 49).ifTrue(() => { result = 1 }) }) result }
integerFromToken: (token) => { tokenLength: token.size() position: 0 negative: false signed: false valid: true base: 10
(position < tokenLength).ifTrue(() => { first: token[position] (first == 43).ifTrue(() => { signed = true position = position + 1 }) (first == 45).ifTrue(() => { signed = true negative = true position = position + 1 }) })
(position >= tokenLength).ifTrue(() => { valid = false })
valid.ifTrue(() => { (position + 1 < tokenLength).ifTrue(() => { (token[position] == 48).ifTrue(() => { prefix: token[position + 1] (prefix == 120).ifTrue(() => { base = 16 position = position + 2 }) (prefix == 111).ifTrue(() => { base = 8 position = position + 2 }) (prefix == 98).ifTrue(() => { base = 2 position = position + 2 }) }) }) })
(base != 10).ifTrue(() => { signed.ifTrue(() => { valid = false }) })
(position >= tokenLength).ifTrue(() => { valid = false })
resultValue: 0 digits: 0 previousUnderscore: false leadingZero: false
valid.ifTrue(() => { (() => position < tokenLength).whileTrue(() => { octet: token[position]
(octet == 95).ifTrue(() => { invalidUnderscore: digits == 0 previousUnderscore.ifTrue(() => { invalidUnderscore = true }) invalidUnderscore.ifTrue(() => { valid = false }) previousUnderscore = true })
(octet == 95).ifFalse(() => { digit: radixDigit(octet, base) (digit < 0).ifTrue(() => { valid = false }) (digit >= 0).ifTrue(() => { (digits == 0).ifTrue(() => { (digit == 0).ifTrue(() => { leadingZero = true }) }) (base == 10).ifTrue(() => { leadingZero.ifTrue(() => { (digits > 0).ifTrue(() => { valid = false }) }) }) resultValue = resultValue * base + digit digits = digits + 1 previousUnderscore = false }) })
position = position + 1 }) })
(digits == 0).ifTrue(() => { valid = false }) previousUnderscore.ifTrue(() => { valid = false })
negative.ifTrue(() => { resultValue = 0 - resultValue })
result: { valid: valid value: resultValue } result }
powerOfTen: (power) => { ignoredPowerValidation: 0 + power (power < 0).ifTrue(() => { fail() })
resultValue: 1 factor: 10 remaining: power
(() => remaining > 0).whileTrue(() => { (remaining.mod(2) == 1).ifTrue(() => { resultValue = resultValue * factor }) remaining = remaining.div(2) (remaining > 0).ifTrue(() => { factor = factor * factor }) })
resultValue }
floatFromToken: (token) => { decoded: Encoding.UTF8.decode(token) special: null
((decoded == "inf") || (decoded == "+inf")).ifTrue(() => { special = 1.0 / 0.0 }) (decoded == "-inf").ifTrue(() => { special = -1.0 / 0.0 }) ((decoded == "nan") || (decoded == "+nan") || (decoded == "-nan")).ifTrue(() => { special = 0.0 / 0.0 })
result: { valid: special !== null value: special }
(special === null).ifTrue(() => { tokenLength: token.size() position: 0 negative: false valid: true
(position < tokenLength).ifTrue(() => { first: token[position] (first == 43).ifTrue(() => { position = position + 1 }) (first == 45).ifTrue(() => { negative = true position = position + 1 }) }) (position >= tokenLength).ifTrue(() => { valid = false })
coefficient: 0 integerDigits: 0 fractionDigits: 0 totalDigits: 0 leadingZeros: 0 significant: false firstIntegerZero: false previousDigit: false
valid.ifTrue(() => { scanningInteger: true (() => scanningInteger && (position < tokenLength)).whileTrue(() => { octet: token[position] digit: decimalDigit(octet)
(digit >= 0).ifTrue(() => { (integerDigits == 0).ifTrue(() => { (digit == 0).ifTrue(() => { firstIntegerZero = true }) }) ((integerDigits > 0) && firstIntegerZero).ifTrue(() => { valid = false }) coefficient = coefficient * 10 + digit integerDigits = integerDigits + 1 totalDigits = totalDigits + 1 significant.ifFalse(() => { (digit == 0).ifTrue(() => { leadingZeros = leadingZeros + 1 }) (digit != 0).ifTrue(() => { significant = true }) }) previousDigit = true position = position + 1 })
(digit < 0).ifTrue(() => { underscore: octet == 95 underscore.ifTrue(() => { nextValid: false (position + 1 < tokenLength).ifTrue(() => { (decimalDigit(token[position + 1]) >= 0).ifTrue(() => { nextValid = true }) }) (previousDigit && nextValid).ifFalse(() => { valid = false }) previousDigit = false position = position + 1 }) underscore.ifFalse(() => { scanningInteger = false }) }) }) }) (integerDigits == 0).ifTrue(() => { valid = false }) previousDigit.ifFalse(() => { valid = false })
hasFraction: false valid.ifTrue(() => { (position < tokenLength).ifTrue(() => { (token[position] == 46).ifTrue(() => { hasFraction = true position = position + 1 previousDigit = false
scanningFraction: true (() => scanningFraction && (position < tokenLength)).whileTrue(() => { octet: token[position] digit: decimalDigit(octet)
(digit >= 0).ifTrue(() => { coefficient = coefficient * 10 + digit fractionDigits = fractionDigits + 1 totalDigits = totalDigits + 1 significant.ifFalse(() => { (digit == 0).ifTrue(() => { leadingZeros = leadingZeros + 1 }) (digit != 0).ifTrue(() => { significant = true }) }) previousDigit = true position = position + 1 })
(digit < 0).ifTrue(() => { underscore: octet == 95 underscore.ifTrue(() => { nextValid: false (position + 1 < tokenLength).ifTrue(() => { (decimalDigit(token[position + 1]) >= 0).ifTrue(() => { nextValid = true }) }) (previousDigit && nextValid).ifFalse(() => { valid = false }) previousDigit = false position = position + 1 }) underscore.ifFalse(() => { scanningFraction = false }) }) }) (fractionDigits == 0).ifTrue(() => { valid = false }) previousDigit.ifFalse(() => { valid = false }) }) }) })
exponentValue: 0 exponentNegative: false exponentDigits: 0 hasExponent: false
valid.ifTrue(() => { (position < tokenLength).ifTrue(() => { exponentMarker: token[position] == 101 (token[position] == 69).ifTrue(() => { exponentMarker = true })
exponentMarker.ifTrue(() => { hasExponent = true position = position + 1
(position < tokenLength).ifTrue(() => { (token[position] == 43).ifTrue(() => { position = position + 1 }) (position < tokenLength).ifTrue(() => { (token[position] == 45).ifTrue(() => { exponentNegative = true position = position + 1 }) }) })
previousDigit = false scanningExponent: true (() => scanningExponent && (position < tokenLength)).whileTrue(() => { octet: token[position] digit: decimalDigit(octet)
(digit >= 0).ifTrue(() => { exponentValue = exponentValue * 10 + digit exponentDigits = exponentDigits + 1 previousDigit = true position = position + 1 })
(digit < 0).ifTrue(() => { underscore: octet == 95 underscore.ifTrue(() => { nextValid: false (position + 1 < tokenLength).ifTrue(() => { (decimalDigit(token[position + 1]) >= 0).ifTrue(() => { nextValid = true }) }) (previousDigit && nextValid).ifFalse(() => { valid = false }) previousDigit = false position = position + 1 }) underscore.ifFalse(() => { scanningExponent = false }) }) }) (exponentDigits == 0).ifTrue(() => { valid = false }) previousDigit.ifFalse(() => { valid = false }) }) }) })
((hasFraction || hasExponent) === false).ifTrue(() => { valid = false }) (position != tokenLength).ifTrue(() => { valid = false })
valid.ifTrue(() => { decimalExponent: exponentValue exponentNegative.ifTrue(() => { decimalExponent = 0 - exponentValue }) decimalExponent = decimalExponent - fractionDigits
negative.ifTrue(() => { coefficient = 0 - coefficient })
floating: null
(coefficient == 0).ifTrue(() => { negative.ifTrue(() => { floating = -0.0 }) negative.ifFalse(() => { floating = 0.0 }) })
(coefficient != 0).ifTrue(() => { significantDigits: totalDigits - leadingZeros adjustedExponent: decimalExponent + significantDigits - 1
(adjustedExponent > 400).ifTrue(() => { negative.ifTrue(() => { floating = -1.0 / 0.0 }) negative.ifFalse(() => { floating = 1.0 / 0.0 }) })
(adjustedExponent < -400).ifTrue(() => { negative.ifTrue(() => { floating = -0.0 }) negative.ifFalse(() => { floating = 0.0 }) })
(floating === null).ifTrue(() => { (decimalExponent >= 0).ifTrue(() => { numerator: coefficient * powerOfTen(decimalExponent) floating = numerator / 1 }) (decimalExponent < 0).ifTrue(() => { denominator: powerOfTen(0 - decimalExponent) floating = coefficient / denominator }) }) })
result.valid = true result.value = floating }) })
result }
twoDigitsAt: (token, position) => { valid: position + 1 < token.size() value: 0
valid.ifTrue(() => { first: decimalDigit(token[position]) second: decimalDigit(token[position + 1]) ((first < 0) || (second < 0)).ifTrue(() => { valid = false }) valid.ifTrue(() => { value = first * 10 + second }) })
{ valid: valid value: value } }
fourDigitsAt: (token, position) => { valid: position + 3 < token.size() value: 0 offset: 0
scan: null scan = () => { (offset < 4).ifTrue(() => { valid.ifTrue(() => { digit: decimalDigit(token[position + offset]) (digit < 0).ifTrue(() => { valid = false }) (digit >= 0).ifTrue(() => { value = value * 10 + digit }) }) offset = offset + 1 scan() }) }
valid.ifTrue(() => { scan() })
{ valid: valid value: value } }
timeAt: (token, start) => { tokenLength: token.size() valid: start + 4 < tokenLength
hour: 0 minute: 0 second: 0 fractionCoefficient: 0 fractionDigits: 0 position: start
valid.ifTrue(() => { hourPart: twoDigitsAt(token, start) minutePart: twoDigitsAt(token, start + 3)
(token[start + 2] == 58).ifFalse(() => { valid = false }) (hourPart.valid && minutePart.valid).ifFalse(() => { valid = false })
valid.ifTrue(() => { hour = hourPart.value minute = minutePart.value position = start + 5 }) })
// TOML 1.0 requires the seconds field; TOML 1.1 lets it be omitted. valid.ifTrue(() => { toml11.ifFalse(() => { secondsPresent: false (position < tokenLength).ifTrue(() => { secondsPresent = token[position] == 58 }) secondsPresent.ifFalse(() => { valid = false }) }) })
valid.ifTrue(() => { (position < tokenLength).ifTrue(() => { (token[position] == 58).ifTrue(() => { secondPart: twoDigitsAt(token, position + 1) secondPart.valid.ifFalse(() => { valid = false }) secondPart.valid.ifTrue(() => { second = secondPart.value position = position + 3
(position < tokenLength).ifTrue(() => { (token[position] == 46).ifTrue(() => { position = position + 1 fractionStart: position
scanningFraction: true (() => scanningFraction && (position < tokenLength)).whileTrue(() => { digit: decimalDigit(token[position]) (digit >= 0).ifTrue(() => { fractionCoefficient = fractionCoefficient * 10 + digit fractionDigits = fractionDigits + 1 position = position + 1 }) (digit < 0).ifTrue(() => { scanningFraction = false }) }) (position == fractionStart).ifTrue(() => { valid = false }) }) }) }) }) }) })
{ valid: valid hour: hour minute: minute second: second fractionCoefficient: fractionCoefficient fractionDigits: fractionDigits position: position } }
temporalFromToken: (token) => { tokenLength: token.size() result: { valid: false value: null }
dateShape: tokenLength >= 10 dateShape.ifTrue(() => { ((token[4] == 45) && (token[7] == 45)).ifFalse(() => { dateShape = false }) })
dateShape.ifTrue(() => { yearPart: fourDigitsAt(token, 0) monthPart: twoDigitsAt(token, 5) dayPart: twoDigitsAt(token, 8) (yearPart.valid && monthPart.valid && dayPart.valid).ifFalse(() => { dateShape = false })
dateShape.ifTrue(() => { (tokenLength == 10).ifTrue(() => { result.value = publicLocalDate(yearPart.value, monthPart.value, dayPart.value) result.valid = true })
(tokenLength > 10).ifTrue(() => { delimiter: token[10] validDelimiter: delimiter == 84 (delimiter == 116).ifTrue(() => { validDelimiter = true }) (delimiter == 32).ifTrue(() => { validDelimiter = true })
validDelimiter.ifTrue(() => { parsedTime: timeAt(token, 11) parsedTime.valid.ifTrue(() => { position: parsedTime.position
(position == tokenLength).ifTrue(() => { result.value = publicLocalDateTime( yearPart.value, monthPart.value, dayPart.value, parsedTime.hour, parsedTime.minute, parsedTime.second, parsedTime.fractionCoefficient, parsedTime.fractionDigits ) result.valid = true })
(position < tokenLength).ifTrue(() => { offsetMinutes: 0 offsetValid: false offsetEnd: position
((token[position] == 90) || (token[position] == 122)).ifTrue(() => { offsetValid = true offsetEnd = position + 1 })
((token[position] == 43) || (token[position] == 45)).ifTrue(() => { (position + 5 < tokenLength).ifTrue(() => { (token[position + 3] == 58).ifTrue(() => { offsetHour: twoDigitsAt(token, position + 1) offsetMinute: twoDigitsAt(token, position + 4)
(offsetHour.valid && offsetMinute.valid).ifTrue(() => { ((offsetHour.value <= 23) && (offsetMinute.value <= 59)).ifTrue(() => { offsetMinutes = offsetHour.value * 60 + offsetMinute.value (token[position] == 45).ifTrue(() => { offsetMinutes = 0 - offsetMinutes }) offsetEnd = position + 6 offsetValid = true }) }) }) }) })
(offsetValid && (offsetEnd == tokenLength)).ifTrue(() => { result.value = publicOffsetDateTime( yearPart.value, monthPart.value, dayPart.value, parsedTime.hour, parsedTime.minute, parsedTime.second, parsedTime.fractionCoefficient, parsedTime.fractionDigits, offsetMinutes ) result.valid = true }) }) }) }) }) }) })
dateShape.ifFalse(() => { parsedTime: timeAt(token, 0) (parsedTime.valid && (parsedTime.position == tokenLength)).ifTrue(() => { result.value = publicLocalTime( parsedTime.hour, parsedTime.minute, parsedTime.second, parsedTime.fractionCoefficient, parsedTime.fractionDigits ) result.valid = true }) })
result }
isBareTerminator: (octet) => { result: octet < 0 isSpace(octet).ifTrue(() => { result = true }) isNewlineStart(octet).ifTrue(() => { result = true }) (octet == 35).ifTrue(() => { result = true }) (octet == 44).ifTrue(() => { result = true }) (octet == 93).ifTrue(() => { result = true }) (octet == 125).ifTrue(() => { result = true }) result }
parseBareValue: () => { token: Encoding.UTF8.encode("")
gathering: true (() => gathering).whileTrue(() => { octet: peek() terminator: octet < 0 isNewlineStart(octet).ifTrue(() => { terminator = true }) (octet == 35).ifTrue(() => { terminator = true }) (octet == 44).ifTrue(() => { terminator = true }) (octet == 93).ifTrue(() => { terminator = true }) (octet == 125).ifTrue(() => { terminator = true })
terminator.ifTrue(() => { gathering = false }) terminator.ifFalse(() => { invalidControl: octet < 32 (octet == 9).ifTrue(() => { invalidControl = false }) (octet == 127).ifTrue(() => { invalidControl = true }) invalidControl.ifTrue(() => { fail() }) token.add(take()) }) }) (token.size() == 0).ifTrue(() => { fail() })
right: token.size() trimming: true (() => trimming && (right > 0)).whileTrue(() => { whitespace: isSpace(token[right - 1]) whitespace.ifTrue(() => { right = right - 1 }) whitespace.ifFalse(() => { trimming = false }) })
trimmed: Encoding.UTF8.encode("") copyIndex: 0 (() => copyIndex < right).whileTrue(() => { trimmed.add(token[copyIndex]) copyIndex = copyIndex + 1 })
(trimmed.size() == 0).ifTrue(() => { fail() })
decoded: Encoding.UTF8.decode(trimmed) result: null
(decoded == "true").ifTrue(() => { result = syntaxNode("boolean", true) }) (decoded == "false").ifTrue(() => { result = syntaxNode("boolean", false) })
(result === null).ifTrue(() => { integer: integerFromToken(trimmed) integer.valid.ifTrue(() => { result = syntaxNode("integer", integer.value) }) })
(result === null).ifTrue(() => { temporal: temporalFromToken(trimmed) temporal.valid.ifTrue(() => { result = temporal.value }) })
(result === null).ifTrue(() => { floating: floatFromToken(trimmed) floating.valid.ifTrue(() => { result = syntaxNode("float", floating.value) }) })
(result === null).ifTrue(() => { fail() })
result }
topFrame: null depth: 0 rootValue: null rootDone: false
pushArrayFrame: () => { frame: { parent: topFrame kind: "array" phase: "valueOrEnd" chunks: Map() maxLevel: -1 } topFrame = frame depth = depth + 1 }
pushInlineTableFrame: () => { frame: { parent: topFrame kind: "inlineTable" phase: "keyOrEnd" entries: Map() dottedTables: IdentityMap() pendingPath: null } topFrame = frame depth = depth + 1 }
appendArrayValue: (frame, valueNode) => { carryFrameChunk(frame, Array(valueNode), 0) frame.phase = "commaOrEnd" }
acceptValue: (valueNode) => { (depth == 0).ifTrue(() => { rootDone.ifTrue(() => { fail() }) rootValue = valueNode rootDone = true })
(depth > 0).ifTrue(() => { frame: topFrame
(frame.kind == "array").ifTrue(() => { (frame.phase == "awaitValue").ifFalse(() => { fail() }) appendArrayValue(frame, valueNode) })
(frame.kind == "inlineTable").ifTrue(() => { (frame.phase == "awaitValue").ifFalse(() => { fail() }) putPath( frame.entries, frame.pendingPath, frame.dottedTables, valueNode ) frame.pendingPath = null frame.phase = "commaOrEnd" }) }) }
closeArrayFrame: () => { frame: topFrame (frame.kind == "array").ifFalse(() => { fail() }) validPhase: frame.phase == "valueOrEnd" (frame.phase == "commaOrEnd").ifTrue(() => { validPhase = true }) validPhase.ifFalse(() => { fail() })
materialized: collectFrameChunks(frame, frame.maxLevel, Array()) valueNode: syntaxNode("array", materialized) topFrame = frame.parent depth = depth - 1 acceptValue(valueNode) }
closeInlineTableFrame: () => { frame: topFrame (frame.kind == "inlineTable").ifFalse(() => { fail() }) validPhase: frame.phase == "keyOrEnd" (frame.phase == "commaOrEnd").ifTrue(() => { validPhase = true }) validPhase.ifFalse(() => { fail() })
valueNode: syntaxNode("table", frame.entries) topFrame = frame.parent depth = depth - 1 acceptValue(valueNode) }
startValue: () => { skipSpaces() first: peek() (first < 0).ifTrue(() => { fail() }) handled: false
(first == 91).ifTrue(() => { index = index + 1 pushArrayFrame() handled = true }) (first == 123).ifTrue(() => { index = index + 1 pushInlineTableFrame() handled = true })
handled.ifFalse(() => { result: null (first == 34).ifTrue(() => { multiline: false (index + 2 < length).ifTrue(() => { ((source[index + 1] == 34) && (source[index + 2] == 34)).ifTrue(() => { multiline = true }) }) result = syntaxNode("string", parseBasicString(multiline)) }) (first == 39).ifTrue(() => { multiline: false (index + 2 < length).ifTrue(() => { ((source[index + 1] == 39) && (source[index + 2] == 39)).ifTrue(() => { multiline = true }) }) result = syntaxNode("string", parseLiteralString(multiline)) }) (result === null).ifTrue(() => { result = parseBareValue() }) acceptValue(result) }) }
running: true (() => running).whileTrue(() => { wasTopLevel: depth == 0
wasTopLevel.ifTrue(() => { rootDone.ifTrue(() => { running = false }) rootDone.ifFalse(() => { startValue() }) })
wasTopLevel.ifFalse(() => { frame: topFrame phase: frame.phase
(frame.kind == "array").ifTrue(() => { skipArrayTrivia()
(phase == "valueOrEnd").ifTrue(() => { closing: peek() == 93 closing.ifTrue(() => { index = index + 1 closeArrayFrame() }) closing.ifFalse(() => { frame.phase = "awaitValue" startValue() }) })
(phase == "value").ifTrue(() => { frame.phase = "awaitValue" startValue() })
(phase == "commaOrEnd").ifTrue(() => { comma: peek() == 44 closing: peek() == 93 comma.ifTrue(() => { index = index + 1 skipArrayTrivia() trailing: peek() == 93 trailing.ifTrue(() => { index = index + 1 closeArrayFrame() }) trailing.ifFalse(() => { frame.phase = "value" }) }) comma.ifFalse(() => { closing.ifTrue(() => { index = index + 1 closeArrayFrame() }) closing.ifFalse(() => { fail() }) }) }) })
(frame.kind == "inlineTable").ifTrue(() => { skipInlineTableTrivia()
(phase == "keyOrEnd").ifTrue(() => { closing: peek() == 125 closing.ifTrue(() => { index = index + 1 closeInlineTableFrame() }) closing.ifFalse(() => { frame.pendingPath = parseKeyPath() skipSpaces() (take() == 61).ifFalse(() => { fail() }) skipSpaces() frame.phase = "value" }) })
(phase == "value").ifTrue(() => { frame.phase = "awaitValue" startValue() })
(phase == "commaOrEnd").ifTrue(() => { comma: peek() == 44 closing: peek() == 125 comma.ifTrue(() => { index = index + 1 skipInlineTableTrivia() trailing: peek() == 125 trailing.ifTrue(() => { // TOML 1.0 forbids a trailing comma in an inline table. toml11.ifFalse(() => { fail() }) index = index + 1 closeInlineTableFrame() }) trailing.ifFalse(() => { frame.phase = "keyOrEnd" }) }) comma.ifFalse(() => { closing.ifTrue(() => { index = index + 1 closeInlineTableFrame() }) closing.ifFalse(() => { fail() }) }) }) }) }) })
result: rootValue skipSpaces() (peek() == 35).ifTrue(() => { index = index + 1 skipComment() }) (index < length).ifTrue(() => { isNewlineStart(peek()).ifTrue(() => { consumeNewline() }) }) skipSpaces() (index == length).ifFalse(() => { fail() }) result
}
documentStatements: (text) => { String.recognizes(text).ifFalse(() => { Error().signal() }) source: Encoding.UTF8.encode(text) index: 0 length: source.size()
statementChunks: Map() statementMaxLevel: -1 buffer: Encoding.UTF8.encode("") significant: false
carryStatementChunk: (initialChunk, initialLevel) => { chunk: initialChunk level: initialLevel carrying: true (() => carrying).whileTrue(() => { present: statementChunks.containsKey(level) present.ifTrue(() => { left: statementChunks[level] statementChunks.remove(level) chunk = Array(...left, ...chunk) level = level + 1 }) present.ifFalse(() => { statementChunks[level] = chunk (level > statementMaxLevel).ifTrue(() => { statementMaxLevel = level }) carrying = false }) }) }
collectStatementChunks: (initialLevel, initialResult) => { level: initialLevel result: initialResult (() => level >= 0).whileTrue(() => { statementChunks.containsKey(level).ifTrue(() => { result = Array(...result, ...statementChunks[level]) }) level = level - 1 }) result } squareDepth: 0 braceDepth: 0 stringQuote: -1 multiline: false comment: false
peek: () => { value: -1 (index < length).ifTrue(() => { value = source[index] }) value }
take: () => { (index >= length).ifTrue(() => { fail() }) value: source[index] index = index + 1 value }
append: (octet) => { buffer.add(octet) (octet == 32).ifFalse(() => { (octet == 9).ifFalse(() => { significant = true }) }) }
appendQuotes: (quote, count) => { remaining: count (() => remaining > 0).whileTrue(() => { append(quote) remaining = remaining - 1 }) }
quoteRun: (quote) => { look: index count: 0 scanning: true
(() => scanning && (look < length)).whileTrue(() => { matches: source[look] == quote matches.ifTrue(() => { count = count + 1 look = look + 1 }) matches.ifFalse(() => { scanning = false }) })
count }
finish: () => { significant.ifTrue(() => { carryStatementChunk(Array(Encoding.UTF8.decode(buffer)), 0) }) buffer = Encoding.UTF8.encode("") significant = false }
appendNewline: (include) => { first: take() (first == 10).ifTrue(() => { include.ifTrue(() => { append(10) }) }) (first == 13).ifTrue(() => { (peek() == 10).ifFalse(() => { fail() }) second: take() include.ifTrue(() => { append(13) append(second) }) }) (first == 10).ifFalse(() => { (first == 13).ifFalse(() => { fail() }) }) }
step: () => { octet: peek()
wasComment: comment wasComment.ifTrue(() => { isNewline: octet == 10 (octet == 13).ifTrue(() => { isNewline = true })
isNewline.ifTrue(() => { comment = false nested: squareDepth > 0 (braceDepth > 0).ifTrue(() => { nested = true }) nested.ifTrue(() => { appendNewline(true) }) nested.ifFalse(() => { appendNewline(false) finish() }) })
isNewline.ifFalse(() => { forbiddenControl: octet < 32 (octet == 9).ifTrue(() => { forbiddenControl = false }) (octet == 127).ifTrue(() => { forbiddenControl = true }) forbiddenControl.ifTrue(() => { fail() }) index = index + 1 }) })
wasComment.ifFalse(() => { wasString: stringQuote >= 0 wasString.ifTrue(() => { wasMultiline: multiline wasMultiline.ifTrue(() => { // Snapshot this before closing mutates stringQuote. quoteOctet: octet == stringQuote quoteOctet.ifTrue(() => { run: quoteRun(stringQuote) (run >= 3).ifTrue(() => { (run > 5).ifTrue(() => { fail() }) appendQuotes(stringQuote, run) index = index + run stringQuote = -1 multiline = false }) (run < 3).ifTrue(() => { append(take()) }) })
quoteOctet.ifFalse(() => { escapedBasic: stringQuote == 34 (octet == 92).ifFalse(() => { escapedBasic = false })
escapedBasic.ifTrue(() => { append(take()) (index >= length).ifTrue(() => { fail() }) append(take()) })
escapedBasic.ifFalse(() => { append(take()) }) }) })
wasMultiline.ifFalse(() => { isNewline: octet == 10 (octet == 13).ifTrue(() => { isNewline = true }) isNewline.ifTrue(() => { fail() })
escapedBasic: stringQuote == 34 (octet == 92).ifFalse(() => { escapedBasic = false })
escapedBasic.ifTrue(() => { append(take()) (index >= length).ifTrue(() => { fail() }) append(take()) })
escapedBasic.ifFalse(() => { append(take()) (octet == stringQuote).ifTrue(() => { stringQuote = -1 }) }) }) })
wasString.ifFalse(() => { (octet == 35).ifTrue(() => { comment = true index = index + 1 })
(octet == 35).ifFalse(() => { isQuote: octet == 34 (octet == 39).ifTrue(() => { isQuote = true })
isQuote.ifTrue(() => { run: quoteRun(octet) (run >= 3).ifTrue(() => { appendQuotes(octet, 3) index = index + 3 stringQuote = octet multiline = true }) (run < 3).ifTrue(() => { append(take()) stringQuote = octet multiline = false }) })
isQuote.ifFalse(() => { (octet == 91).ifTrue(() => { squareDepth = squareDepth + 1 append(take()) }) (octet == 93).ifTrue(() => { (squareDepth == 0).ifTrue(() => { fail() }) squareDepth = squareDepth - 1 append(take()) }) (octet == 123).ifTrue(() => { braceDepth = braceDepth + 1 append(take()) }) (octet == 125).ifTrue(() => { (braceDepth == 0).ifTrue(() => { fail() }) braceDepth = braceDepth - 1 append(take()) })
structural: octet == 91 (octet == 93).ifTrue(() => { structural = true }) (octet == 123).ifTrue(() => { structural = true }) (octet == 125).ifTrue(() => { structural = true })
structural.ifFalse(() => { isNewline: octet == 10 (octet == 13).ifTrue(() => { isNewline = true })
isNewline.ifTrue(() => { nested: squareDepth > 0 (braceDepth > 0).ifTrue(() => { nested = true }) nested.ifTrue(() => { appendNewline(true) }) nested.ifFalse(() => { appendNewline(false) finish() }) })
isNewline.ifFalse(() => { append(take()) }) }) }) }) }) })
}
visitIndex: 0 source.each((ignoredOctet) => { (visitIndex == index).ifTrue(() => { step() }) visitIndex = visitIndex + 1 })
(index == length).ifFalse(() => { fail() })
(stringQuote >= 0).ifTrue(() => { fail() }) (squareDepth != 0).ifTrue(() => { fail() }) (braceDepth != 0).ifTrue(() => { fail() })
finish() collectStatementChunks(statementMaxLevel, Array()) }
documentTable: (text) => { items: documentStatements(text)
node: (kind, value) => { result: { kind: kind value: value } result }
root: node("table", Map()) states: IdentityMap() states[root] = "root" current: root
arrayTableBuilders: IdentityMap() arrayTableBuilderEntries: Map() arrayTableBuilderCount: 0
appendArrayTableElement: (arrayNode, element) => { builder: null arrayTableBuilders.containsKey(arrayNode).ifTrue(() => { builder = arrayTableBuilders[arrayNode] }) arrayTableBuilders.containsKey(arrayNode).ifFalse(() => { builder = { arrayNode: arrayNode chunks: Map() maxLevel: -1 last: null } arrayTableBuilders[arrayNode] = builder arrayTableBuilderEntries[arrayTableBuilderCount] = builder arrayTableBuilderCount = arrayTableBuilderCount + 1 })
chunk: Array(element) level: 0 carrying: true (() => carrying).whileTrue(() => { present: builder.chunks.containsKey(level) present.ifTrue(() => { left: builder.chunks[level] builder.chunks.remove(level) chunk = Array(...left, ...chunk) level = level + 1 }) present.ifFalse(() => { builder.chunks[level] = chunk (level > builder.maxLevel).ifTrue(() => { builder.maxLevel = level }) carrying = false }) }) builder.last = element }
materializeArrayTableBuilder: (builder) => { result: Array() level: builder.maxLevel (() => level >= 0).whileTrue(() => { builder.chunks.containsKey(level).ifTrue(() => { result = Array(...result, ...builder.chunks[level]) }) level = level - 1 }) result }
isSpace: (octet) => { result: octet == 32 (octet == 9).ifTrue(() => { result = true }) result }
decodeRange: (source, start, end) => { buffer: Encoding.UTF8.encode("") position: start (() => position < end).whileTrue(() => { buffer.add(source[position]) position = position + 1 }) Encoding.UTF8.decode(buffer) }
trimBounds: (source) => { left: 0 right: source.size()
trimmingLeft: true (() => trimmingLeft && (left < right)).whileTrue(() => { whitespace: isSpace(source[left]) whitespace.ifTrue(() => { left = left + 1 }) whitespace.ifFalse(() => { trimmingLeft = false }) })
trimmingRight: true (() => trimmingRight && (right > left)).whileTrue(() => { whitespace: isSpace(source[right - 1]) whitespace.ifTrue(() => { right = right - 1 }) whitespace.ifFalse(() => { trimmingRight = false }) })
{ left: left right: right } }
markInlineTable: (valueNode) => { (valueNode.kind == "table").ifTrue(() => { states[valueNode] = "inline" }) }
putDotted: (tableNode, parts, ignoredPosition, valueNode) => { selected: tableNode position: 0
(() => position < parts.count).whileTrue(() => { name: parts.entries[position] last: position == parts.count - 1 entries: selected.value
last.ifTrue(() => { entries.containsKey(name).ifTrue(() => { fail() }) entries[name] = valueNode markInlineTable(valueNode) position = parts.count })
last.ifFalse(() => { child: null entries.containsKey(name).ifTrue(() => { child = entries[name] (child.kind == "table").ifFalse(() => { fail() }) states.containsKey(child).ifFalse(() => { fail() }) state: states[child] (state == "header").ifTrue(() => { fail() }) (state == "inline").ifTrue(() => { fail() }) (state == "implicit").ifTrue(() => { states[child] = "dotted" }) })
entries.containsKey(name).ifFalse(() => { child = node("table", Map()) entries[name] = child states[child] = "dotted" })
selected = child position = position + 1 }) }) }
latestArrayTable: (arrayNode) => { (arrayNode.kind == "array").ifFalse(() => { fail() }) states.containsKey(arrayNode).ifFalse(() => { fail() }) (states[arrayNode] == "array-table").ifFalse(() => { fail() }) arrayTableBuilders.containsKey(arrayNode).ifFalse(() => { fail() }) builder: arrayTableBuilders[arrayNode] selected: builder.last (selected === null).ifTrue(() => { fail() }) (selected.kind == "table").ifFalse(() => { fail() }) selected }
existingParent: (child) => { selected: null
(child.kind == "table").ifTrue(() => { states.containsKey(child).ifFalse(() => { fail() }) (states[child] == "inline").ifTrue(() => { fail() }) selected = child })
(child.kind == "array").ifTrue(() => { selected = latestArrayTable(child) })
(selected === null).ifTrue(() => { fail() }) selected }
selectHeader: (parts) => { selected: root position: 0
(() => position < parts.count).whileTrue(() => { name: parts.entries[position] last: position == parts.count - 1 entries: selected.value child: null
entries.containsKey(name).ifTrue(() => { child = entries[name]
last.ifTrue(() => { (child.kind == "table").ifFalse(() => { fail() }) states.containsKey(child).ifFalse(() => { fail() }) state: states[child] (state == "implicit").ifTrue(() => { states[child] = "header" }) (state == "implicit").ifFalse(() => { fail() }) selected = child })
last.ifFalse(() => { selected = existingParent(child) }) })
entries.containsKey(name).ifFalse(() => { child = node("table", Map()) entries[name] = child last.ifTrue(() => { states[child] = "header" }) last.ifFalse(() => { states[child] = "implicit" }) selected = child })
position = position + 1 })
selected }
selectArrayHeader: (parts) => { selected: root position: 0 created: null
(() => position < parts.count).whileTrue(() => { name: parts.entries[position] last: position == parts.count - 1 entries: selected.value child: null
last.ifTrue(() => { element: node("table", Map()) states[element] = "array-element"
entries.containsKey(name).ifTrue(() => { child = entries[name] (child.kind == "array").ifFalse(() => { fail() }) states.containsKey(child).ifFalse(() => { fail() }) (states[child] == "array-table").ifFalse(() => { fail() }) })
entries.containsKey(name).ifFalse(() => { child = node("array", Array()) entries[name] = child states[child] = "array-table" })
appendArrayTableElement(child, element) created = element })
last.ifFalse(() => { entries.containsKey(name).ifTrue(() => { child = entries[name] selected = existingParent(child) })
entries.containsKey(name).ifFalse(() => { child = node("table", Map()) entries[name] = child states[child] = "implicit" selected = child }) })
position = position + 1 })
created }
parseHeader: (statement) => { source: Encoding.UTF8.encode(statement) bounds: trimBounds(source) (bounds.left >= bounds.right).ifTrue(() => { fail() }) (source[bounds.left] == 91).ifFalse(() => { fail() }) (source[bounds.right - 1] == 93).ifFalse(() => { fail() })
arrayHeader: false keyStart: bounds.left + 1 keyEnd: bounds.right - 1
(keyStart < keyEnd).ifTrue(() => { (source[keyStart] == 91).ifTrue(() => { arrayHeader = true (keyStart + 1 >= keyEnd).ifTrue(() => { fail() }) (source[keyEnd - 1] == 93).ifFalse(() => { fail() }) keyStart = keyStart + 1 keyEnd = keyEnd - 1 }) })
keyText: decodeRange(source, keyStart, keyEnd) { array: arrayHeader path: syntaxKeyPath(keyText) } }
parseAssignment: (statement) => { source: Encoding.UTF8.encode(statement) length: source.size() position: 0 quote: -1 separator: -1
(() => (position < length) && (separator < 0)).whileTrue(() => { octet: source[position] inQuote: quote >= 0
inQuote.ifTrue(() => { escaped: quote == 34 (octet == 92).ifFalse(() => { escaped = false })
escaped.ifTrue(() => { position = position + 1 (position >= length).ifTrue(() => { fail() }) position = position + 1 })
escaped.ifFalse(() => { (octet == quote).ifTrue(() => { quote = -1 }) position = position + 1 }) })
inQuote.ifFalse(() => { isQuote: octet == 34 (octet == 39).ifTrue(() => { isQuote = true })
isQuote.ifTrue(() => { quote = octet position = position + 1 })
isQuote.ifFalse(() => { isNewline: octet == 10 (octet == 13).ifTrue(() => { isNewline = true }) isNewline.ifTrue(() => { fail() })
(octet == 61).ifTrue(() => { separator = position }) position = position + 1 }) })
}) (quote >= 0).ifTrue(() => { fail() }) (separator < 0).ifTrue(() => { fail() })
keyText: decodeRange(source, 0, separator) valueText: decodeRange(source, separator + 1, length) { path: syntaxKeyPath(keyText) value: syntaxValue(valueText) } }
items.each((statement) => { source: Encoding.UTF8.encode(statement) bounds: trimBounds(source) (bounds.left >= bounds.right).ifTrue(() => { fail() })
header: source[bounds.left] == 91 header.ifTrue(() => { parsedHeader: parseHeader(statement) parsedHeader.array.ifTrue(() => { current = selectArrayHeader(parsedHeader.path) }) parsedHeader.array.ifFalse(() => { current = selectHeader(parsedHeader.path) }) })
header.ifFalse(() => { assignment: parseAssignment(statement) putDotted(current, assignment.path, 0, assignment.value) }) })
builderIndex: 0 (() => builderIndex < arrayTableBuilderCount).whileTrue(() => { builder: arrayTableBuilderEntries[builderIndex] builder.arrayNode.value = materializeArrayTableBuilder(builder) builderIndex = builderIndex + 1 })
root }
documentTable(text)}
/// Parses one complete TOML 1.1 document into its root table node; invalid text signals/// an Error. Equivalent to `parseDialect(text, "1.1")`.parse: (text) => { parseDialect(text, "1.1")}