///|
/// A character class constant (`classes[i]` of the abstract machine).
pub(all) struct ClassConst {
parts : Array[@runtime.ClassPart]
inverted : Bool
ignore_case : Bool
} derive(Eq, Debug)
///|
pub impl ToJson for ClassConst with fn to_json(self) {
{
"value": self.parts.to_json(),
"inverted": self.inverted.to_json(),
"ignoreCase": self.ignore_case.to_json(),
}
}
///|
/// An action, predicate or initializer code block (`functions[i]`).
/// Deduplicated on (predicate, params, body), exactly as PEG.js does.
pub(all) struct FunctionConst {
predicate : Bool
params : Array[String]
body : String
} derive(Eq, Debug)
///|
pub impl ToJson for FunctionConst with fn to_json(self) {
{
"predicate": self.predicate.to_json(),
"params": self.params.to_json(),
"body": self.body.to_json(),
}
}
///|
/// Serializes an expectation constant the way `generateBytecode` stores it
/// (`{type: "rule", value}` for named rules, `value` for literal text).
pub fn expectation_const_json(e : @runtime.Expectation) -> Json {
match e {
Other(description~) => { "type": "rule", "value": description.to_json() }
Literal(text~, ignore_case~) =>
{
"type": "literal",
"value": text.to_json(),
"ignoreCase": ignore_case.to_json(),
}
Class(parts~, inverted~, ignore_case~) =>
{
"type": "class",
"value": parts.to_json(),
"inverted": inverted.to_json(),
"ignoreCase": ignore_case.to_json(),
}
Any => { "type": "any" }
End => { "type": "end" }
Not(_) => abort("negated expectations are never constants")
}
}
///|
/// The compiled form of one rule.
pub(all) struct RuleCode {
name : String
bytecode : Array[Int]
} derive(Eq, Debug)
///|
/// Everything the parsing machine needs: per-rule bytecode plus the constant
/// tables it indexes. Produced by the compiler, consumed by the VM and by the
/// code generator.
pub(all) struct Program {
opcodes : Opcodes
rules : Array[RuleCode]
literals : Array[String]
classes : Array[ClassConst]
expectations : Array[@runtime.Expectation]
functions : Array[FunctionConst]
/// Initializer code block, if the grammar has one.
initializer : String?
/// Names of the rules parsing may start from; the first is the default.
allowed_start_rules : Array[String]
/// Whether rule results are memoized (the `cache` option).
cache : Bool
/// Whether rule enter/match/fail events are traced (the `trace` option).
trace : Bool
features : @runtime.Features
} derive(Debug)
///|
pub fn Program::rule_index(self : Program, name : String) -> Int? {
for i, r in self.rules {
if r.name == name {
return Some(i)
}
}
None
}
///|
pub extend ClassConst with ToJson::{to_json}
///|
pub extend FunctionConst with ToJson::{to_json}