kex docs Standard Library

Kex.AST

module Kex.AST

Parses Kex source code into a structured AST, at run time.

Opt-in — nothing here is in scope until using Kex.AST.

This is the entry point for tools that read Kex source: linters, formatters, documentation generators, code search. The AST includes module definitions, function signatures, type/record definitions, traits, make blocks, and the doc-comments extracted from # lines — which is how the standard library's own documentation is generated.

using Kex.AST

main do
  match Kex.AST.parseFile("src/main.kex") do
    Ok(program) => IO.printLine("${program.items.count} top-level items")
    Error(e)    => IO.printError(e.message)
  end
end

Everything answers a Result, so a source file that does not parse is a value you handle rather than an exception.

parse

parse(source: String) -> Result<Program, ParseError>
parse(source: String, filename: String) -> Result<Program, ParseError>

Parses Kex source text into a structured AST.

Pass filename when you have one — it is what appears in every Location and in the error message, so diagnostics can point at a real file.

Parameters
source
the Kex source text
filename
the name to report locations against; optional

Returns the parsed program, or why it failed

Examples
Kex.AST.parse("let double(n: Integer) -> Integer = n * 2\n")
# => Ok(Program { schemaVersion: 2, items: [...] })
Kex.AST.parse("let x =").error?   # => true

Counting a file's top-level items

Kex.AST.parse(source, "main.kex").map { |p| p.items.count }

parseFile

parseFile(path: FS.FilePath) -> Result<Program, ParseError>

Reads a file and parses it, reporting locations against its path.

A file that cannot be read is an Error like one that cannot be parsed.

Parameters
path
the file to read and parse

Returns the parsed program, or why it failed

Examples
match Kex.AST.parseFile("src/main.kex") do
  Ok(program) => IO.printLine("${program.items.count} items")
  Error(e)    => IO.printError(e.message)
end

Parsing every source in a directory

FS.Directory.files(dir)
  .or([])
  .filter { |f| FS.Path.extension(f) == ".kex" }
  .map { |f| Kex.AST.parseFile(FS.Path.join(dir, f)) }

parseType

parseType(source: String) -> Result<TypeRef, ParseError>

Parses a type expression on its own, without a surrounding program.

Use it to read a type written in data — a signature in a config file, a type named on a command line. typeRefText renders the result back.

Parameters
source
the type expression

Returns the parsed type, or why it failed

Examples
Kex.AST.parseType("[Integer]").map { |t| Kex.AST.typeRefText(t) }
# => Ok("[Integer]")
Kex.AST.parseType("Map<String, Integer>").map { |t| Kex.AST.typeRefText(t) }
# => Ok("Map<String, Integer>")

parseExpression

parseExpression(source: String) -> Result<Expression, ParseError>

Parses a single expression on its own, without a surrounding program.

This gives you the expression's SHAPE. To evaluate one instead, use Evaluator.runExpression.

Parameters
source
the expression text

Returns the parsed expression, or why it failed

Examples
Kex.AST.parseExpression("1 + 2").ok?   # => true
Kex.AST.parseExpression("1 +").ok?     # => false

typeRefText

typeRefText(typeRef: TypeRef) -> String

Renders a TypeRef back to the way it is written in source.

A list reads as [Integer], a map as {String: Integer}, an optional as String? — the spelling a reader would recognise, not the constructor tree behind it.

Parameters
typeRef
the parsed type

Returns the type, as source

Examples
Kex.AST.parseType("[Integer]").map { |t| Kex.AST.typeRefText(t) }
# => Ok("[Integer]")
Kex.AST.parseType("String?").map { |t| Kex.AST.typeRefText(t) }
# => Ok("String?")

patternRefText

patternRefText(patternRef: PatternRef) -> String

Renders a PatternRef back to the way it is written in source.

Parameters
patternRef
the parsed pattern

Returns the pattern, as source

Examples
Kex.AST.patternRefText(WildcardPattern)             # => "_"
Kex.AST.patternRefText(BindPattern("n"))            # => "n"

patternFieldText

patternFieldText(name, _, _) -> String

referenceText

referenceText(reference: TypeRef | PatternRef) -> String

Renders either a type or a pattern back to source.

The one call to reach for when a node may carry either — it dispatches to typeRefText or patternRefText as appropriate.

Parameters
reference
the parsed node

Returns the node, as source

Examples
Kex.AST.referenceText(WildcardPattern)   # => "_"
Kex.AST.referenceText(AnyType)           # => "Any"

record Location

Where in a source file something appeared.

Line and column are 1-based, for reporting to a person; the offsets are 0-based byte positions, for slicing the source.

Fields

file
String
column
Integer
startOffset
Integer
endOffset
Integer

record Program

A parsed source file: its schema version, and its top-level items.

Fields

schemaVersion
Integer
items
[Node]

record ParseError

Why a source file could not be parsed.

Fields

message
String
location
Location?

type TypeRef

A type as it was written in source.

typeRefText renders one back to the source spelling.

Variants

  • NamedType(String, [TypeRef])
  • FunctionType([TypeRef], TypeRef)
  • TupleType([TypeRef])
  • ListType(TypeRef)
  • MapType(TypeRef, TypeRef)
  • UnionType([TypeRef])
  • IntersectionType([TypeRef])
  • RecordType([(String, TypeRef)])
  • NullableType(TypeRef)
  • BlockType(TypeRef)
  • AtomType(String)
  • TypeQuery(String, Expression)
  • TypeVar(String)
  • AnyType
  • NoneType

type PatternRef

Structured representation of patterns.

Variants

  • BindPattern(String)
  • LiteralPattern(String)
  • ConstructorPattern(String, [PatternRef])
  • TuplePattern([PatternRef])
  • ListPattern([PatternRef], PatternRef?)
  • RecordPattern(String?, [PatternField])
  • RangePattern(PatternRef, PatternRef)
  • ThisPattern(PatternRef)
  • WildcardPattern

record PatternField

Fields

name
String
pattern
PatternRef?
stringKey
Bool

type Expression

Structured representation of expression AST nodes.

Variants

  • LitInt(Int)
  • LitFloat(Float)
  • LitChar(Int)
  • LitString(String)
  • InterpolatedString([String], [Expression])
  • LitBool(Bool)
  • LitAtom(String)
  • LitNone
  • Identifier(String)
  • This
  • BinaryOp(Expression, String, Expression)
  • UnaryOp(String, Expression)
  • Call(Expression, [Expression], [NamedArgument], Expression?)
  • TaggedLiteral(String, [String], [Expression])
  • MethodCall(Expression, String, [Expression], [NamedArgument], Expression?, Bool, Bool, TypeRef?)
  • If(Expression, PatternRef?, [Expression], [ElseIf], [Expression]?)
  • Match(Expression, String?, [MatchArm])
  • Receive(String?, [MatchArm], Expression?, Expression?)
  • ListLit([Expression], Expression?)
  • MapLit([MapItem])
  • RecordLit(String, [RecordField])
  • TupleLit([Expression])
  • Block([Expression])
  • Lambda([LambdaParam], [Expression], TypeRef?, RescueInfo?)
  • Let(PatternRef, TypeRef?, Expression)
  • Var(String, TypeRef?, Expression)
  • Assign(String, Expression)
  • Return(Expression)
  • Break
  • Next
  • Spawn([Expression])
  • Try(Expression)
  • Spread(Expression)
  • TrailingIf(Expression, Expression)
  • ThenElse(Expression, Expression, Expression)
  • ShorthandLambda(String, [Expression], Bool)
  • CurryPlaceholder
  • Curry(String, String?, Bool, [[Expression]])
  • Using(String, String?, [String], [String], [Expression])
  • With(String, Expression, [Expression])
  • GeneratedDeclaration(Expression, GeneratedTemplate)
  • ErrorExpression(String)
  • Trying([Expression], RescueInfo)
  • While(Expression, [Expression])
  • Loop([String], [Expression])
  • RangeLit(Expression, Expression)

record NamedArgument

Fields

name
String

record MatchArm

Fields

patterns
[PatternRef]

record LambdaParam

Fields

name
String
type
TypeRef?

record RescueInfo

Fields

arms
[MatchArm]
catchAllName
String?
catchAllBody
[Expression]
inlineReturn
Expression?

record ElseIf

Fields

condition
Expression

type MapItem

Variants

  • MapEntry(Expression, Expression)
  • MapSpread(Expression)

record RecordField

Fields

name
String

type GeneratedTemplate

A declaration template whose name (and, for a make block, target) is computed by a compiled do expression.

Variants

  • GeneratedNode(Node)
  • GeneratedMake(GeneratedMakeInfo)

record GeneratedMakeInfo

Fields

isFinal
Bool
implements
[TypeRef]
location
Location

record MainInfo

Fields

doc
String?
params
[ParamInfo]
rescueInfo
RescueInfo?
location
Location

record ParamInfo

Fields

name
String?
pattern
PatternRef?
type
TypeRef?
hasDefault
Bool

record ClauseInfo

Fields

params
[ParamInfo]
returnType
TypeRef?
rescueInfo
RescueInfo?
hasParamList
Bool

record FunctionInfo

Fields

name
String
doc
String?
isFoul
Bool
predicate
Bool
clauses
[ClauseInfo]
location
Location

record AnnotationInfo

Fields

name
String
doc
String?
implicitThis
Bool
location
Location

record VariantInfo

Fields

name
String
fields
[TypeRef]

record TypeInfo

Fields

name
String
doc
String?
typeParams
[String]
parents
[TypeRef]
variants
[VariantInfo]?
location
Location

record FieldInfo

Fields

name
String
hasDefault
Bool

record RecordInfo

Fields

name
String
doc
String?
typeParams
[String]
fields
[FieldInfo]
location
Location

record TraitInfo

Fields

name
String
doc
String?
typeParams
[String]
body
[Node]
location
Location

record MakeInfo

Fields

target
TypeRef
doc
String?
isFinal
Bool
implements
[TypeRef]
body
[Node]
location
Location

record PragmaInfo

Fields

name
String
value
String?
location
Location

record ModuleInfo

Fields

name
String
doc
String?
items
[Node]
location
Location

record ConstantInfo

Fields

name
String
doc
String?
type
TypeRef?
location
Location

record VisibilityInfo

Fields

isPublic
Bool
items
[Node]
location
Location

record UsingInfo

Fields

moduleName
String
alias
String?
onlyNames
[String]
exceptNames
[String]
location
Location

record ExportInfo

Fields

moduleName
String
alias
String?
onlyNames
[String]
exceptNames
[String]
location
Location

type CompiledItem

Variants

  • CompiledNode(Node)
  • CompiledExpression(Expression)

record CompiledInfo

Fields

location
Location

type Node

Variants

  • ModuleDef(ModuleInfo)
  • FunctionDef(FunctionInfo)
  • TypeAnnotation(AnnotationInfo)
  • TypeDef(TypeInfo)
  • RecordDef(RecordInfo)
  • TraitDef(TraitInfo)
  • MakeDef(MakeInfo)
  • PragmaDef(PragmaInfo)
  • ConstantDef(ConstantInfo)
  • MainDef(MainInfo)
  • Visibility(VisibilityInfo)
  • UsingDef(UsingInfo)
  • ExportDef(ExportInfo)
  • Compiled(CompiledInfo)

type TypeRef | PatternRef

Source-like conversion through the standard .to(String) spelling.

to

to(_) -> String?