mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-27 13:58:05 +00:00
23cfebf621
* implemented add, mul, div, sub assign for identifiers. * Implemented struct field initialization. * Implemented imports * Implemented storage VM API (interop layer) + additional bug fixes when encountered. * Bumped version 0.12.0 * fixed double point extension on compiled output file. * Fixed bug where callExpr in returns where added to voidCall * fixed binExpr compare equal * Check the env for the gopath first * removed travis.yml * custom types + implemented general declarations. * commented out the storage test to make the build pass
89 lines
2 KiB
Go
89 lines
2 KiB
Go
package compiler
|
|
|
|
import (
|
|
"go/constant"
|
|
"go/types"
|
|
"log"
|
|
)
|
|
|
|
// A structScope holds the positions for it's fields. Struct fields have different
|
|
// positions then local variables in any scope.
|
|
type structScope struct {
|
|
// A pointer to the underlying type.
|
|
t *types.Struct
|
|
|
|
// A mapping of fieldnames identifier and its position.
|
|
fields map[string]int
|
|
|
|
// A mapping of fieldnames and with type and value.
|
|
// This will be populated in "initFields" to initialize all
|
|
// structs fields to their zero value.
|
|
// strings: "" (just a pushf 0x00)
|
|
// int: 0
|
|
// bool: false
|
|
typeAndValues map[string]types.TypeAndValue
|
|
}
|
|
|
|
// newStructScope will create a new structScope with all fields initialized.
|
|
func newStructScope(t *types.Struct) *structScope {
|
|
s := &structScope{
|
|
fields: map[string]int{},
|
|
typeAndValues: make(map[string]types.TypeAndValue, t.NumFields()),
|
|
t: t,
|
|
}
|
|
s.initFields()
|
|
return s
|
|
}
|
|
|
|
func (s *structScope) initFields() {
|
|
var tv types.TypeAndValue
|
|
for i := 0; i < s.t.NumFields(); i++ {
|
|
f := s.t.Field(i)
|
|
s.newField(f.Name())
|
|
|
|
switch t := f.Type().(type) {
|
|
case *types.Basic:
|
|
switch t.Kind() {
|
|
case types.Int:
|
|
tv = types.TypeAndValue{
|
|
Type: t,
|
|
Value: constant.MakeInt64(0),
|
|
}
|
|
case types.String:
|
|
tv = types.TypeAndValue{
|
|
Type: t,
|
|
Value: constant.MakeString(""),
|
|
}
|
|
case types.Bool, types.UntypedBool:
|
|
tv = types.TypeAndValue{
|
|
Type: t,
|
|
Value: constant.MakeBool(false),
|
|
}
|
|
default:
|
|
log.Fatalf("could not initialize struct field %s to zero, type: %s", f.Name(), t)
|
|
}
|
|
}
|
|
s.typeAndValues[f.Name()] = tv
|
|
}
|
|
}
|
|
|
|
func (s *structScope) newField(name string) int {
|
|
i := len(s.fields)
|
|
s.fields[name] = i
|
|
return i
|
|
}
|
|
|
|
func (s *structScope) loadField(name string) int {
|
|
i, ok := s.fields[name]
|
|
if !ok {
|
|
log.Fatalf("could not resolve field %s for struct %v", name, s)
|
|
}
|
|
return i
|
|
}
|
|
|
|
func (s *structScope) initialize(t *types.Struct) {
|
|
s.t = t
|
|
for i := 0; i < t.NumFields(); i++ {
|
|
s.newField(t.Field(i).Name())
|
|
}
|
|
}
|