more additions to pkgctx
This commit is contained in:
parent
84c615ac58
commit
17004883e8
@ -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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user