forked from TrueCloudLab/neoneo-go
52 lines
1.1 KiB
Go
52 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())
|
||
|
}
|
||
|
}
|