Skip to content

v1.3.1

Choose a tag to compare

@github-actions github-actions released this 05 Mar 21:54
· 5 commits to main since this release

go-simplicity v1.3.1

SimplicityHL 0.3.0 Compatibility

This release fixes all grammar and semantic incompatibilities with the deployed SimplicityHL IDE (SimplicityHL 0.3.0, Pest-based parser). Generated .shl programs now parse, type-check, and compile without errors.


Breaking Changes (output only)

Generated .shl output has changed. Source .go contracts require no modifications.

  • jet::verify(expr) → assert!(expr) everywhere
  • jet::eq_128(a, b) → eq_128(a, b) (user-defined helper function)
  • jet::le_128(a, b) → le_128(a, b) (user-defined helper function)
  • jet::lt_128(a, b) → lt_128(a, b) (user-defined helper function)
  • Intermediate variable prefixes changed: __ → c_ / o_
  • Match arm bindings now include type annotations: Left(data) → Left(data: Type)

Fixes

Identifiers must start with a letter

SimplicityHL's Pest grammar: identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }. Variables prefixed with __ (e.g., __total_supply_conf) were invalid. Fixed by using c_ prefix for confidential-value intermediates and o_ prefix for option intermediates.

Match arm trailing commas

SimplicityHL requires trailing commas on single-expression match arms: Right(v: u64) => v,. All buildLiquidJetLines() match arms now include mandatory trailing commas.

jet::verify() does not exist

SimplicityHL 0.3.0 uses the builtin assert!(expr) instead of jet::verify(expr). A new formatJetCallExpr() helper maps verify → assert!() across all code generation paths (standalone calls, let bindings, multisig counter code).

Match arm bindings require type annotations

SimplicityHL requires typed bindings in match arms: Left(x: (u1, u256)), Right(v: u64), Some(v: Asset1). The generateMatchExpression() function now emits VarType when available.

No native u128 comparison jets

SimplicityHL 0.3.0 provides eq_64, le_64, lt_64 and eq_256 — but no eq_128, le_128, or lt_128. The transpiler now emits user-defined helper functions that decompose u128 into (u64, u64) via <u128>::into() and compare piecewise:

fn le_128(a: u128, b: u128) -> bool {
    let (ah, al): (u64, u64) = <u128>::into(a);
    let (bh, bl): (u64, u64) = <u128>::into(b);
    match jet::lt_64(ah, bh) {
        true => true,
        false => {
            match jet::eq_64(ah, bh) {
                true => jet::le_64(al, bl),
                false => false,
            }
        }
    }
}

Helper functions are emitted only when needed — the transpiler scans jet calls and match arm bodies to determine which helpers (eq_128, le_128, lt_128) are required.

Witness values are linear

SimplicityHL treats witness values as linear resources — each witness::NAME reference can only be consumed once. The transpiler now detects witnesses referenced multiple times and emits a let binding at the top of fn main(), replacing all subsequent references with the local variable.


Transpiler Changes

cmd/simgo/main.go

  • Version bump to 1.3.1

pkg/transpiler/transpiler.go (+406 / -28 lines)

  • New formatJetCallExpr() — routes verify → assert!(), u128 compare jets → helper function calls, all others → jet::name()
  • New u128CompareJets map — identifies jets that need helper function treatment
  • New u128HelperFunctions() — generates eq_128, le_128, lt_128 SimplicityHL function definitions using <u128>::into() for type casting
  • New deduplicateWitnessRefs() — scans jet calls and match arms for multi-use witnesses, emits local bindings, replaces references
  • buildLiquidJetLines() — c_ / o_ variable prefixes, trailing commas on all single-expression match arms, _ wildcard for discarded tuple elements
  • writeLetBinding() — uses formatJetCallExpr(), _ wildcard for carry-tuple destructuring
  • analyzeArmBodyStmt() — same carry-tuple and jet formatting fixes
  • evaluateJetArg() — i_inline prefix for inline temporaries (was __inline)
  • generateCode() — scans jet calls for u128 helper usage, emits helper functions between param module and fn main()
  • generateMainFunction() — calls deduplicateWitnessRefs() before any code emission; all standalone call paths use formatJetCallExpr()
  • generateMultisigMatchCode() — assert!() instead of jet::verify()

pkg/transpiler/patterns.go

  • generateMatchExpression() — emits typed match arm bindings (VarType field); adds semicolons to body statements that lack them

Tests

tests/jet_test.go

  • TestV12AMMInvariantCompilation — updated to check for le_128( helper call and fn le_128( helper definition instead of jet::le_128
  • TestBooleanIfElse — updated to check for le_128( helper call and fn le_128( helper definition
  • TestComparisonJets — jet::verify → assert!
  • TestBooleanIfElseWithSubtract — jet::verify → assert!

tests/examples_test.go

  • All match arm checks updated: Left(data) → Left(data:, Right(sig) → Right(sig:, Some(sig) → Some(sig:
  • Multisig final verify: jet::verify(jet::le_32(...)) → assert!(jet::le_32(...))

tests/parser_test.go

  • Match arm binding assertions updated for typed annotations

SimplicityHL 0.3.0 Grammar Reference

Key rules that drove these fixes (from Pest grammar):

Rule Constraint
identifier Must start with ASCII_ALPHA, not _
match_arm Single expressions require trailing ,
call_name assert is a builtin; no verify jet
type_cast <SourceType>::into(expr) — source type, not target
match_pattern Only Left/Right/Some/None/true/false — no tuple patterns

Binaries

File OS Arch
simgo-windows-amd64.exe Windows x86-64
simgo-linux-amd64 Linux x86-64
simgo-darwin-arm64 macOS Apple Silicon
simgo-darwin-amd64 macOS Intel

Full Changelog: v1.3.0...v1.3.1