github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/equity/compiler/ast.go (about)

     1  package compiler
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	chainjson "github.com/bytom/bytom/encoding/json"
    10  )
    11  
    12  // Contract is a compiled Equity contract.
    13  type Contract struct {
    14  	// Name is the contract name.
    15  	Name string `json:"name"`
    16  
    17  	// Params is the list of contract parameters.
    18  	Params []*Param `json:"params,omitempty"`
    19  
    20  	// Clauses is the list of contract clauses.
    21  	Clauses []*Clause `json:"clauses"`
    22  
    23  	// Value is the name of the value locked by the contract.
    24  	Value ValueInfo `json:"value"`
    25  
    26  	// Body is the optimized bytecode of the contract body. This is not
    27  	// a complete program!  Use instantiate to turn this (plus some
    28  	// arguments) into a program.
    29  	Body chainjson.HexBytes `json:"body_bytecode"`
    30  
    31  	// Opcodes is the human-readable string of opcodes corresponding to
    32  	// Body.
    33  	Opcodes string `json:"body_opcodes,omitempty"`
    34  
    35  	// Recursive tells whether this contract calls itself.  (This is
    36  	// used to select between two possible instantiation options.)
    37  	Recursive bool `json:"recursive"`
    38  
    39  	// Pre-optimized list of instruction steps, with stack snapshots.
    40  	Steps []Step `json:"-"`
    41  }
    42  
    43  // Param is a contract or clause parameter.
    44  type Param struct {
    45  	// Name is the parameter name.
    46  	Name string `json:"name"`
    47  
    48  	// Type is the declared parameter type.
    49  	Type typeDesc `json:"type"`
    50  
    51  	// InferredType, if available, is a more-specific type than Type,
    52  	// inferred from the logic of the contract.
    53  	InferredType typeDesc `json:"inferred_type,omitempty"`
    54  }
    55  
    56  // Clause is a compiled contract clause.
    57  type Clause struct {
    58  	// Name is the clause name.
    59  	Name string `json:"name"`
    60  
    61  	// Params is the list of clause parameters.
    62  	Params []*Param `json:"params,omitempty"`
    63  
    64  	statements []statement
    65  
    66  	// BlockHeight is the list of expressions passed to greater()/less() in this
    67  	// clause.
    68  	BlockHeight []string `json:"blockheight,omitempty"`
    69  
    70  	// HashCalls is the list of hash functions and their arguments used
    71  	// in this clause.
    72  	HashCalls []HashCall `json:"hash_calls,omitempty"`
    73  
    74  	// Values is the list of values unlocked or relocked in this clause.
    75  	Values []ValueInfo `json:"values"`
    76  
    77  	// Contracts is the list of contracts called by this clause.
    78  	Contracts []string `json:"contracts,omitempty"`
    79  }
    80  
    81  // HashCall describes a call to a hash function.
    82  type HashCall struct {
    83  	// HashType is "sha3" or "sha256".
    84  	HashType string `json:"hash_type"`
    85  
    86  	// Arg is the expression passed to the hash function.
    87  	Arg string `json:"arg"`
    88  
    89  	// ArgType is the type of Arg.
    90  	ArgType string `json:"arg_type"`
    91  }
    92  
    93  // IfBody describes a if ... else ... struct
    94  type IfStatmentBody struct {
    95  	// if statements body
    96  	trueBody []statement
    97  
    98  	// else statements body
    99  	falseBody []statement
   100  }
   101  
   102  type statement interface {
   103  	countVarRefs(map[string]int)
   104  }
   105  
   106  type defineStatement struct {
   107  	variable *Param
   108  	expr     expression
   109  }
   110  
   111  func (s defineStatement) countVarRefs(counts map[string]int) {
   112  	s.expr.countVarRefs(counts)
   113  }
   114  
   115  type assignStatement struct {
   116  	variable *Param
   117  	expr     expression
   118  }
   119  
   120  func (s assignStatement) countVarRefs(counts map[string]int) {
   121  	s.expr.countVarRefs(counts)
   122  }
   123  
   124  type ifStatement struct {
   125  	condition expression
   126  	body      *IfStatmentBody
   127  }
   128  
   129  func (s ifStatement) countVarRefs(counts map[string]int) {
   130  	s.condition.countVarRefs(counts)
   131  }
   132  
   133  type verifyStatement struct {
   134  	expr expression
   135  }
   136  
   137  func (s verifyStatement) countVarRefs(counts map[string]int) {
   138  	s.expr.countVarRefs(counts)
   139  }
   140  
   141  type lockStatement struct {
   142  	lockedAmount expression
   143  	lockedAsset  expression
   144  	program      expression
   145  
   146  	// Added as a decoration, used by CHECKOUTPUT
   147  	index int64
   148  }
   149  
   150  func (s lockStatement) countVarRefs(counts map[string]int) {
   151  	s.lockedAmount.countVarRefs(counts)
   152  	s.lockedAsset.countVarRefs(counts)
   153  	s.program.countVarRefs(counts)
   154  }
   155  
   156  type unlockStatement struct {
   157  	unlockedAmount expression
   158  	unlockedAsset  expression
   159  }
   160  
   161  func (s unlockStatement) countVarRefs(counts map[string]int) {
   162  	s.unlockedAmount.countVarRefs(counts)
   163  	s.unlockedAsset.countVarRefs(counts)
   164  }
   165  
   166  type expression interface {
   167  	String() string
   168  	typ(*environ) typeDesc
   169  	countVarRefs(map[string]int)
   170  }
   171  
   172  type binaryExpr struct {
   173  	left, right expression
   174  	op          *binaryOp
   175  }
   176  
   177  func (e binaryExpr) String() string {
   178  	return fmt.Sprintf("(%s %s %s)", e.left, e.op.op, e.right)
   179  }
   180  
   181  func (e binaryExpr) typ(*environ) typeDesc {
   182  	return e.op.result
   183  }
   184  
   185  func (e binaryExpr) countVarRefs(counts map[string]int) {
   186  	e.left.countVarRefs(counts)
   187  	e.right.countVarRefs(counts)
   188  }
   189  
   190  type unaryExpr struct {
   191  	op   *unaryOp
   192  	expr expression
   193  }
   194  
   195  func (e unaryExpr) String() string {
   196  	return fmt.Sprintf("%s%s", e.op.op, e.expr)
   197  }
   198  
   199  func (e unaryExpr) typ(*environ) typeDesc {
   200  	return e.op.result
   201  }
   202  
   203  func (e unaryExpr) countVarRefs(counts map[string]int) {
   204  	e.expr.countVarRefs(counts)
   205  }
   206  
   207  type callExpr struct {
   208  	fn   expression
   209  	args []expression
   210  }
   211  
   212  func (e callExpr) String() string {
   213  	var argStrs []string
   214  	for _, a := range e.args {
   215  		argStrs = append(argStrs, a.String())
   216  	}
   217  	return fmt.Sprintf("%s(%s)", e.fn, strings.Join(argStrs, ", "))
   218  }
   219  
   220  func (e callExpr) typ(env *environ) typeDesc {
   221  	if b := referencedBuiltin(e.fn); b != nil {
   222  		switch b.name {
   223  		case "sha3":
   224  			if len(e.args) == 1 {
   225  				switch e.args[0].typ(env) {
   226  				case strType:
   227  					return sha3StrType
   228  				case pubkeyType:
   229  					return sha3PubkeyType
   230  				}
   231  			}
   232  
   233  		case "sha256":
   234  			if len(e.args) == 1 {
   235  				switch e.args[0].typ(env) {
   236  				case strType:
   237  					return sha256StrType
   238  				case pubkeyType:
   239  					return sha256PubkeyType
   240  				}
   241  			}
   242  		}
   243  
   244  		return b.result
   245  	}
   246  	if e.fn.typ(env) == predType {
   247  		return boolType
   248  	}
   249  	if e.fn.typ(env) == contractType {
   250  		return progType
   251  	}
   252  	return nilType
   253  }
   254  
   255  func (e callExpr) countVarRefs(counts map[string]int) {
   256  	e.fn.countVarRefs(counts)
   257  	for _, a := range e.args {
   258  		a.countVarRefs(counts)
   259  	}
   260  }
   261  
   262  type varRef string
   263  
   264  func (v varRef) String() string {
   265  	return string(v)
   266  }
   267  
   268  func (e varRef) typ(env *environ) typeDesc {
   269  	if entry := env.lookup(string(e)); entry != nil {
   270  		return entry.t
   271  	}
   272  	return nilType
   273  }
   274  
   275  func (e varRef) countVarRefs(counts map[string]int) {
   276  	counts[string(e)]++
   277  }
   278  
   279  type bytesLiteral []byte
   280  
   281  func (e bytesLiteral) String() string {
   282  	return "0x" + hex.EncodeToString([]byte(e))
   283  }
   284  
   285  func (bytesLiteral) typ(*environ) typeDesc {
   286  	return "String"
   287  }
   288  
   289  func (bytesLiteral) countVarRefs(map[string]int) {}
   290  
   291  type integerLiteral int64
   292  
   293  func (e integerLiteral) String() string {
   294  	return strconv.FormatInt(int64(e), 10)
   295  }
   296  
   297  func (integerLiteral) typ(*environ) typeDesc {
   298  	return "Integer"
   299  }
   300  
   301  func (integerLiteral) countVarRefs(map[string]int) {}
   302  
   303  type booleanLiteral bool
   304  
   305  func (e booleanLiteral) String() string {
   306  	if e {
   307  		return "true"
   308  	}
   309  	return "false"
   310  }
   311  
   312  func (booleanLiteral) typ(*environ) typeDesc {
   313  	return "Boolean"
   314  }
   315  
   316  func (booleanLiteral) countVarRefs(map[string]int) {}
   317  
   318  type listExpr []expression
   319  
   320  func (e listExpr) String() string {
   321  	var elts []string
   322  	for _, elt := range e {
   323  		elts = append(elts, elt.String())
   324  	}
   325  	return fmt.Sprintf("[%s]", strings.Join(elts, ", "))
   326  }
   327  
   328  func (listExpr) typ(*environ) typeDesc {
   329  	return "List"
   330  }
   331  
   332  func (e listExpr) countVarRefs(counts map[string]int) {
   333  	for _, elt := range e {
   334  		elt.countVarRefs(counts)
   335  	}
   336  }