more additions to pkgctx

This commit is contained in:
Brian Picciano 2014-10-24 14:10:07 -04:00
parent 84c615ac58
commit 17004883e8

View File

@ -1,5 +1,17 @@
package pkgctx package pkgctx
import (
"strings"
"github.com/mediocregopher/ginger/seq"
"github.com/mediocregopher/ginger/types"
)
const (
coreAbs = "github.com/mediocregopher/ginger/core"
coreAlias = "gingercore"
)
// PkgCtx is given to all macros and represents the package that they are being // PkgCtx is given to all macros and represents the package that they are being
// evaluated within. // evaluated within.
type PkgCtx struct { type PkgCtx struct {
@ -16,3 +28,86 @@ type PkgCtx struct {
// use it during testing // use it during testing
CallMap map[string]interface{} CallMap map[string]interface{}
} }
// Returns an empty PkgCtx
func New() *PkgCtx {
return &PkgCtx{
Packages: map[string]string{},
CallMap: map[string]interface{}{},
}
}
// A returns a new PkgCtx, which is a copy of a merge between p and p2. p2's
// keys overwrite any conflicting keys in p. p and p2 are unaffected by this
// operation
func (p *PkgCtx) MergeLeft(p2 *PkgCtx) *PkgCtx {
p3 := New()
for pkg := range p.Packages {
p3.Packages[pkg] = p.Packages[pkg]
}
for pkg := range p2.Packages {
p3.Packages[pkg] = p2.Packages[pkg]
}
for fn := range p.CallMap {
p3.CallMap[fn] = p.CallMap[fn]
}
for fn := range p2.CallMap {
p3.CallMap[fn] = p2.CallMap[fn]
}
return p3
}
// Returns a copy of p
func (p *PkgCtx) Copy() *PkgCtx {
return p.MergeLeft(New())
}
func (p *PkgCtx) PopulateFromCode(el types.Elem) bool {
if s, ok := el.(seq.Seq); ok {
return seq.Traverse(p.PopulateFromCode, s)
}
gt, ok := el.(types.GoType)
if !ok {
return true
}
str, ok := gt.V.(string)
if !ok {
return true
}
if len(str) < 2 {
return true
}
if str[0] != ':' {
return true
}
str = str[1:]
// At this point str is a reference to something. We check if it's already
// pointing somewhere first
if _, ok = p.CallMap[str]; ok {
return true
}
// If there isn't a '.' in the string, it's not directly referencing another
// package. Since it isn't in this context either, it must be referencing
// something in core
var i int
if i = strings.IndexRune(str, '.'); i < 1 {
p.Packages[coreAbs] = coreAlias
p.CallMap[str] = nil
// TODO there needs to be a CodeGen interface or something. The
// CallMap's value type needs to be that, because in all likelyhood the
// CallMap will be directly translated to a map variable in the
// generated package, with the values being different depending on what
// they're being used for (external functions will be references to
// those functions, local variables may just end up being just GoType's
// of the actual value.
}
return true
}