Packages
caffeine_lang
4.6.4
6.3.1
6.3.0
6.2.2
6.2.1
6.2.0
6.1.2
6.1.1
6.1.0
6.0.0
5.6.0
5.5.0
5.4.4
5.4.3
5.4.2
5.4.1
5.4.0
5.3.0
5.2.0
5.1.1
5.1.0
5.0.12
5.0.11
5.0.10
5.0.8
5.0.7
5.0.6
5.0.5
5.0.4
5.0.1
5.0.0
4.10.0
4.9.0
4.8.3
4.8.2
4.8.1
4.8.0
4.7.9
4.7.8
4.7.7
4.7.6
4.7.5
4.6.7
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.7
4.3.6
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.0.2
1.0.1
0.1.0
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.2
0.0.1
A compiler for generating reliability artifacts from service expectation definitions.
Current section
Files
Jump to
Current section
Files
src/caffeine_lang/frontend/ast.gleam
/// AST for Caffeine blueprint and expectation files.
import caffeine_lang/types.{type ParsedType}
import gleam/list
import gleam/string
// =============================================================================
// COMMENTS
// =============================================================================
/// A comment attached to an AST node.
pub type Comment {
LineComment(text: String)
SectionComment(text: String)
}
// =============================================================================
// FILE-LEVEL NODES
// =============================================================================
/// Marker type for parsed (not yet validated) AST.
pub type Parsed
/// Marker type for validated AST.
pub type Validated
/// A blueprints file containing type aliases, extendables, and blueprint blocks.
/// Type aliases must come before extendables, which must come before blocks.
/// The phantom `phase` parameter tracks whether the file has been validated.
pub type BlueprintsFile(phase) {
BlueprintsFile(
type_aliases: List(TypeAlias),
extendables: List(Extendable),
blocks: List(BlueprintsBlock),
trailing_comments: List(Comment),
)
}
// =============================================================================
// TYPE ALIASES
// =============================================================================
/// A type alias that defines a named, reusable refined type.
/// Example: _env (Type): String { x | x in { prod, staging, dev } }
pub type TypeAlias {
TypeAlias(name: String, type_: ParsedType, leading_comments: List(Comment))
}
/// An expects file containing extendables and expects blocks.
/// The phantom `phase` parameter tracks whether the file has been validated.
pub type ExpectsFile(phase) {
ExpectsFile(
extendables: List(Extendable),
blocks: List(ExpectsBlock),
trailing_comments: List(Comment),
)
}
/// Promotes a BlueprintsFile to a new phantom phase by reconstructing all fields.
@internal
pub fn promote_blueprints_file(file: BlueprintsFile(a)) -> BlueprintsFile(b) {
BlueprintsFile(
type_aliases: file.type_aliases,
extendables: file.extendables,
blocks: file.blocks,
trailing_comments: file.trailing_comments,
)
}
/// Promotes an ExpectsFile to a new phantom phase by reconstructing all fields.
@internal
pub fn promote_expects_file(file: ExpectsFile(a)) -> ExpectsFile(b) {
ExpectsFile(
extendables: file.extendables,
blocks: file.blocks,
trailing_comments: file.trailing_comments,
)
}
// =============================================================================
// EXTENDABLES
// =============================================================================
/// An extendable block that can be inherited by blueprints or expectations.
pub type Extendable {
Extendable(
name: String,
kind: ExtendableKind,
body: Struct,
leading_comments: List(Comment),
)
}
/// The kind of extendable (Requires for types, Provides for values).
pub type ExtendableKind {
ExtendableRequires
ExtendableProvides
}
/// Converts an extendable kind to its display string.
@internal
pub fn extendable_kind_to_string(kind: ExtendableKind) -> String {
case kind {
ExtendableRequires -> "Requires"
ExtendableProvides -> "Provides"
}
}
// =============================================================================
// ARTIFACT REFS
// =============================================================================
/// A parsed artifact reference — the closed set of valid artifact types.
pub type ParsedArtifactRef {
ParsedSLO
ParsedDependencyRelations
}
/// Converts a ParsedArtifactRef to its canonical string representation.
@internal
pub fn parsed_artifact_ref_to_string(ref: ParsedArtifactRef) -> String {
case ref {
ParsedSLO -> "SLO"
ParsedDependencyRelations -> "DependencyRelations"
}
}
// =============================================================================
// BLUEPRINT NODES
// =============================================================================
/// A block of blueprints for one or more artifacts.
pub type BlueprintsBlock {
BlueprintsBlock(
artifacts: List(ParsedArtifactRef),
items: List(BlueprintItem),
leading_comments: List(Comment),
)
}
/// A single blueprint item with name, extends, requires, and provides.
pub type BlueprintItem {
BlueprintItem(
name: String,
extends: List(String),
requires: Struct,
provides: Struct,
leading_comments: List(Comment),
)
}
// =============================================================================
// EXPECTS NODES
// =============================================================================
/// A block of expectations for a blueprint.
pub type ExpectsBlock {
ExpectsBlock(
blueprint: String,
items: List(ExpectItem),
leading_comments: List(Comment),
)
}
/// A single expectation item with name, extends, and provides.
pub type ExpectItem {
ExpectItem(
name: String,
extends: List(String),
provides: Struct,
leading_comments: List(Comment),
)
}
// =============================================================================
// STRUCT AND FIELD
// =============================================================================
/// A struct containing a list of fields.
pub type Struct {
Struct(fields: List(Field), trailing_comments: List(Comment))
}
/// A field with a name and value (either a type or a literal).
pub type Field {
Field(name: String, value: Value, leading_comments: List(Comment))
}
/// A value in a field - either a type (in Requires) or a literal (in Provides).
pub type Value {
TypeValue(type_: ParsedType)
LiteralValue(literal: Literal)
}
// =============================================================================
// LITERALS
// =============================================================================
/// Literal values.
pub type Literal {
LiteralString(value: String)
LiteralInteger(value: Int)
LiteralFloat(value: Float)
LiteralPercentage(value: Float)
LiteralTrue
LiteralFalse
LiteralList(elements: List(Literal))
LiteralStruct(fields: List(Field), trailing_comments: List(Comment))
}
/// Builds a list of name-type pairs from type aliases for lookup purposes.
/// Used by both the validator and generator to resolve type alias references.
@internal
pub fn build_type_alias_pairs(
type_aliases: List(TypeAlias),
) -> List(#(String, ParsedType)) {
list.map(type_aliases, fn(ta) { #(ta.name, ta.type_) })
}
/// Converts a value to a display string.
@internal
pub fn value_to_string(value: Value) -> String {
case value {
TypeValue(t) -> types.parsed_type_to_string(t)
LiteralValue(lit) -> literal_to_string(lit)
}
}
/// Converts a literal to a short display string.
@internal
pub fn literal_to_string(lit: Literal) -> String {
case lit {
LiteralString(s) -> "\"" <> s <> "\""
LiteralInteger(n) -> string.inspect(n)
LiteralFloat(f) -> string.inspect(f)
LiteralPercentage(f) -> string.inspect(f) <> "%"
LiteralTrue -> "true"
LiteralFalse -> "false"
LiteralList(_) -> "[...]"
LiteralStruct(_, _) -> "{...}"
}
}