github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/vm/cvm/ast/stmt.go (about)

     1  package ast
     2  
     3  import (
     4  	"github.com/sixexorg/magnetic-ring/common/sink"
     5  )
     6  
     7  const (
     8  	stmtAssign      byte = 0x01
     9  	stmtLocalAssign byte = 0x02
    10  	stmtFuncCall    byte = 0x03
    11  	stmtDoBlock     byte = 0x04
    12  	stmtWhile       byte = 0x05
    13  	stmtRepeat      byte = 0x06
    14  	stmtIf          byte = 0x07
    15  	stmtNumberFor   byte = 0x08
    16  	stmtGenericFor  byte = 0x09
    17  	stmtFuncDef     byte = 0x0A
    18  	stmtReturn      byte = 0x0B
    19  	stmtBreak       byte = 0x0C
    20  )
    21  
    22  type Stmt interface {
    23  	PositionHolder
    24  	Serialization(sk *sink.ZeroCopySink)
    25  }
    26  
    27  type StmtBase struct {
    28  	Node
    29  }
    30  
    31  type AssignStmt struct {
    32  	StmtBase
    33  
    34  	Lhs []Expr
    35  	Rhs []Expr
    36  }
    37  
    38  type LocalAssignStmt struct {
    39  	StmtBase
    40  
    41  	Names []string
    42  	Exprs []Expr
    43  }
    44  
    45  type FuncCallStmt struct {
    46  	StmtBase
    47  
    48  	Expr Expr
    49  }
    50  
    51  type DoBlockStmt struct {
    52  	StmtBase
    53  
    54  	Stmts []Stmt
    55  }
    56  
    57  type WhileStmt struct {
    58  	StmtBase
    59  
    60  	Condition Expr
    61  	Stmts     []Stmt
    62  }
    63  
    64  type RepeatStmt struct {
    65  	StmtBase
    66  
    67  	Condition Expr
    68  	Stmts     []Stmt
    69  }
    70  
    71  type IfStmt struct {
    72  	StmtBase
    73  
    74  	Condition Expr
    75  	Then      []Stmt
    76  	Else      []Stmt
    77  }
    78  
    79  type NumberForStmt struct {
    80  	StmtBase
    81  
    82  	Name  string
    83  	Init  Expr
    84  	Limit Expr
    85  	Step  Expr
    86  	Stmts []Stmt
    87  }
    88  
    89  type GenericForStmt struct {
    90  	StmtBase
    91  
    92  	Names []string
    93  	Exprs []Expr
    94  	Stmts []Stmt
    95  }
    96  
    97  type FuncDefStmt struct {
    98  	StmtBase
    99  
   100  	Name *FuncName
   101  	Func *FunctionExpr
   102  }
   103  
   104  type ReturnStmt struct {
   105  	StmtBase
   106  
   107  	Exprs []Expr
   108  }
   109  
   110  type BreakStmt struct {
   111  	StmtBase
   112  }
   113  
   114  func (this *AssignStmt) Serialization(sk *sink.ZeroCopySink) {
   115  	sk.WriteByte(stmtAssign)
   116  	sk.WriteVarUint(uint64(this.CodeLine))
   117  	sk.WriteVarUint(uint64(this.CodeLastline))
   118  	sk.WriteVarUint(uint64(len(this.Lhs)))
   119  	for _, expr := range this.Lhs {
   120  		expr.Serialization(sk)
   121  	}
   122  	sk.WriteVarUint(uint64(len(this.Rhs)))
   123  	for _, expr := range this.Rhs {
   124  		expr.Serialization(sk)
   125  	}
   126  }
   127  func (this *LocalAssignStmt) Serialization(sk *sink.ZeroCopySink) {
   128  	sk.WriteByte(stmtLocalAssign)
   129  	sk.WriteVarUint(uint64(this.CodeLine))
   130  	sk.WriteVarUint(uint64(this.CodeLastline))
   131  	sk.WriteVarUint(uint64(len(this.Names)))
   132  	for _, name := range this.Names {
   133  		sk.WriteString(name)
   134  	}
   135  	sk.WriteVarUint(uint64(len(this.Exprs)))
   136  	for _, expr := range this.Exprs {
   137  		expr.Serialization(sk)
   138  	}
   139  }
   140  func (this *FuncCallStmt) Serialization(sk *sink.ZeroCopySink) {
   141  	sk.WriteByte(stmtFuncCall)
   142  	sk.WriteVarUint(uint64(this.CodeLine))
   143  	sk.WriteVarUint(uint64(this.CodeLastline))
   144  	this.Expr.Serialization(sk)
   145  }
   146  func (this *DoBlockStmt) Serialization(sk *sink.ZeroCopySink) {
   147  	sk.WriteByte(stmtDoBlock)
   148  	sk.WriteVarUint(uint64(this.CodeLine))
   149  	sk.WriteVarUint(uint64(this.CodeLastline))
   150  	sk.WriteVarUint(uint64(len(this.Stmts)))
   151  	for _, stmt := range this.Stmts {
   152  		stmt.Serialization(sk)
   153  	}
   154  }
   155  func (this *WhileStmt) Serialization(sk *sink.ZeroCopySink) {
   156  	sk.WriteByte(stmtWhile)
   157  	sk.WriteVarUint(uint64(this.CodeLine))
   158  	sk.WriteVarUint(uint64(this.CodeLastline))
   159  	this.Condition.Serialization(sk)
   160  	sk.WriteVarUint(uint64(len(this.Stmts)))
   161  	for _, stmt := range this.Stmts {
   162  		stmt.Serialization(sk)
   163  	}
   164  }
   165  func (this *RepeatStmt) Serialization(sk *sink.ZeroCopySink) {
   166  	sk.WriteByte(stmtRepeat)
   167  	sk.WriteVarUint(uint64(this.CodeLine))
   168  	sk.WriteVarUint(uint64(this.CodeLastline))
   169  	// Condition
   170  	this.Condition.Serialization(sk)
   171  	// Stmts
   172  	sk.WriteVarUint(uint64(len(this.Stmts)))
   173  	for _, stmt := range this.Stmts {
   174  		stmt.Serialization(sk)
   175  	}
   176  }
   177  func (this *IfStmt) Serialization(sk *sink.ZeroCopySink) {
   178  	sk.WriteByte(stmtIf)
   179  	sk.WriteVarUint(uint64(this.CodeLine))
   180  	sk.WriteVarUint(uint64(this.CodeLastline))
   181  	// Condition
   182  	this.Condition.Serialization(sk)
   183  	// Then
   184  	sk.WriteVarUint(uint64(len(this.Then)))
   185  	for _, stmt := range this.Then {
   186  		stmt.Serialization(sk)
   187  	}
   188  	// Else
   189  	sk.WriteVarUint(uint64(len(this.Else)))
   190  	for _, stmt := range this.Else {
   191  		stmt.Serialization(sk)
   192  	}
   193  }
   194  func (this *NumberForStmt) Serialization(sk *sink.ZeroCopySink) {
   195  	sk.WriteByte(stmtNumberFor)
   196  	sk.WriteVarUint(uint64(this.CodeLine))
   197  	sk.WriteVarUint(uint64(this.CodeLastline))
   198  	// Name
   199  	sk.WriteString(this.Name)
   200  	// Init
   201  	this.Init.Serialization(sk)
   202  	// Limit
   203  	this.Limit.Serialization(sk)
   204  	// Step
   205  	this.Step.Serialization(sk)
   206  	// Stmts
   207  	for _, stmt := range this.Stmts {
   208  		stmt.Serialization(sk)
   209  	}
   210  }
   211  func (this *GenericForStmt) Serialization(sk *sink.ZeroCopySink) {
   212  	sk.WriteByte(stmtGenericFor)
   213  	sk.WriteVarUint(uint64(this.CodeLine))
   214  	sk.WriteVarUint(uint64(this.CodeLastline))
   215  	// Names
   216  	sk.WriteVarUint(uint64(len(this.Names)))
   217  	for _, name := range this.Names {
   218  		sk.WriteString(name)
   219  	}
   220  	// Exprs
   221  	sk.WriteVarUint(uint64(len(this.Exprs)))
   222  	for _, expr := range this.Exprs {
   223  		expr.Serialization(sk)
   224  	}
   225  	// Stmts
   226  	sk.WriteVarUint(uint64(len(this.Stmts)))
   227  	for _, stmt := range this.Stmts {
   228  		stmt.Serialization(sk)
   229  	}
   230  }
   231  func (this *FuncDefStmt) Serialization(sk *sink.ZeroCopySink) {
   232  	sk.WriteByte(stmtFuncDef)
   233  	sk.WriteVarUint(uint64(this.CodeLine))
   234  	sk.WriteVarUint(uint64(this.CodeLastline))
   235  	// Name
   236  	this.Name.Serialization(sk)
   237  	// Func
   238  	this.Func.Serialization(sk)
   239  }
   240  func (this *ReturnStmt) Serialization(sk *sink.ZeroCopySink) {
   241  	sk.WriteByte(stmtReturn)
   242  	sk.WriteVarUint(uint64(this.CodeLine))
   243  	sk.WriteVarUint(uint64(this.CodeLastline))
   244  	sk.WriteVarUint(uint64(len(this.Exprs)))
   245  	for _, expr := range this.Exprs {
   246  		expr.Serialization(sk)
   247  	}
   248  }
   249  func (this *BreakStmt) Serialization(sk *sink.ZeroCopySink) {
   250  	sk.WriteByte(stmtBreak)
   251  	sk.WriteVarUint(uint64(this.CodeLine))
   252  	sk.WriteVarUint(uint64(this.CodeLastline))
   253  }
   254  
   255  func StmtDeserialize(source *sink.ZeroCopySource) (stmt Stmt, err error) {
   256  
   257  	t, _ := source.NextByte()
   258  	codeLine, _, _, _ := source.NextVarUint()
   259  	codeLastLine, _, _, _ := source.NextVarUint()
   260  	var i uint64
   261  	switch t {
   262  
   263  	case stmtAssign:
   264  		len, _, _, _ := source.NextVarUint()
   265  		lhs := make([]Expr, len)
   266  		for i = 0; i < len; i++ {
   267  			lhs[i], err = ExprDeserialize(source)
   268  			if err != nil {
   269  				return nil, err
   270  			}
   271  		}
   272  		len, _, _, _ = source.NextVarUint()
   273  		rhs := make([]Expr, len)
   274  		for i = 0; i < len; i++ {
   275  			rhs[i], err = ExprDeserialize(source)
   276  			if err != nil {
   277  				return nil, err
   278  			}
   279  		}
   280  		stmt = &AssignStmt{Lhs: lhs, Rhs: rhs}
   281  		stmt.SetLine(int(codeLine))
   282  		stmt.SetLastLine(int(codeLastLine))
   283  	case stmtLocalAssign:
   284  		len, _, _, _ := source.NextVarUint()
   285  		names := make([]string, len)
   286  		for i = 0; i < len; i++ {
   287  			names[i], _, _, _ = source.NextString()
   288  			if err != nil {
   289  				return nil, err
   290  			}
   291  		}
   292  		len, _, _, _ = source.NextVarUint()
   293  		exprs := make([]Expr, len)
   294  		for i = 0; i < len; i++ {
   295  			s, err := ExprDeserialize(source)
   296  			// exprs[i], err = ExprDeserialize(source)
   297  			exprs[i] = s
   298  			if err != nil {
   299  				return nil, err
   300  			}
   301  		}
   302  		stmt = &LocalAssignStmt{Names: names, Exprs: exprs}
   303  		stmt.SetLine(int(codeLine))
   304  		stmt.SetLastLine(int(codeLastLine))
   305  	case stmtFuncCall:
   306  		expr, err := ExprDeserialize(source)
   307  		if err != nil {
   308  			return nil, err
   309  		}
   310  		stmt = &FuncCallStmt{Expr: expr}
   311  		stmt.SetLine(int(codeLine))
   312  		stmt.SetLastLine(int(codeLastLine))
   313  	case stmtDoBlock:
   314  		len, _, _, _ := source.NextVarUint()
   315  		stmts := make([]Stmt, len)
   316  		for i = 0; i < len; i++ {
   317  			stmts[i], err = StmtDeserialize(source)
   318  			if err != nil {
   319  				return nil, err
   320  			}
   321  		}
   322  		stmt = &DoBlockStmt{Stmts: stmts}
   323  		stmt.SetLine(int(codeLine))
   324  		stmt.SetLastLine(int(codeLastLine))
   325  	case stmtWhile:
   326  		condition, err := ExprDeserialize(source)
   327  		if err != nil {
   328  			return nil, err
   329  		}
   330  		len, _, _, _ := source.NextVarUint()
   331  		stmts := make([]Stmt, len)
   332  		for i = 0; i < len; i++ {
   333  			stmts[i], err = StmtDeserialize(source)
   334  			if err != nil {
   335  				return nil, err
   336  			}
   337  		}
   338  		stmt = &WhileStmt{Condition: condition, Stmts: stmts}
   339  		stmt.SetLine(int(codeLine))
   340  		stmt.SetLastLine(int(codeLastLine))
   341  	case stmtRepeat:
   342  		condition, err := ExprDeserialize(source)
   343  		if err != nil {
   344  			return nil, err
   345  		}
   346  		len, _, _, _ := source.NextVarUint()
   347  		stmts := make([]Stmt, len)
   348  		for i = 0; i < len; i++ {
   349  			stmts[i], err = StmtDeserialize(source)
   350  			if err != nil {
   351  				return nil, err
   352  			}
   353  		}
   354  		stmt = &RepeatStmt{Condition: condition, Stmts: stmts}
   355  		stmt.SetLine(int(codeLine))
   356  		stmt.SetLastLine(int(codeLastLine))
   357  	case stmtIf:
   358  		condition, err := ExprDeserialize(source)
   359  		if err != nil {
   360  			return nil, err
   361  		}
   362  		len, _, _, _ := source.NextVarUint()
   363  		then := make([]Stmt, len)
   364  		i = 0
   365  		for i = 0; i < len; i++ {
   366  			then[i], err = StmtDeserialize(source)
   367  			if err != nil {
   368  				return nil, err
   369  			}
   370  		}
   371  		len, _, _, _ = source.NextVarUint()
   372  		else_ := make([]Stmt, len)
   373  		i = 0
   374  		for i = 0; i < len; i++ {
   375  			else_[i], err = StmtDeserialize(source)
   376  			if err != nil {
   377  				return nil, err
   378  			}
   379  		}
   380  		stmt = &IfStmt{Condition: condition, Then: then, Else: else_}
   381  		stmt.SetLine(int(codeLine))
   382  		stmt.SetLastLine(int(codeLastLine))
   383  	case stmtNumberFor:
   384  		name, _, _, _ := source.NextString()
   385  		init, err := ExprDeserialize(source)
   386  		if err != nil {
   387  			return nil, err
   388  		}
   389  		limit, err := ExprDeserialize(source)
   390  		if err != nil {
   391  			return nil, err
   392  		}
   393  		step, err := ExprDeserialize(source)
   394  		if err != nil {
   395  			return nil, err
   396  		}
   397  		len, _, _, _ := source.NextVarUint()
   398  		stmts := make([]Stmt, len)
   399  		for i = 0; i < len; i++ {
   400  			stmts[i], err = StmtDeserialize(source)
   401  			if err != nil {
   402  				return nil, err
   403  			}
   404  		}
   405  		stmt = &NumberForStmt{Name: name, Init: init, Limit: limit, Step: step, Stmts: stmts}
   406  		stmt.SetLine(int(codeLine))
   407  		stmt.SetLastLine(int(codeLastLine))
   408  	case stmtGenericFor:
   409  		len, _, _, _ := source.NextVarUint()
   410  		names := make([]string, len)
   411  		for i = 0; i < len; i++ {
   412  			names[i], _, _, _ = source.NextString()
   413  		}
   414  		len, _, _, _ = source.NextVarUint()
   415  		exprs := make([]Expr, len)
   416  		for i = 0; i < len; i++ {
   417  			exprs[i], err = ExprDeserialize(source)
   418  			if err != nil {
   419  				return nil, err
   420  			}
   421  		}
   422  		len, _, _, _ = source.NextVarUint()
   423  		stmts := make([]Stmt, len)
   424  		for i = 0; i < len; i++ {
   425  			stmts[i], err = StmtDeserialize(source)
   426  			if err != nil {
   427  				return nil, err
   428  			}
   429  		}
   430  		stmt = &GenericForStmt{Names: names, Exprs: exprs, Stmts: stmts}
   431  		stmt.SetLine(int(codeLine))
   432  		stmt.SetLastLine(int(codeLastLine))
   433  	case stmtFuncDef:
   434  		name := &FuncName{}
   435  		name.DeSerialization(source)
   436  
   437  		funcExpr := &FunctionExpr{}
   438  		funcExpr.DeSerialization(source)
   439  		if err != nil {
   440  			return nil, err
   441  		}
   442  		stmt = &FuncDefStmt{Name: name, Func: funcExpr}
   443  		stmt.SetLine(int(codeLine))
   444  		stmt.SetLastLine(int(codeLastLine))
   445  	case stmtReturn:
   446  		len, _, _, _ := source.NextVarUint()
   447  		exprs := make([]Expr, len)
   448  		for i = 0; i < len; i++ {
   449  			exprs[i], err = ExprDeserialize(source)
   450  		}
   451  		stmt = &ReturnStmt{Exprs: exprs}
   452  		stmt.SetLine(int(codeLine))
   453  		stmt.SetLastLine(int(codeLastLine))
   454  	case stmtBreak:
   455  		stmt = &BreakStmt{}
   456  		stmt.SetLine(int(codeLine))
   457  		stmt.SetLastLine(int(codeLastLine))
   458  	}
   459  	return stmt, err
   460  }