Fix up lint errors.

Also:
* Made all types used in errors public.
* Made interpreter receiver a pointer.  This will reduce GC load for deep stacks.
This commit is contained in:
Joe Beda 2016-03-14 12:50:42 +00:00
parent bf2c1df9e5
commit 0eedf437b1
3 changed files with 42 additions and 30 deletions

View File

@ -31,8 +31,9 @@ type vmExt struct {
type vmExtMap map[string]vmExt
// RuntimeError is an error discovered during evaluation of the program
type RuntimeError struct {
StackTrace []traceFrame
StackTrace []TraceFrame
Msg string
}
@ -127,7 +128,8 @@ func makeValueArray(elements []thunk) *valueArray {
// The stack
type traceFrame struct {
// TraceFrame is a single frame of the call stack.
type TraceFrame struct {
Loc LocationRange
Name string
}
@ -158,17 +160,17 @@ type interpreter struct {
ExternalVars vmExtMap
}
func (this interpreter) execute(ast_ astNode) (value, error) {
func (i *interpreter) execute(a astNode) (value, error) {
// TODO(dcunnin): All the other cases...
switch ast := ast_.(type) {
switch ast := a.(type) {
case *astBinary:
// TODO(dcunnin): Assume it's + on numbers for now
leftVal, err := this.execute(ast.left)
leftVal, err := i.execute(ast.left)
if err != nil {
return nil, err
}
leftNum := leftVal.(*valueNumber).value
rightVal, err := this.execute(ast.right)
rightVal, err := i.execute(ast.right)
if err != nil {
return nil, err
}
@ -188,18 +190,17 @@ func (this interpreter) execute(ast_ astNode) (value, error) {
func unparseNumber(v float64) string {
if v == math.Floor(v) {
return fmt.Sprintf("%.0f", v)
} else {
}
// See "What Every Computer Scientist Should Know About Floating-Point Arithmetic"
// Theorem 15
// http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
return fmt.Sprintf("%.17g", v)
}
}
func (this interpreter) manifestJson(
v_ value, multiline bool, indent string, buf *bytes.Buffer) error {
func (i *interpreter) manifestJSON(v value, multiline bool, indent string, buf *bytes.Buffer) error {
// TODO(dcunnin): All the other types...
switch v := v_.(type) {
switch v := v.(type) {
case *valueBoolean:
if v.value {
buf.WriteString("true")
@ -217,16 +218,16 @@ func (this interpreter) manifestJson(
}
func execute(ast astNode, ext vmExtMap, maxStack int) (string, error) {
theInterpreter := interpreter{
i := interpreter{
Stack: makeCallStack(maxStack),
ExternalVars: ext,
}
result, err := theInterpreter.execute(ast)
result, err := i.execute(ast)
if err != nil {
return "", err
}
var buffer bytes.Buffer
err = theInterpreter.manifestJson(result, true, "", &buffer)
err = i.manifestJSON(result, true, "", &buffer)
if err != nil {
return "", err
}

35
main.go
View File

@ -16,29 +16,40 @@ limitations under the License.
package jsonnet
// Note: There are no garbage collection params because we're using the native Go garbage collector.
type Vm struct {
maxStack int
maxTrace int
// Note: There are no garbage collection params because we're using the native
// Go garbage collector.
// VM is the core interpreter and is the touchpoint used to parse and execute
// Jsonnet.
type VM struct {
MaxStack int
MaxTrace int // The number of lines of stack trace to display (0 for all of them).
ext vmExtMap
}
func MakeVm() *Vm {
return &Vm{
maxStack: 500,
maxTrace: 20,
// MakeVM creates a new VM with default parameters.
func MakeVM() *VM {
return &VM{
MaxStack: 500,
MaxTrace: 20,
}
}
func (vm *Vm) ExtVar(key string, val string) {
// ExtVar binds a Jsonnet external var to the given value.
func (vm *VM) ExtVar(key string, val string) {
vm.ext[key] = vmExt{value: val, isCode: false}
}
func (vm *Vm) ExtCode(key string, val string) {
// ExtCode binds a Jsonnet external code var to the given value.
func (vm *VM) ExtCode(key string, val string) {
vm.ext[key] = vmExt{value: val, isCode: true}
}
func (vm *Vm) EvaluateSnippet(filename string, snippet string) (string, error) {
// EvaluateSnippet evaluates a string containing Jsonnet code, return a JSON
// string.
//
// The filename parameter is only used for error messages.
func (vm *VM) EvaluateSnippet(filename string, snippet string) (string, error) {
tokens, err := lex(filename, snippet)
if err != nil {
return "", err
@ -48,7 +59,7 @@ func (vm *Vm) EvaluateSnippet(filename string, snippet string) (string, error) {
return "", err
}
ast, err = desugarFile(ast)
output, err := execute(ast, vm.ext, vm.maxStack)
output, err := execute(ast, vm.ext, vm.MaxStack)
if err != nil {
return "", err
}

View File

@ -40,7 +40,7 @@ var mainTests = []mainTest{
func TestMain(t *testing.T) {
for _, test := range mainTests {
vm := MakeVm()
vm := MakeVM()
output, err := vm.EvaluateSnippet(test.name, test.input)
var errString string
if err != nil {