Skip to content

TOML

Canonical source: protos/lib/toml/TOML.protos at locked revision e99b712ecf658a527b1fe82c8beba2c1286d8dc9.

// 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")
}

โ† toml family ยท Standard-library source