return nil
}
+func countsVarRef(stat statement, counts map[string]int) map[string]int {
+ if stmt, ok := stat.(*defineStatement); ok && stmt.expr == nil {
+ return counts
+ }
+
+ if _, ok := stat.(*unlockStatement); ok {
+ return counts
+ }
+
+ stat.countVarRefs(counts)
+ if stmt, ok := stat.(*ifStatement); ok {
+ for _, trueStmt := range stmt.body.trueBody {
+ counts = countsVarRef(trueStmt, counts)
+ }
+
+ for _, falseStmt := range stmt.body.falseBody {
+ counts = countsVarRef(falseStmt, counts)
+ }
+ }
+
+ return counts
+}
+
func assignIndexes(clause *Clause) error {
var nextIndex int64
for i, stmt := range clause.statements {
// a count of the number of times each variable is referenced
counts := make(map[string]int)
- for _, s := range clause.statements {
- if stmt, ok := s.(*defineStatement); ok && stmt.expr == nil {
- continue
- }
-
- s.countVarRefs(counts)
- if stmt, ok := s.(*ifStatement); ok {
- for _, trueStmt := range stmt.body.trueBody {
- trueStmt.countVarRefs(counts)
- }
-
- for _, falseStmt := range stmt.body.falseBody {
- falseStmt.countVarRefs(counts)
- }
- }
+ for _, stat := range clause.statements {
+ counts = countsVarRef(stat, counts)
}
for _, stat := range clause.statements {
*sequence++
strSequence := fmt.Sprintf("%d", *sequence)
+ // compile the contract valueAmount and valueAsset for expression
+ stk, counts = compileContractValue(b, stmt.condition, contract.Value, stk, counts)
+
// compile condition expression
stk, err = compileExpr(b, stk, contract, clause, env, counts, stmt.condition)
if err != nil {
}
if stmt.expr != nil {
+ // compile the contract valueAmount and valueAsset for expression
+ stk, counts = compileContractValue(b, stmt.expr, contract.Value, stk, counts)
+
// variable
stk, err = compileExpr(b, stk, contract, clause, env, counts, stmt.expr)
if err != nil {
stk = b.addDrop(stk)
}
+ // compile the contract valueAmount and valueAsset for expression
+ stk, counts = compileContractValue(b, stmt.expr, contract.Value, stk, counts)
+
// variable
stk, err = compileExpr(b, stk, contract, clause, env, counts, stmt.expr)
if err != nil {
stk.str = stmt.variable.Name
case *verifyStatement:
+ // compile the contract valueAmount and valueAsset for expression
+ stk, counts = compileContractValue(b, stmt.expr, contract.Value, stk, counts)
+
stk, err = compileExpr(b, stk, contract, clause, env, counts, stmt.expr)
if err != nil {
return stk, errors.Wrapf(err, "in verify statement in clause \"%s\"", clause.Name)
return stk, 1, err
}
+func compileContractValue(b *builder, expr expression, contractValue ValueInfo, stk stack, counts map[string]int) (stack, map[string]int) {
+ valueCounts := make(map[string]int)
+ expr.countVarRefs(valueCounts)
+ if valueCounts[contractValue.Amount] > 0 {
+ counts[contractValue.Amount] = valueCounts[contractValue.Amount]
+ stk = b.addAmount(stk, contractValue.Amount)
+ }
+
+ if valueCounts[contractValue.Asset] > 0 {
+ counts[contractValue.Asset] = valueCounts[contractValue.Asset]
+ stk = b.addAsset(stk, contractValue.Asset)
+ }
+
+ return stk, counts
+}
+
func compileRef(b *builder, stk stack, counts map[string]int, ref varRef) (stack, error) {
depth := stk.find(string(ref))
if depth < 0 {