neoneo-go/pkg/vm/compiler/struct_scope.go
Anthony De Meulemeester 8fe079ec8e
Update compiler (#22)
* refactor to use ast.Walk for recursive converting
* added lots of test cases
* added a new way to handle jump labels
* function calls with multiple arguments
* binary expression (LOR LAND)
* struct types + method receives
* cleaner opcode dumps, side by side diff for debugging test cases
2018-02-19 10:24:28 +01:00

51 lines
1.1 KiB
Go

package compiler
import (
"go/ast"
"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 {
// identifier of the initialized struct in the program.
name string
// a mapping of field identifier and its position.
fields map[string]int
}
func newStructScope() *structScope {
return &structScope{
fields: map[string]int{},
}
}
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 name %s for struct %s", name, s.name)
}
return i
}
func (s *structScope) initializeFields(ident *ast.Ident, tInfo *types.Info) {
def, ok := tInfo.Defs[ident]
if !ok {
log.Fatalf("could not initialize fields of %s: definitions not found in typeinfo", ident.Name)
}
t, ok := def.Type().Underlying().(*types.Struct)
if !ok {
log.Fatalf("%s is not of type struct", ident.Name)
}
for i := 0; i < t.NumFields(); i++ {
s.newField(t.Field(i).Name())
}
}