use super::{BenchmarkDeclaration, Budgets, ContentionPosture, Row, WorkFormula};
use crate::bounded::Overflow;
use crate::descriptor::emitting::row_metavariable;
use crate::descriptor::trial::{named_clause, table_schema_identity};
use crate::descriptor::vocabulary::{self, HarnessName, HarnessWord};
use crate::descriptor::{Emitter, Name};
use crate::stamp::{Visibility, declared_reach_tokens};
use crate::token::{
GeneratedDelimiter, GeneratedToken, bound_local, call, comma, comma_many, constant,
documentation, group, metavariable, method_chain, roster, text_pair,
};
const WORKLOAD_LOCAL: &str = "workload";
const PREFLIGHT_LOCAL: &str = "preflight";
const PLANTED_WORSE_LOCAL: &str = "planted_worse";
const COMPLEXITY_LOCAL: &str = "complexity";
const ROW_LOCAL: &str = "row";
const ATTACHMENT_LOCAL: &str = "attachment";
const REPORT: &str = "REPORT";
fn parsed(reference: HarnessName, name: &Name) -> Result<Vec<GeneratedToken>, Overflow> {
let mut tokens = vocabulary::road(
&[HarnessName::Bench, reference, HarnessName::Named],
text_pair(name.namespace(), name.stem()),
)?;
tokens.push(GeneratedToken::alone('?'));
Ok(tokens)
}
#[must_use]
pub fn axis_literals(row: &Row) -> Vec<GeneratedToken> {
let mut sizes = Vec::new();
for size in row.axis() {
sizes.push(GeneratedToken::number(*size));
sizes.push(GeneratedToken::alone(','));
}
sizes
}
pub fn budgets(declared: &Budgets) -> Result<Vec<GeneratedToken>, Overflow> {
let mut tokens = vocabulary::road(
&[
HarnessName::Bench,
HarnessName::DeclaredBudgets,
HarnessName::Declared,
],
comma_many(vec![
vec![GeneratedToken::number(u64::from(declared.samples))],
vec![GeneratedToken::number(u64::from(declared.warmups))],
vec![GeneratedToken::number(declared.ratio_numerator)],
vec![GeneratedToken::number(declared.ratio_denominator)],
]),
)?;
tokens.push(GeneratedToken::alone('?'));
Ok(tokens)
}
#[must_use]
pub fn contention(posture: ContentionPosture) -> Vec<GeneratedToken> {
vocabulary::path(&[
HarnessName::Bench,
HarnessName::ContentionPosture,
posture.arm(),
])
}
pub fn work_formula(declared: Option<&WorkFormula>) -> Result<Vec<GeneratedToken>, Overflow> {
let Some(formula) = declared else {
return Ok(crate::token::absolute_path(&[
"core", "option", "Option", "None",
]));
};
let owned = method_chain(
vec![GeneratedToken::byte_text(formula.bytes())],
&["to_vec"],
)?;
let mut encoded = vocabulary::road(
&[
HarnessName::Bench,
HarnessName::WorkFormula,
HarnessName::Encoded,
],
owned,
)?;
encoded.push(GeneratedToken::alone('?'));
call(
crate::token::absolute_path(&["core", "option", "Option", "Some"]),
encoded,
)
}
pub fn observations(row: &Row) -> Result<Vec<GeneratedToken>, Overflow> {
let mut named = Vec::new();
for observation in row.observations() {
named.extend(parsed(HarnessName::WorkObservationRef, observation)?);
named.push(GeneratedToken::alone(','));
}
roster(named)
}
pub fn declared_row(row: &Row) -> Result<Vec<GeneratedToken>, Overflow> {
let references = call(
vocabulary::path(&[
HarnessName::Bench,
HarnessName::BenchReferences,
HarnessName::Declared,
]),
comma_many(vec![
vec![GeneratedToken::word(WORKLOAD_LOCAL)],
vec![GeneratedToken::word(PREFLIGHT_LOCAL)],
vec![GeneratedToken::word(PLANTED_WORSE_LOCAL)],
vec![GeneratedToken::word(COMPLEXITY_LOCAL)],
]),
)?;
let mut axis = vocabulary::road(
&[
HarnessName::Bench,
HarnessName::InputSizeAxis,
HarnessName::Declared,
],
roster(axis_literals(row))?,
)?;
axis.push(GeneratedToken::alone('?'));
let measurement = row.measurement();
let measurement = call(
vocabulary::path(&[
HarnessName::Bench,
HarnessName::BenchMeasurement,
HarnessName::Declared,
]),
comma_many(vec![
axis,
budgets(&measurement.budgets)?,
contention(measurement.contention),
work_formula(measurement.work_formula.as_ref())?,
]),
)?;
let mut tokens = call(
vocabulary::path(&[
HarnessName::Bench,
HarnessName::BenchRow,
HarnessName::Declared,
]),
comma(references, measurement),
)?;
tokens.push(GeneratedToken::alone('?'));
Ok(tokens)
}
pub fn row_expression(row: &Row) -> Result<Vec<GeneratedToken>, Overflow> {
let references = row.references();
let mut body = bound_local(
WORKLOAD_LOCAL,
parsed(HarnessName::WorkloadRef, &references.workload)?,
);
body.extend(bound_local(
PREFLIGHT_LOCAL,
parsed(HarnessName::PreflightRef, &references.correctness_preflight)?,
));
body.extend(bound_local(
PLANTED_WORSE_LOCAL,
parsed(HarnessName::PlantedWorseRef, &references.planted_worse)?,
));
body.extend(bound_local(
COMPLEXITY_LOCAL,
parsed(
HarnessName::ComplexityClaimRef,
&references.complexity_claim,
)?,
));
body.extend(bound_local(ROW_LOCAL, declared_row(row)?));
let lens = row.lens().spelling();
let mut attachment = vocabulary::road(
&[
HarnessName::Bench,
HarnessName::BenchAttachment,
HarnessName::Attached,
],
comma_many(vec![
vec![GeneratedToken::word(WORKLOAD_LOCAL)],
metavariable(&row_metavariable(lens, HarnessWord::Measured)),
vec![GeneratedToken::word(PLANTED_WORSE_LOCAL)],
metavariable(&row_metavariable(lens, HarnessWord::PlantedWorse)),
metavariable(&row_metavariable(lens, HarnessWord::Judge)),
observations(row)?,
]),
)?;
attachment.push(GeneratedToken::alone('?'));
body.extend(bound_local(ATTACHMENT_LOCAL, attachment));
body.extend(vocabulary::road(
&[
HarnessName::Bench,
HarnessName::BenchBinding,
HarnessName::Bound,
],
comma_many(vec![
vec![GeneratedToken::word(ROW_LOCAL)],
vec![GeneratedToken::word(ATTACHMENT_LOCAL)],
metavariable(&row_metavariable(lens, HarnessWord::Preflight)),
]),
)?);
Ok(vec![group(GeneratedDelimiter::Brace, body)?])
}
#[must_use]
pub fn matched_clauses(payload: &BenchmarkDeclaration) -> Vec<GeneratedToken> {
let mut clauses = crate::support::matched_clause(HarnessWord::Reporter.spelling(), "expr");
for row in payload.rows() {
let lens = row.lens().spelling();
for seat in [
HarnessWord::Measured,
HarnessWord::PlantedWorse,
HarnessWord::Judge,
HarnessWord::Preflight,
] {
clauses.extend(crate::support::matched_clause(
&row_metavariable(lens, seat),
"expr",
));
}
}
clauses
}
pub fn bench_table(
payload: &BenchmarkDeclaration,
emitter: Emitter,
) -> Result<Vec<GeneratedToken>, Overflow> {
let mut body = vocabulary::key(HarnessWord::Provenance);
body.extend(produced_provenance(emitter)?);
body.push(GeneratedToken::alone(','));
body.extend(vocabulary::key(HarnessWord::Bindings));
let mut bindings = Vec::new();
for row in payload.rows() {
bindings.extend(row_expression(row)?);
bindings.push(GeneratedToken::alone(','));
}
body.push(group(GeneratedDelimiter::Bracket, bindings)?);
body.push(GeneratedToken::alone(','));
let mut tokens = declared_reach_tokens(Visibility::Crate)?;
tokens.push(GeneratedToken::word("fn"));
tokens.push(GeneratedToken::word(payload.table_function().spelling()));
tokens.extend(named_clause(payload.table())?);
tokens.push(group(GeneratedDelimiter::Brace, body)?);
Ok(tokens)
}
fn produced_provenance(emitter: Emitter) -> Result<Vec<GeneratedToken>, Overflow> {
let mut producer = vocabulary::road(
&[
HarnessName::Descriptor,
HarnessName::ProducerName,
HarnessName::Named,
],
text_pair(emitter.namespace, emitter.producer),
)?;
producer.push(GeneratedToken::alone('?'));
let mut schema = table_schema_identity()?;
schema.push(GeneratedToken::alone('?'));
let mut fields = vocabulary::key(HarnessWord::Producer);
fields.extend(producer);
fields.push(GeneratedToken::alone(','));
fields.extend(vocabulary::key(HarnessWord::Schema));
fields.extend(schema);
fields.push(GeneratedToken::alone(','));
let mut tokens = vocabulary::path(&[
HarnessName::Descriptor,
HarnessName::ProvenanceType,
HarnessName::ProducedProvenance,
]);
tokens.push(group(GeneratedDelimiter::Brace, fields)?);
Ok(tokens)
}
pub fn reporter(payload: &BenchmarkDeclaration) -> Result<Vec<GeneratedToken>, Overflow> {
let mut report_type = vec![GeneratedToken::word("fn")];
let mut borrowed = vec![GeneratedToken::alone('&')];
borrowed.extend(vocabulary::path(&[
HarnessName::Bench,
HarnessName::BenchReport,
]));
report_type.push(group(GeneratedDelimiter::Parenthesis, borrowed)?);
let mut body = declared_reach_tokens(Visibility::Crate)?;
body.extend(constant(
REPORT,
report_type,
metavariable(HarnessWord::Reporter.spelling()),
));
let mut tokens = documentation(REPORTER_SENTENCE)?;
tokens.extend(declared_reach_tokens(Visibility::Crate)?);
tokens.push(GeneratedToken::word("mod"));
tokens.push(GeneratedToken::word(payload.reporter().module().spelling()));
tokens.push(group(GeneratedDelimiter::Brace, body)?);
Ok(tokens)
}
const REPORTER_SENTENCE: &str =
"The target-supplied reader for reports produced from this benchmark declaration.";