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