moonrockz/krueger/ast does not have a README file
impl Show for DecodeErrorpub(all) enum Expression {
UnitExpr
Application(ArrayView[Node[Expression]])
OperatorApplication(String, InfixDirection, Node[Expression], Node[Expression])
FunctionOrValue(ArrayView[String], String)
IfBlock(Node[Expression], Node[Expression], Node[Expression])
PrefixOperator(String)
Operator(String)
Integer(Int64)
Hex(Int64)
Floatable(Double)
Negation(Node[Expression])
Literal(String)
CharLiteral(Char)
TupledExpression(ArrayView[Node[Expression]])
ParenthesizedExpression(Node[Expression])
LetExpression(LetBlock)
CaseExpression(CaseBlock)
LambdaExpression(Lambda)
RecordExpr(ArrayView[Node[RecordSetter]])
ListExpr(ArrayView[Node[Expression]])
RecordAccess(Node[Expression], Node[String])
RecordAccessFunction(String)
RecordUpdateExpression(Node[String], ArrayView[Node[RecordSetter]])
GLSLExpression(String)
} derive(Eq, Debug)pub(all) struct LetBlock {
declarations : ArrayView[Node[LetDeclaration]]
expression : Node[Expression]
} derive(Eq, Debug)pub(all) enum Module {
NormalModule(DefaultModuleData)
PortModule(DefaultModuleData)
EffectModule(EffectModuleData)
} derive(Eq, Debug)pub(all) enum Pattern {
AllPattern
UnitPattern
CharPattern(Char)
StringPattern(String)
IntPattern(Int64)
HexPattern(Int64)
FloatPattern(Double)
TuplePattern(ArrayView[Node[Pattern]])
RecordPattern(ArrayView[Node[String]])
UnConsPattern(Node[Pattern], Node[Pattern])
ListPattern(ArrayView[Node[Pattern]])
VarPattern(String)
NamedPattern(QualifiedNameRef, ArrayView[Node[Pattern]])
AsPattern(Node[Pattern], Node[String])
ParenthesizedPattern(Node[Pattern])
} derive(Eq, Debug)test {
let source = @scanner.SourceText::new(
"module Main exposing (..)\n\nname = \"\u{1F600}\" ++ x\n",
)
let result = @parser.parse_module(source, @scanner.DefaultScanner::new())
guard result.ast is Some(file) else { fail("no AST") }
let decl = file.declarations[0]
debug_inspect(
decl.range,
content="{ start: { row: 3, column: 1 }, end: { row: 3, column: 16 } }",
)
inspect(@ast.encode_range(decl.range).stringify(), content="[3,1,3,16]")
}pub(all) struct RecordField {
name : Node[String]
type_annotation : Node[TypeAnnotation]
} derive(Eq, Debug)pub(all) struct RecordSetter {
field : Node[String]
expression : Node[Expression]
} derive(Eq, Debug)pub(all) struct Signature {
name : Node[String]
type_annotation : Node[TypeAnnotation]
} derive(Eq, Debug)pub(all) enum TopLevelExpose {
InfixExpose(String)
FunctionExpose(String)
TypeOrAliasExpose(String)
TypeExpose(ExposedType)
} derive(Eq, Debug)pub(all) enum TypeAnnotation {
GenericType(String)
Typed(Node[(ArrayView[String], String)], ArrayView[Node[TypeAnnotation]])
Unit
Tupled(ArrayView[Node[TypeAnnotation]])
Record(ArrayView[Node[RecordField]])
GenericRecord(Node[String], Node[ArrayView[Node[RecordField]]])
FunctionTypeAnnotation(Node[TypeAnnotation], Node[TypeAnnotation])
} derive(Eq, Debug)test {
let source = @scanner.SourceText::new(
"module Main exposing (main)\n\nmain =\n \"hi\"\n",
)
let result = @parser.parse_module(source, @scanner.DefaultScanner::new())
guard result.ast is Some(file) else { fail("no AST") }
let text = @ast.encode_file(file).stringify()
let decoded = @ast.decode_file(@json.parse(text))
inspect(decoded == file, content="true")
// Malformed input raises an error that names the JSON path.
try @ast.decode_file({ "imports": [] }) catch {
e =>
inspect(
e,
content="$: Expecting an OBJECT with a field named `moduleDefinition`",
)
} noraise {
_ => fail("expected a DecodeError")
}
}test {
let source = @scanner.SourceText::new("module Main exposing (x)\n\nx = 1\n")
let result = @parser.parse_module(source, @scanner.DefaultScanner::new())
guard result.ast is Some(file) else { fail("no AST") }
let json = @ast.encode_file(file)
guard json is { "declarations": [declaration], .. } else {
fail("unexpected shape")
}
inspect(
declaration.stringify(),
content=(
#|{"range":[3,1,3,6],"value":{"type":"function","function":{"documentation":null,"signature":null,"declaration":{"range":[3,1,3,6],"value":{"name":{"range":[3,1,3,2],"value":"x"},"arguments":[],"expression":{"range":[3,5,3,6],"value":{"type":"integer","integer":1}}}}}}}
),
)
}test {
let source = @scanner.SourceText::new(
"module Main exposing (..)\n\nbig =\n 9007199254740993\n",
)
let result = @parser.parse_module(source, @scanner.DefaultScanner::new())
guard result.ast is Some(file) else { fail("no AST") }
// elm-syntax writes the nearest Double.
let nearest = @ast.encode_file(file).stringify()
inspect(nearest.contains("9007199254740992"), content="true")
// exact_ints keeps the digits of the literal.
let exact = @ast.encode_file_with(file, exact_ints=true).stringify()
inspect(exact.contains("9007199254740993"), content="true")
// The decoder reads both forms; the exact form gives the literal back.
inspect(@ast.decode_file(@json.parse(exact)) == file, content="true")
}Install
Download zipParser and parsing utilities for Elm and Elm-like dialects (e.g. Morphir) in MoonBit
Dependencies