use json = "../json"
use parser = "../parser"
primitive ParseNode
fun apply(locator: parser.Locator, obj: json.Object val): (Node | String) =>
let name =
match try obj("name")? end
| let str: String box =>
str
else
return "node.name must be a string"
end
let src_info =
match try obj("src_info")? end
| let src_info_obj: json.Object val =>
let line' =
match try src_info_obj("line")? end
| let n: I128 =>
n
else
return "src_info.line must be an integer"
end
let column' =
match try src_info_obj("column")? end
| let n: I128 =>
n
else
return "src_info.column must be an integer"
end
let next_line' =
match try src_info_obj("next_line")? end
| let n: I128 =>
n
else
return "src_info.next_line must be an integer"
end
let next_column' =
match try src_info_obj("next_column")? end
| let n: I128 =>
n
else
return "src_info.next_column must be an integer"
end
SrcInfo(locator where
line' = USize.from[I128](line'),
column' = USize.from[I128](column'),
next_line' = USize.from[I128](next_line'),
next_column' = USize.from[I128](next_column'))
else
SrcInfo(locator)
end
let scope_index =
match try obj("scope")? end
| let index: I128 =>
USize.from[I128](index)
end
let children': Array[Node] trn = Array[Node]
match try obj("children")? end
| let children_seq: json.Sequence val =>
for child_item in children_seq.values() do
match child_item
| let child_obj: json.Object val =>
match ParseNode(locator, child_obj)
| let n: Node =>
children'.push(n)
| let err: String =>
return err
end
else
return "node.children should be a sequence of objects"
end
end
end
let children: ReadSeq[Node] val = consume children'
let annotation =
match try obj("annotation")? end
| let int: I128 =>
match try children(USize.from[I128](int))? end
| let annotation': NodeWith[Annotation] =>
annotation'
else
return "annotation must refer to an Annotation"
end
| None =>
None
else
return "annotation must refer to an Annotation"
end
let doc_strings =
match _get_seq_with[DocString](
obj,
children,
"doc_strings",
"doc_strings must refer to DocStrings",
false)
| let seq: NodeSeqWith[DocString] =>
seq
| let err: String =>
return err
end
let pre_trivia =
match _get_seq_with[Trivia](
obj,
children,
"pre_trivia",
"pre_trivia must refer to Trivias",
false)
| let seq: NodeSeqWith[Trivia] =>
seq
| let err: String =>
return err
end
let post_trivia =
match _get_seq_with[Trivia](
obj,
children,
"post_trivia",
"post_trivia must refer to Trivias",
false)
| let seq: NodeSeqWith[Trivia] =>
seq
| let err: String =>
return err
end
let ctor: (_NodeConstructor | None) =
match name
| "Annotation" =>
ParseNode~_ctor[Annotation](ParseAnnotation~apply(obj, children))
| "CallArgs" =>
ParseNode~_ctor[CallArgs](ParseCallArgs~apply(obj, children))
| "DocString" =>
ParseNode~_ctor[DocString](ParseDocString~apply(obj, children))
| "ErrorSection" =>
ParseNode~_ctor[ErrorSection](ParseErrorSection~apply(obj, children))
| "ExpArray" =>
ParseNode~_ctor[Expression](ParseExpArray~apply(obj, children))
| "ExpAtom" =>
ParseNode~_ctor[Expression](ParseExpAtom~apply(obj, children))
| "ExpCall" =>
ParseNode~_ctor[Expression](ParseExpCall~apply(obj, children))
| "ExpConsume" =>
ParseNode~_ctor[Expression](ParseExpConsume~apply(obj, children))
| "ExpDecl" =>
ParseNode~_ctor[Expression](ParseExpDecl~apply(obj, children))
| "ExpFfi" =>
ParseNode~_ctor[Expression](ParseExpFfi~apply(obj, children))
| "ExpFor" =>
ParseNode~_ctor[Expression](ParseExpFor~apply(obj, children))
| "ExpGeneric" =>
ParseNode~_ctor[Expression](ParseExpGeneric~apply(obj, children))
| "ExpHash" =>
ParseNode~_ctor[Expression](ParseExpHash~apply(obj, children))
| "ExpIf" =>
ParseNode~_ctor[Expression](ParseExpIf~apply(obj, children))
| "IfCondition" =>
ParseNode~_ctor[IfCondition](ParseIfCondition~apply(obj, children))
| "ExpJump" =>
ParseNode~_ctor[Expression](ParseExpJump~apply(obj, children))
| "ExpLambda" =>
ParseNode~_ctor[Expression](ParseExpLambda~apply(obj, children))
| "ExpMatch" =>
ParseNode~_ctor[Expression](ParseExpMatch~apply(obj, children))
| "MatchPattern" =>
ParseNode~_ctor[MatchPattern](ParseMatchPattern~apply(obj, children))
| "MatchCase" =>
ParseNode~_ctor[MatchCase](ParseMatchCase~apply(obj, children))
| "ExpObject" =>
ParseNode~_ctor[Expression](ParseExpObject~apply(obj, children))
| "ExpOperation" =>
ParseNode~_ctor[Expression](ParseExpOperation~apply(obj, children))
| "ExpRecover" =>
ParseNode~_ctor[Expression](ParseExpRecover~apply(obj, children))
| "ExpRepeat" =>
ParseNode~_ctor[Expression](ParseExpRepeat~apply(obj, children))
| "ExpSequence" =>
ParseNode~_ctor[Expression](ParseExpSequence~apply(obj, children))
| "ExpTry" =>
ParseNode~_ctor[Expression](ParseExpTry~apply(obj, children))
| "ExpTuple" =>
ParseNode~_ctor[Expression](ParseExpTuple~apply(obj, children))
| "ExpWhile" =>
ParseNode~_ctor[Expression](ParseExpWhile~apply(obj, children))
| "ExpWith" =>
ParseNode~_ctor[Expression](ParseExpWith~apply(obj, children))
| "WithElement" =>
ParseNode~_ctor[WithElement](ParseWithElement~apply(obj, children))
| "Identifier" =>
ParseNode~_ctor[Identifier](ParseIdentifier~apply(obj, children))
| "Keyword" =>
ParseNode~_ctor[Keyword](ParseKeyword~apply(obj, children))
| "LiteralBool" =>
ParseNode~_ctor[LiteralBool](ParseLiteralBool~apply(obj, children))
| "LiteralChar" =>
ParseNode~_ctor[LiteralChar](ParseLiteralChar~apply(obj, children))
| "LiteralFloat" =>
ParseNode~_ctor[LiteralFloat](ParseLiteralFloat~apply(obj, children))
| "LiteralInteger" =>
ParseNode~_ctor[LiteralInteger](ParseLiteralInteger~apply(
obj, children))
| "LiteralString" =>
ParseNode~_ctor[LiteralString](ParseLiteralString~apply(obj, children))
| "MethodParam" =>
ParseNode~_ctor[MethodParam](ParseMethodParam~apply(obj, children))
| "MethodParams" =>
ParseNode~_ctor[MethodParams](ParseMethodParams~apply(obj, children))
| "Span" =>
ParseNode~_ctor[Span](ParseSpan~apply(obj, children))
| "SrcFile" =>
ParseNode~_ctor[SrcFile](ParseSrcFile~apply(obj, children))
| "Token" =>
ParseNode~_ctor[Token](ParseToken~apply(obj, children))
| "Trivia" =>
ParseNode~_ctor[Trivia](ParseTrivia~apply(obj, children))
| "TuplePattern" =>
ParseNode~_ctor[TuplePattern](ParseTuplePattern~apply(obj, children))
| "TypeArgs" =>
ParseNode~_ctor[TypeArgs](ParseTypeArgs~apply(obj, children))
| "TypeArrow" =>
ParseNode~_ctor[TypeType](ParseTypeArrow~apply(obj, children))
| "TypeAtom" =>
ParseNode~_ctor[TypeType](ParseTypeAtom~apply(obj, children))
| "TypeInfix" =>
ParseNode~_ctor[TypeType](ParseTypeInfix~apply(obj, children))
| "TypeLambda" =>
ParseNode~_ctor[TypeType](ParseTypeLambda~apply(obj, children))
| "TypeNominal" =>
ParseNode~_ctor[TypeType](ParseTypeNominal~apply(obj, children))
| "TypeParams" =>
ParseNode~_ctor[TypeParams](ParseTypeParams~apply(obj, children))
| "TypeParam" =>
ParseNode~_ctor[TypeParam](ParseTypeParam~apply(obj, children))
| "TypeTuple" =>
ParseNode~_ctor[TypeType](ParseTypeTuple~apply(obj, children))
| "TypedefAlias" =>
ParseNode~_ctor[Typedef](ParseTypedefAlias~apply(obj, children))
| "TypedefClass" =>
ParseNode~_ctor[Typedef](ParseTypedefClass~apply(obj, children))
| "TypedefField" =>
ParseNode~_ctor[TypedefField](ParseTypedefField~apply(obj, children))
| "TypedefMembers" =>
ParseNode~_ctor[TypedefMembers](ParseTypedefMembers~apply(
obj, children))
| "TypedefMethod" =>
ParseNode~_ctor[TypedefMethod](ParseTypedefMethod~apply(obj, children))
| "TypedefPrimitive" =>
ParseNode~_ctor[Typedef](ParseTypedefPrimitive~apply(obj, children))
| "UsingFFI" =>
ParseNode~_ctor[Using](ParseUsingFFI~apply(obj, children))
| "UsingPony" =>
ParseNode~_ctor[Using](ParseUsingPony~apply(obj, children))
end
match ctor
| let ctor': _NodeConstructor =>
ctor'(
src_info,
children,
annotation,
doc_strings,
pre_trivia,
post_trivia,
scope_index)
else
"unknown node data type " + name
end
fun _ctor[D: NodeData val](
ctor: {ref (): (D | String)},
src_info: SrcInfo,
children: NodeSeq,
annotation: (NodeWith[Annotation] | None),
doc_strings: NodeSeqWith[DocString],
pre_trivia: NodeSeqWith[Trivia],
post_trivia: NodeSeqWith[Trivia],
scope_index: (USize | None))
: (Node | String)
=>
let data =
match ctor()
| let data': D =>
data'
| let err: String =>
return err
end
NodeWith[D](
src_info,
children,
data,
annotation,
doc_strings,
pre_trivia,
post_trivia,
None,
scope_index)
fun _get_child(
obj: json.Object val,
children: NodeSeq,
key: String,
help: String,
mandatory: Bool = true)
: (Node | String | None)
=>
match try obj(key)? end
| let i: I128 =>
match try children(USize.from[I128](i))? end
| let node: Node =>
node
else
help
end
else
if mandatory then
help
end
end
fun _get_child_with[D: NodeData val](
obj: json.Object val,
children: NodeSeq,
key: String,
help: String,
mandatory: Bool = true)
: (NodeWith[D] | String | None)
=>
match try obj(key)? end
| let i: I128 =>
match try children(USize.from[I128](i))? end
| let node: NodeWith[D] =>
node
| let node': Node =>
help + "; got a " + node'.name()
else
help
end
| let item: json.Item =>
help
else
if mandatory then
help
end
end
fun _get_seq_with[D: NodeData val](
obj: json.Object val,
children: NodeSeq,
key: String,
help: String,
mandatory: Bool = true)
: (NodeSeqWith[D] | String)
=>
match try obj(key)? end
| let seq: json.Sequence box =>
let nodes: Array[NodeWith[D]] trn = Array[NodeWith[D]]
for item in seq.values() do
match item
| let n: I128 =>
try
nodes.push(children(USize.from[I128](n))? as NodeWith[D])
else
return help
end
else
return help
end
end
consume nodes
| let item: json.Item =>
help
else
if mandatory then
help
else
[]
end
end
type _NodeConstructor is
{ ref
( SrcInfo
, NodeSeq
, (NodeWith[Annotation] | None)
, NodeSeqWith[DocString]
, NodeSeqWith[Trivia]
, NodeSeqWith[Trivia]
, (USize | None) )
: (Node | String) }