Packages
caffeine_lang
3.0.3
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/pipeline.gleam
/// Frontend pipeline for compiling .caffeine files to JSON.
/// This module orchestrates the tokenizer, parser, validator, and generator
/// to transform .caffeine source files into JSON for the compiler backend.
import caffeine_lang/common/errors.{type CompilationError}
import caffeine_lang/frontend/generator
import caffeine_lang/frontend/parser
import caffeine_lang/frontend/parser_error
import caffeine_lang/frontend/validator
import gleam/json
import gleam/result
import simplifile
/// Compiles a blueprints .caffeine file to JSON string.
@internal
pub fn compile_blueprints_file(
file_path: String,
) -> Result(String, CompilationError) {
use source <- result.try(read_file(file_path))
use ast <- result.try(
parser.parse_blueprints_file(source)
|> result.map_error(fn(err) {
parser_error_to_compilation_error(err, file_path)
}),
)
use validated <- result.try(
validator.validate_blueprints_file(ast)
|> result.map_error(fn(err) {
validator_error_to_compilation_error(err, file_path)
}),
)
Ok(json.to_string(generator.generate_blueprints_json(validated)))
}
/// Compiles an expects .caffeine file to JSON string.
@internal
pub fn compile_expects_file(
file_path: String,
) -> Result(String, CompilationError) {
use source <- result.try(read_file(file_path))
use ast <- result.try(
parser.parse_expects_file(source)
|> result.map_error(fn(err) {
parser_error_to_compilation_error(err, file_path)
}),
)
use validated <- result.try(
validator.validate_expects_file(ast)
|> result.map_error(fn(err) {
validator_error_to_compilation_error(err, file_path)
}),
)
Ok(json.to_string(generator.generate_expects_json(validated)))
}
fn read_file(file_path: String) -> Result(String, CompilationError) {
simplifile.read(file_path)
|> result.map_error(fn(err) {
errors.ParserFileReadError(
simplifile.describe_error(err) <> " (" <> file_path <> ")",
)
})
}
fn parser_error_to_compilation_error(
err: parser_error.ParserError,
file_path: String,
) -> CompilationError {
errors.FrontendParseError(file_path <> ": " <> parser_error.to_string(err))
}
fn validator_error_to_compilation_error(
err: validator.ValidatorError,
file_path: String,
) -> CompilationError {
errors.FrontendValidationError(
file_path <> ": " <> validator_error_to_string(err),
)
}
fn validator_error_to_string(err: validator.ValidatorError) -> String {
case err {
validator.DuplicateExtendable(name) -> "Duplicate extendable: " <> name
validator.UndefinedExtendable(name, referenced_by) ->
"Undefined extendable '"
<> name
<> "' referenced by '"
<> referenced_by
<> "'"
validator.DuplicateExtendsReference(name, referenced_by) ->
"Duplicate extends reference '"
<> name
<> "' in '"
<> referenced_by
<> "'"
validator.InvalidExtendableKind(name, expected, got) ->
"Invalid extendable kind for '"
<> name
<> "': expected "
<> expected
<> ", got "
<> got
validator.UndefinedTypeAlias(name, referenced_by) ->
"Undefined type alias '"
<> name
<> "' referenced by '"
<> referenced_by
<> "'"
validator.DuplicateTypeAlias(name) -> "Duplicate type alias: " <> name
validator.CircularTypeAlias(name, _cycle) ->
"Circular type alias reference detected in '" <> name <> "'"
validator.InvalidDictKeyTypeAlias(alias_name, resolved_to, referenced_by) ->
"Type alias '"
<> alias_name
<> "' used as Dict key resolves to '"
<> resolved_to
<> "' which is not String-based, in '"
<> referenced_by
<> "'"
}
}