283 keep order of chain specific outputs#285
Conversation
crates/tx3-lang/src/ast.rs
Outdated
| pub optional: bool, | ||
| pub fields: Vec<OutputBlockField>, | ||
| pub span: Span, | ||
| pub declared_index: Option<usize>, |
There was a problem hiding this comment.
why declared_index instead of index?
is there a conflicting index which is not declared?
if not, rename it to just index
crates/tx3-lang/src/cardano.rs
Outdated
| data.insert( | ||
| "declared_index".to_string(), | ||
| ir::Expression::Number( | ||
| self.declared_index | ||
| .map(|x| x as i128) | ||
| .expect("Publish block must have a declaration index"), | ||
| ), | ||
| ); | ||
|
|
There was a problem hiding this comment.
The lowering phase should not be used for enforcing invariants.
If the user should be aware of the rule, then the analyze phase should check the rule.
The assertion of the rule should be applied when needed. In this case, the compiler should be then one erroring when the value is missing.
crates/tx3-lang/src/lowering.rs
Outdated
| datum, | ||
| amount, | ||
| optional: self.optional, | ||
| declared_index: ir::Expression::Number(declared_ix as i128), |
There was a problem hiding this comment.
why do we use an explicit expression type?
Why can't we rely on the into_lower method as we do with the rest of the fields?
crates/tx3-lang/src/parsing.rs
Outdated
| Rule::output_block => { | ||
| let mut ob = OutputBlock::parse(item)?; | ||
| ob.declared_index = Some(declared_index); | ||
| declared_index += 1; | ||
| outputs.push(ob); |
There was a problem hiding this comment.
this shouldn't be here. We're coupling the rules of a specifc type of AST in the parsing logic of a totally unrelated block.
On top of that, the AST is not in charge of defining the indexes of the outputs. The AST describes the intent of the user that typed the code. The index expression should remain as an optional expression all the way down until the compiler is forced to add a value.
crates/tx3-lang/src/parsing.rs
Outdated
| Rule::chain_specific_block => { | ||
| let mut csb = ChainSpecificBlock::parse(item)?; | ||
| let ChainSpecificBlock::Cardano(cardano_block) = &mut csb; | ||
| if let crate::cardano::CardanoBlock::Publish(pb) = cardano_block { | ||
| pb.declared_index = Some(declared_index); | ||
| declared_index += 1; | ||
| } | ||
|
|
||
| adhoc.push(csb); |
There was a problem hiding this comment.
same as previous comment.
…in-specific-outputs
This pull request introduces the concept of a "declared index" for transaction outputs and Cardano publish directives, ensuring their original order is preserved throughout parsing, lowering, compilation, and serialization. The declared index is now tracked in the AST, IR, and final output structures, and is included in all relevant test fixtures and example files. This change enables deterministic ordering of outputs, which is critical for correct transaction construction and downstream processing.
Core logic and data model changes:
declared_indexfield toOutputBlockandCardanoPublishBlockin the AST, and ensured it is set during parsing to reflect the order in which outputs and directives are declared.declared_indexfor sorting outputs, ensuring the final transaction outputs are in the correct order.Parsing and lowering enhancements:
Modified the AST parsing logic for outputs and Cardano-specific blocks to assign and increment
declared_indexas each output or directive is encountered.Ensured that the lowering phase includes the
declared_indexin the IR representations.Test and example updates:
Updated all relevant test cases and example files to include the new
declared_indexfield, ensuring consistency and coverage for the new behavior.These changes collectively ensure that output and directive ordering is explicit and robust throughout the transaction lifecycle.