return false
}
-func requireAllValuesDisposedOnce(contract *Contract, clause *Clause) error {
- err := valueDisposedOnce(contract.Value, clause)
- if err != nil {
- return err
+func referencedBuiltin(expr expression) *builtin {
+ if v, ok := expr.(varRef); ok {
+ for _, b := range builtins {
+ if string(v) == b.name {
+ return &b
+ }
+ }
}
return nil
}
-func valueDisposedOnce(value ValueInfo, clause *Clause) error {
- var count int
- for _, stmt := range clause.statements {
- count = valueDisposedCount(value, stmt, count)
+func countsVarRef(stat statement, counts map[string]int) map[string]int {
+ if stmt, ok := stat.(*defineStatement); ok && stmt.expr == nil {
+ return counts
}
- switch count {
- case -1:
- return fmt.Errorf("valueAmount \"%s\" and valueAsset \"%s\" used times is not equal between if and else statement in clause \"%s\"",
- value.Amount, value.Asset, clause.Name)
- case 0:
- return fmt.Errorf("valueAmount \"%s\" or valueAsset \"%s\" not disposed in clause \"%s\"", value.Amount, value.Asset, clause.Name)
- case 1:
- return nil
- default:
- return fmt.Errorf("valueAmount \"%s\" or valueAsset \"%s\" disposed multiple times in clause \"%s\"", value.Amount, value.Asset, clause.Name)
+
+ if _, ok := stat.(*unlockStatement); ok {
+ return counts
}
-}
-func valueDisposedCount(value ValueInfo, stat statement, count int) int {
- switch stmt := stat.(type) {
- case *ifStatement:
- var trueCount int
- var falseCount int
+ stat.countVarRefs(counts)
+ if stmt, ok := stat.(*ifStatement); ok {
for _, trueStmt := range stmt.body.trueBody {
- trueCount = valueDisposedCount(value, trueStmt, count)
+ counts = countsVarRef(trueStmt, counts)
}
for _, falseStmt := range stmt.body.falseBody {
- falseCount = valueDisposedCount(value, falseStmt, count)
- }
-
- if trueCount != falseCount {
- return -1
- }
- count = trueCount
-
- case *unlockStatement:
- if references(stmt.unlockedAmount, value.Amount) && references(stmt.unlockedAsset, value.Asset) {
- count++
- }
- case *lockStatement:
- if references(stmt.lockedAmount, value.Amount) && references(stmt.lockedAsset, value.Asset) {
- count++
+ counts = countsVarRef(falseStmt, counts)
}
}
- return count
-}
-
-func referencedBuiltin(expr expression) *builtin {
- if v, ok := expr.(varRef); ok {
- for _, b := range builtins {
- if string(v) == b.name {
- return &b
- }
- }
- }
- return nil
+ return counts
}
func assignIndexes(clause *Clause) error {