This repository has been archived by the owner on May 27, 2019. It is now read-only.
/
variable.go
79 lines (64 loc) · 1.92 KB
/
variable.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package emulator
import (
"fmt"
"github.com/ericr/solanalyzer/sources"
)
// Variable represents an emulated variable.
type Variable struct {
Identifier string
TypeName *sources.TypeName
StorageLocation string
Value *Value
}
// NewVariable returns a new instance of Variable.
func NewVariable(identifier string, typeName *sources.TypeName, storage string) *Variable {
return &Variable{
Identifier: identifier,
TypeName: typeName,
StorageLocation: storage,
Value: NewValue(),
}
}
func (v *Variable) String() string {
if v.Value.Expression == nil {
return fmt.Sprintf("%s %s %s", v.TypeName, v.StorageLocation, v.Identifier)
}
return fmt.Sprintf("%s %s %s = %s",
v.TypeName, v.StorageLocation, v.Identifier, v.Value.Expression)
}
// SetVariable sets a new variable.
func (e *Emulator) SetVariable(variable *Variable) {
switch variable.StorageLocation {
case "storage":
e.storage = append(e.storage, variable)
e.storageMap[variable.Identifier] = variable
case "memory":
frame := e.stack.CurrentFrame()
frame.Memory = append(frame.Memory, variable)
frame.MemoryMap[variable.Identifier] = variable
default:
panic("Unknown variable storage location")
}
}
// MustSetVariable must find and set a variable, otherwise the emulator panics.
func (e *Emulator) MustSetVariable(name string, value *Value) {
e.MustFindVariable(name).Value = value
}
// FindVariable attempts to find and return a variable.
func (e *Emulator) FindVariable(name string) *Variable {
frame := e.stack.CurrentFrame()
memoryVar, memoryFound := frame.MemoryMap[name]
storageVar, _ := e.storageMap[name]
if memoryFound {
return memoryVar
}
return storageVar
}
// MustFindVariable must return a variable, otherwise the emulator panics.
func (e *Emulator) MustFindVariable(name string) *Variable {
variable := e.FindVariable(name)
if variable == nil {
panic("Undeclared variable")
}
return variable
}