frontend/itl_expr API
frontend/itl_expr parses interval test cases in the ITL format of the
ITF1788 suite (test data for the IEEE 1788-2015 interval standard) and executes
them against ball_float. It is a pure library: the command-line runner is
cli/itl_expr_cli. The
tutorial walks through the workflow and
the design page gives the pass rule.
Import the package in moon.pkg:
import {
"Luna-Flow/floating/frontend/itl_expr",
}
Parsing
parse_itl
parse_itl(source) parses ITL text into cases.
pub fn parse_itl(String) -> Result[Array[ItlCase], Array[String]]
The text is read line by line, each line trimmed:
- lines starting with
//and empty lines are skipped; a line starting with/*starts a block comment that ends on the first later line containing*/(or on the same line); testcase NAME …starts a new block;NAMEis the word aftertestcaseand must be followed by a space, otherwise the diagnostic"invalid testcase declaration"is recorded; the statement counter restarts at 0;- a line equal to
}is skipped; - every other line is appended (with a space) to the current statement, and a
line ending in
;completes it.
A completed statement left = expected is split at the first =. The left
side is split into words at spaces and tabs outside square brackets; the
first word is the operation and the rest are operands. The case id is
NAME:k, where k counts statements in the block from 1 (statements before
the first testcase use the name anonymous). A statement without = or
without an operation is a diagnostic "NAME:k: missing '='" or
"NAME:k: missing operation"; text left after the last ; gives
"unterminated ITL statement". The result is Ok(cases) when there is no
diagnostic and Err(diagnostics) otherwise.
ItlCase
ItlCase is one parsed statement.
pub struct ItlCase {
// private fields
} derive(Eq, @debug.Debug)
ItlCase::id, operation, operands, expected
These methods return the id NAME:k, the operation word, a copy of the
operand words and the expected text (trimmed, including any decoration
suffix).
pub fn ItlCase::id(Self) -> String
pub fn ItlCase::operation(Self) -> String
pub fn ItlCase::operands(Self) -> Array[String]
pub fn ItlCase::expected(Self) -> String
Execution
execute_case
execute_case(case, precision?) executes one case and returns its result.
pub fn execute_case(ItlCase, precision? : Int) -> ItlResult
precision (default 53) is the bit precision used to read bounds.
Interval results are rounded with @ball_float.BallContext::binary64()
regardless of precision, so the default is the meaningful value for ITF1788
data.
Operands and expected values are read as follows. An interval literal is
[lo,hi], [empty], [entire] or [nai], optionally followed by
_dec with dec one of com, dac, def, trv, ill (default com).
A bound is inf/infinity with an optional sign, a hexadecimal float
0x…p…, or decimal text. Decimal and hexadecimal bounds are rounded to
nearest-even at precision bits.
The case is dispatched on its operation and expected value:
| Case | Operations | Expected | Comparison |
|---|---|---|---|
| boolean | isEmpty, isEntire, isNaI, isCommonInterval, isSingleton, equal, subset, interior, disjoint, precedes, strictPrecedes, less, strictLess, isMember | true or false | equal booleans |
| overlap | overlap | an overlap state name (before, meets, overlaps, starts, containedBy, finishes, equals, after, metBy, overlappedBy, startedBy, contains, finishedBy, bothEmpty, firstEmpty, secondEmpty, undefined) | equal names |
| numeric | inf, sup, mid, rad, wid, mag, mig | a bound | equal numbers |
| unary | pos, neg, abs, recip, sqr, sqrt, exp, exp2, exp10, log, log2, log10, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh | interval | equal sets |
| ternary | fma | interval | equal sets |
| integer power | pown (second operand an integer) | interval | equal sets |
| binary | add, sub, mul, div, pow, atan2, min, max, intersection, convexHull, cancelPlus, cancelMinus | interval | equal sets |
“Equal sets” means: both NaI, or both empty, or equal lower bounds and equal
upper bounds (compared numerically, so ). When the expected text
contains _, the decorations must also be equal. The boolean dispatch is
chosen whenever the expected text is true or false.
Dispositions:
Executablewhen the case was run;passed()tells the outcome;Unsupported(reason)for an unknown operation, a binary-dispatch case whose expected value is not an interval (for example one followed by asignalannotation), a binary-dispatch case with other than two operands, or a binary boolean predicate whose second operand is missing or unreadable;Diagnostic(reason)when the first operand of a boolean case, or an operand or the expected value of the overlap, numeric, unary, ternary or integer-power dispatch, cannot be read, or an operand of the binary dispatch is not an interval literal.
execute_case does not abort on case content.
summarize_results
summarize_results(results) counts a list of results.
pub fn summarize_results(Array[ItlResult]) -> RunSummary
total_cases is the length of the list.
Results
ItlDisposition
ItlDisposition says whether a case was executed.
pub(all) enum ItlDisposition {
Executable
Unsupported(String)
Diagnostic(String)
}
ItlResult
ItlResult is the outcome of one case.
pub struct ItlResult {
// private fields
}
ItlResult::id, disposition, passed, message
These methods return the case id, the disposition, whether the case passed,
and a message: empty on success, "expected E, got A" on a mismatch (intervals
printed by BallFloatDecorated::to_string), and a short reason or the
offending text otherwise.
pub fn ItlResult::id(Self) -> String
pub fn ItlResult::disposition(Self) -> ItlDisposition
pub fn ItlResult::passed(Self) -> Bool
pub fn ItlResult::message(Self) -> String
RunSummary
RunSummary aggregates a list of results.
pub struct RunSummary {
// private fields
}
RunSummary counters and results
These methods return the counts, a copy of the results, and the overall verdict.
pub fn RunSummary::total_cases(Self) -> Int
pub fn RunSummary::executable_cases(Self) -> Int
pub fn RunSummary::passed_cases(Self) -> Int
pub fn RunSummary::failed_cases(Self) -> Int
pub fn RunSummary::unsupported_cases(Self) -> Int
pub fn RunSummary::diagnostic_cases(Self) -> Int
pub fn RunSummary::results(Self) -> Array[ItlResult]
pub fn RunSummary::success(Self) -> Bool
and
. success() is true when
no executable case failed and there is no diagnostic case; unsupported
cases do not affect it.
///|
test "itl summary" {
let source =
#|testcase s {
#| sub [1.0,2.0] [3.0,4.0] = [-3.0,-1.0];
#| sqr [-2.0,1.0] = [0.0,4.0];
#| mid [1.0,2.0] = 1.5;
#| isEmpty [empty] = true;
#|}
let summary = @itl_expr.summarize_results(
@itl_expr.parse_itl(source).unwrap().map(c => @itl_expr.execute_case(c)),
)
inspect(summary.total_cases(), content="4")
inspect(summary.passed_cases(), content="4")
}
Trait implementations
ItlCase::equal, ItlCase::not_equal, ItlCase::to_repr
These methods compare all fields of two cases and render a case for Debug.
Use ==, != and debug_inspect in new code.
pub fn ItlCase::equal(Self, Self) -> Bool
pub fn ItlCase::not_equal(Self, Self) -> Bool
pub fn ItlCase::to_repr(Self) -> @debug.Repr
Complete public interface
This snapshot is the generated pkg.generated.mbti of the package. It is the authority when prose and interface disagree.
// Generated using `moon info`, DON'T EDIT IT
package "Luna-Flow/floating/frontend/itl_expr"
import {
"moonbitlang/core/debug",
}
// Values
pub fn execute_case(ItlCase, precision? : Int) -> ItlResult
pub fn parse_itl(String) -> Result[Array[ItlCase], Array[String]]
pub fn summarize_results(Array[ItlResult]) -> RunSummary
// Errors
// Types and methods
pub struct ItlCase {
// private fields
} derive(Eq, @debug.Debug)
pub fn ItlCase::equal(Self, Self) -> Bool
pub fn ItlCase::expected(Self) -> String
pub fn ItlCase::id(Self) -> String
pub fn ItlCase::not_equal(Self, Self) -> Bool
pub fn ItlCase::operands(Self) -> Array[String]
pub fn ItlCase::operation(Self) -> String
pub fn ItlCase::to_repr(Self) -> @debug.Repr
pub(all) enum ItlDisposition {
Executable
Unsupported(String)
Diagnostic(String)
}
pub struct ItlResult {
// private fields
}
pub fn ItlResult::disposition(Self) -> ItlDisposition
pub fn ItlResult::id(Self) -> String
pub fn ItlResult::message(Self) -> String
pub fn ItlResult::passed(Self) -> Bool
pub struct RunSummary {
// private fields
}
pub fn RunSummary::diagnostic_cases(Self) -> Int
pub fn RunSummary::executable_cases(Self) -> Int
pub fn RunSummary::failed_cases(Self) -> Int
pub fn RunSummary::passed_cases(Self) -> Int
pub fn RunSummary::results(Self) -> Array[ItlResult]
pub fn RunSummary::success(Self) -> Bool
pub fn RunSummary::total_cases(Self) -> Int
pub fn RunSummary::unsupported_cases(Self) -> Int
// Type aliases
// Traits