mirror of
https://github.com/google/go-jsonnet.git
synced 2025-08-08 07:17:12 +02:00
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:
parent
bf2c1df9e5
commit
0eedf437b1
@ -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)
|
||||
}
|
||||
|
||||
// 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
35
main.go
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user