aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/compile/compile.go84
-rw-r--r--internal/compile/serial.go50
2 files changed, 70 insertions, 64 deletions
diff --git a/internal/compile/compile.go b/internal/compile/compile.go
index 1aee10c..6d98fc1 100644
--- a/internal/compile/compile.go
+++ b/internal/compile/compile.go
@@ -30,7 +30,6 @@ import (
"path/filepath"
"strconv"
- "go.starlark.net/resolve"
"go.starlark.net/syntax"
)
@@ -289,12 +288,12 @@ func (op Opcode) String() string {
// Programs are serialized by the gobProgram function,
// which must be updated whenever this declaration is changed.
type Program struct {
- Loads []Ident // name (really, string) and position of each load stmt
+ Loads []Binding // name (really, string) and position of each load stmt
Names []string // names of attributes and predeclared variables
Constants []interface{} // = string | int64 | float64 | *big.Int
Functions []*Funcode
- Globals []Ident // for error messages and tracing
- Toplevel *Funcode // module initialization function
+ Globals []Binding // for error messages and tracing
+ Toplevel *Funcode // module initialization function
}
// A Funcode is the code of a compiled Starlark function.
@@ -308,16 +307,16 @@ type Funcode struct {
Doc string // docstring of this function
Code []byte // the byte code
pclinetab []uint16 // mapping from pc to linenum
- Locals []Ident // locals, parameters first
- Freevars []Ident // for tracing
+ Locals []Binding // locals, parameters first
+ Freevars []Binding // for tracing
MaxStack int
NumParams int
NumKwonlyParams int
HasVarargs, HasKwargs bool
}
-// An Ident is the name and position of an identifier.
-type Ident struct {
+// A Binding is the name and position of a binding identifier.
+type Binding struct {
Name string
Pos syntax.Position
}
@@ -401,28 +400,28 @@ func (fn *Funcode) Position(pc uint32) syntax.Position {
return pos
}
-// idents convert syntactic identifiers to compiled form.
-func idents(ids []*syntax.Ident) []Ident {
- res := make([]Ident, len(ids))
- for i, id := range ids {
- res[i].Name = id.Name
- res[i].Pos = id.NamePos
+// bindings converts syntax.Bindings to compiled form.
+func bindings(bindings []*syntax.Binding) []Binding {
+ res := make([]Binding, len(bindings))
+ for i, bind := range bindings {
+ res[i].Name = bind.First.Name
+ res[i].Pos = bind.First.NamePos
}
return res
}
// Expr compiles an expression to a program consisting of a single toplevel function.
-func Expr(expr syntax.Expr, name string, locals []*syntax.Ident) *Funcode {
+func Expr(expr syntax.Expr, name string, locals []*syntax.Binding) *Funcode {
pos := syntax.Start(expr)
stmts := []syntax.Stmt{&syntax.ReturnStmt{Result: expr}}
return File(stmts, pos, name, locals, nil).Toplevel
}
// File compiles the statements of a file into a program.
-func File(stmts []syntax.Stmt, pos syntax.Position, name string, locals, globals []*syntax.Ident) *Program {
+func File(stmts []syntax.Stmt, pos syntax.Position, name string, locals, globals []*syntax.Binding) *Program {
pcomp := &pcomp{
prog: &Program{
- Globals: idents(globals),
+ Globals: bindings(globals),
},
names: make(map[string]uint32),
constants: make(map[interface{}]uint32),
@@ -433,7 +432,7 @@ func File(stmts []syntax.Stmt, pos syntax.Position, name string, locals, globals
return pcomp.prog
}
-func (pcomp *pcomp) function(name string, pos syntax.Position, stmts []syntax.Stmt, locals, freevars []*syntax.Ident) *Funcode {
+func (pcomp *pcomp) function(name string, pos syntax.Position, stmts []syntax.Stmt, locals, freevars []*syntax.Binding) *Funcode {
fcomp := &fcomp{
pcomp: pcomp,
pos: pos,
@@ -442,8 +441,8 @@ func (pcomp *pcomp) function(name string, pos syntax.Position, stmts []syntax.St
Pos: pos,
Name: name,
Doc: docStringFromBody(stmts),
- Locals: idents(locals),
- Freevars: idents(freevars),
+ Locals: bindings(locals),
+ Freevars: bindings(freevars),
},
}
@@ -898,34 +897,36 @@ func (fcomp *fcomp) setPos(pos syntax.Position) {
// set emits code to store the top-of-stack value
// to the specified local or global variable.
func (fcomp *fcomp) set(id *syntax.Ident) {
- switch resolve.Scope(id.Scope) {
- case resolve.Local:
- fcomp.emit1(SETLOCAL, uint32(id.Index))
- case resolve.Global:
- fcomp.emit1(SETGLOBAL, uint32(id.Index))
+ bind := id.Binding
+ switch bind.Scope {
+ case syntax.LocalScope:
+ fcomp.emit1(SETLOCAL, uint32(bind.Index))
+ case syntax.GlobalScope:
+ fcomp.emit1(SETGLOBAL, uint32(bind.Index))
default:
- log.Fatalf("%s: set(%s): neither global nor local (%d)", id.NamePos, id.Name, id.Scope)
+ log.Fatalf("%s: set(%s): neither global nor local (%d)", id.NamePos, id.Name, bind.Scope)
}
}
// lookup emits code to push the value of the specified variable.
func (fcomp *fcomp) lookup(id *syntax.Ident) {
- switch resolve.Scope(id.Scope) {
- case resolve.Local:
+ bind := id.Binding
+ switch bind.Scope {
+ case syntax.LocalScope:
fcomp.setPos(id.NamePos)
- fcomp.emit1(LOCAL, uint32(id.Index))
- case resolve.Free:
- fcomp.emit1(FREE, uint32(id.Index))
- case resolve.Global:
+ fcomp.emit1(LOCAL, uint32(bind.Index))
+ case syntax.FreeScope:
+ fcomp.emit1(FREE, uint32(bind.Index))
+ case syntax.GlobalScope:
fcomp.setPos(id.NamePos)
- fcomp.emit1(GLOBAL, uint32(id.Index))
- case resolve.Predeclared:
+ fcomp.emit1(GLOBAL, uint32(bind.Index))
+ case syntax.PredeclaredScope:
fcomp.setPos(id.NamePos)
fcomp.emit1(PREDECLARED, fcomp.pcomp.nameIndex(id.Name))
- case resolve.Universal:
+ case syntax.UniversalScope:
fcomp.emit1(UNIVERSAL, fcomp.pcomp.nameIndex(id.Name))
default:
- log.Fatalf("%s: compiler.lookup(%s): scope = %d", id.NamePos, id.Name, id.Scope)
+ log.Fatalf("%s: compiler.lookup(%s): scope = %d", id.NamePos, id.Name, bind.Scope)
}
}
@@ -1108,7 +1109,7 @@ func (fcomp *fcomp) stmt(stmt syntax.Stmt) {
fcomp.string(stmt.From[i].Name)
}
module := stmt.Module.Value.(string)
- fcomp.pcomp.prog.Loads = append(fcomp.pcomp.prog.Loads, Ident{
+ fcomp.pcomp.prog.Loads = append(fcomp.pcomp.prog.Loads, Binding{
Name: module,
Pos: stmt.Module.TokenPos,
})
@@ -1116,7 +1117,7 @@ func (fcomp *fcomp) stmt(stmt syntax.Stmt) {
fcomp.setPos(stmt.Load)
fcomp.emit1(LOAD, uint32(len(stmt.From)))
for i := range stmt.To {
- fcomp.emit1(SETGLOBAL, uint32(stmt.To[len(stmt.To)-1-i].Index))
+ fcomp.emit1(SETGLOBAL, uint32(stmt.To[len(stmt.To)-1-i].Binding.Index))
}
default:
@@ -1708,7 +1709,12 @@ func (fcomp *fcomp) function(pos syntax.Position, name string, f *syntax.Functio
// Capture the values of the function's
// free variables from the lexical environment.
for _, freevar := range f.FreeVars {
- fcomp.lookup(freevar)
+ switch freevar.Scope {
+ case syntax.LocalScope:
+ fcomp.emit1(LOCAL, uint32(freevar.Index))
+ case syntax.FreeScope:
+ fcomp.emit1(FREE, uint32(freevar.Index))
+ }
}
fcomp.emit1(MAKETUPLE, uint32(len(f.FreeVars)))
diff --git a/internal/compile/serial.go b/internal/compile/serial.go
index 6056ea7..b3f986f 100644
--- a/internal/compile/serial.go
+++ b/internal/compile/serial.go
@@ -96,7 +96,7 @@ func (prog *Program) Encode() []byte {
e.p = append(e.p, "????"...) // string data offset; filled in later
e.int(Version)
e.string(prog.Toplevel.Pos.Filename())
- e.idents(prog.Loads)
+ e.bindings(prog.Loads)
e.int(len(prog.Names))
for _, name := range prog.Names {
e.string(name)
@@ -118,7 +118,7 @@ func (prog *Program) Encode() []byte {
e.string(c.Text(10))
}
}
- e.idents(prog.Globals)
+ e.bindings(prog.Globals)
e.function(prog.Toplevel)
e.int(len(prog.Functions))
for _, fn := range prog.Functions {
@@ -161,29 +161,29 @@ func (e *encoder) bytes(b []byte) {
e.s = append(e.s, b...)
}
-func (e *encoder) ident(id Ident) {
- e.string(id.Name)
- e.int(int(id.Pos.Line))
- e.int(int(id.Pos.Col))
+func (e *encoder) binding(bind Binding) {
+ e.string(bind.Name)
+ e.int(int(bind.Pos.Line))
+ e.int(int(bind.Pos.Col))
}
-func (e *encoder) idents(ids []Ident) {
- e.int(len(ids))
- for _, id := range ids {
- e.ident(id)
+func (e *encoder) bindings(binds []Binding) {
+ e.int(len(binds))
+ for _, bind := range binds {
+ e.binding(bind)
}
}
func (e *encoder) function(fn *Funcode) {
- e.ident(Ident{fn.Name, fn.Pos})
+ e.binding(Binding{fn.Name, fn.Pos})
e.string(fn.Doc)
e.bytes(fn.Code)
e.int(len(fn.pclinetab))
for _, x := range fn.pclinetab {
e.int64(int64(x))
}
- e.idents(fn.Locals)
- e.idents(fn.Freevars)
+ e.bindings(fn.Locals)
+ e.bindings(fn.Freevars)
e.int(fn.MaxStack)
e.int(fn.NumParams)
e.int(fn.NumKwonlyParams)
@@ -228,7 +228,7 @@ func DecodeProgram(data []byte) (_ *Program, err error) {
filename := d.string()
d.filename = &filename
- loads := d.idents()
+ loads := d.bindings()
names := make([]string, d.int())
for i := range names {
@@ -252,7 +252,7 @@ func DecodeProgram(data []byte) (_ *Program, err error) {
constants[i] = c
}
- globals := d.idents()
+ globals := d.bindings()
toplevel := d.function()
funcs := make([]*Funcode, d.int())
for i := range funcs {
@@ -323,33 +323,33 @@ func (d *decoder) bytes() []byte {
return r
}
-func (d *decoder) ident() Ident {
+func (d *decoder) binding() Binding {
name := d.string()
line := int32(d.int())
col := int32(d.int())
- return Ident{Name: name, Pos: syntax.MakePosition(d.filename, line, col)}
+ return Binding{Name: name, Pos: syntax.MakePosition(d.filename, line, col)}
}
-func (d *decoder) idents() []Ident {
- idents := make([]Ident, d.int())
- for i := range idents {
- idents[i] = d.ident()
+func (d *decoder) bindings() []Binding {
+ bindings := make([]Binding, d.int())
+ for i := range bindings {
+ bindings[i] = d.binding()
}
- return idents
+ return bindings
}
func (d *decoder) bool() bool { return d.int() != 0 }
func (d *decoder) function() *Funcode {
- id := d.ident()
+ id := d.binding()
doc := d.string()
code := d.bytes()
pclinetab := make([]uint16, d.int())
for i := range pclinetab {
pclinetab[i] = uint16(d.int())
}
- locals := d.idents()
- freevars := d.idents()
+ locals := d.bindings()
+ freevars := d.bindings()
maxStack := d.int()
numParams := d.int()
numKwonlyParams := d.int()