Skip to content

Commit 7244266

Browse files
committed
Hide fields in vm.Program
1 parent ad0e877 commit 7244266

File tree

5 files changed

+60
-34
lines changed

5 files changed

+60
-34
lines changed

compiler/compiler.go

+12-13
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,16 @@ func Compile(tree *parser.Tree, config *conf.Config) (program *Program, err erro
4747
c.emit(OpCast, 2)
4848
}
4949

50-
program = &Program{
51-
Node: tree.Node,
52-
Source: tree.Source,
53-
Locations: c.locations,
54-
Variables: c.variables,
55-
Constants: c.constants,
56-
Bytecode: c.bytecode,
57-
Arguments: c.arguments,
58-
Functions: c.functions,
59-
DebugInfo: c.debugInfo,
60-
}
50+
program = NewProgram(
51+
tree.Source,
52+
c.locations,
53+
c.variables,
54+
c.constants,
55+
c.bytecode,
56+
c.arguments,
57+
c.functions,
58+
c.debugInfo,
59+
)
6160
return
6261
}
6362

@@ -145,7 +144,7 @@ func (c *compiler) addVariable(name string) int {
145144
return p
146145
}
147146

148-
// emitFunction adds builtin.Function.Func to the program.Functions and emits call opcode.
147+
// emitFunction adds builtin.Function.Func to the program.functions and emits call opcode.
149148
func (c *compiler) emitFunction(fn *ast.Function, argsLen int) {
150149
switch argsLen {
151150
case 0:
@@ -162,7 +161,7 @@ func (c *compiler) emitFunction(fn *ast.Function, argsLen int) {
162161
}
163162
}
164163

165-
// addFunction adds builtin.Function.Func to the program.Functions and returns its index.
164+
// addFunction adds builtin.Function.Func to the program.functions and returns its index.
166165
func (c *compiler) addFunction(fn *ast.Function) int {
167166
if fn == nil {
168167
panic("function is nil")

file/source.go

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ func (s *Source) Content() string {
4040
}
4141

4242
func (s *Source) Snippet(line int) (string, bool) {
43+
if s == nil {
44+
return "", false
45+
}
4346
charStart, found := s.findLineOffset(line)
4447
if !found || len(s.contents) == 0 {
4548
return "", false

vm/program.go

+30-9
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,43 @@ import (
99
"strings"
1010
"text/tabwriter"
1111

12-
"github.com/antonmedv/expr/ast"
1312
"github.com/antonmedv/expr/builtin"
1413
"github.com/antonmedv/expr/file"
1514
"github.com/antonmedv/expr/vm/runtime"
1615
)
1716

1817
type Program struct {
19-
Node ast.Node
20-
Source *file.Source
21-
Locations []file.Location
22-
Variables []any
23-
Constants []any
2418
Bytecode []Opcode
2519
Arguments []int
26-
Functions []Function
27-
DebugInfo map[string]string
20+
Constants []any
21+
22+
source *file.Source
23+
locations []file.Location
24+
variables []any
25+
functions []Function
26+
debugInfo map[string]string
27+
}
28+
29+
func NewProgram(
30+
source *file.Source,
31+
locations []file.Location,
32+
variables []any,
33+
constants []any,
34+
bytecode []Opcode,
35+
arguments []int,
36+
functions []Function,
37+
debugInfo map[string]string,
38+
) *Program {
39+
return &Program{
40+
source: source,
41+
locations: locations,
42+
variables: variables,
43+
Constants: constants,
44+
Bytecode: bytecode,
45+
Arguments: arguments,
46+
functions: functions,
47+
debugInfo: debugInfo,
48+
}
2849
}
2950

3051
func (program *Program) Disassemble() string {
@@ -56,7 +77,7 @@ func (program *Program) Opcodes(w io.Writer) {
5677
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\n", pp, label, arg)
5778
}
5879
argumentWithInfo := func(label string, prefix string) {
59-
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, program.DebugInfo[fmt.Sprintf("%s_%d", prefix, arg)])
80+
_, _ = fmt.Fprintf(w, "%v\t%v\t<%v>\t%v\n", pp, label, arg, program.debugInfo[fmt.Sprintf("%s_%d", prefix, arg)])
6081
}
6182
constant := func(label string) {
6283
var c any

vm/vm.go

+13-9
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,18 @@ func Debug() *VM {
5959
func (vm *VM) Run(program *Program, env any) (_ any, err error) {
6060
defer func() {
6161
if r := recover(); r != nil {
62+
var location file.Location
63+
if vm.ip-1 < len(program.locations) {
64+
location = program.locations[vm.ip-1]
65+
}
6266
f := &file.Error{
63-
Location: program.Locations[vm.ip-1],
67+
Location: location,
6468
Message: fmt.Sprintf("%v", r),
6569
}
6670
if err, ok := r.(error); ok {
6771
f.Wrap(err)
6872
}
69-
err = f.Bind(program.Source)
73+
err = f.Bind(program.source)
7074
}
7175
}()
7276

@@ -108,10 +112,10 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
108112
vm.pop()
109113

110114
case OpStore:
111-
program.Variables[arg] = vm.pop()
115+
program.variables[arg] = vm.pop()
112116

113117
case OpLoadVar:
114-
vm.push(program.Variables[arg])
118+
vm.push(program.variables[arg])
115119

116120
case OpLoadConst:
117121
vm.push(runtime.Fetch(env, program.Constants[arg]))
@@ -126,7 +130,7 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
126130
vm.push(runtime.FetchMethod(env, program.Constants[arg].(*runtime.Method)))
127131

128132
case OpLoadFunc:
129-
vm.push(program.Functions[arg])
133+
vm.push(program.functions[arg])
130134

131135
case OpFetch:
132136
b := vm.pop()
@@ -332,15 +336,15 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
332336
vm.push(out[0].Interface())
333337

334338
case OpCall0:
335-
out, err := program.Functions[arg]()
339+
out, err := program.functions[arg]()
336340
if err != nil {
337341
panic(err)
338342
}
339343
vm.push(out)
340344

341345
case OpCall1:
342346
a := vm.pop()
343-
out, err := program.Functions[arg](a)
347+
out, err := program.functions[arg](a)
344348
if err != nil {
345349
panic(err)
346350
}
@@ -349,7 +353,7 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
349353
case OpCall2:
350354
b := vm.pop()
351355
a := vm.pop()
352-
out, err := program.Functions[arg](a, b)
356+
out, err := program.functions[arg](a, b)
353357
if err != nil {
354358
panic(err)
355359
}
@@ -359,7 +363,7 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
359363
c := vm.pop()
360364
b := vm.pop()
361365
a := vm.pop()
362-
out, err := program.Functions[arg](a, b, c)
366+
out, err := program.functions[arg](a, b, c)
363367
if err != nil {
364368
panic(err)
365369
}

vm/vm_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import (
66
"reflect"
77
"testing"
88

9+
"github.com/stretchr/testify/require"
10+
911
"github.com/antonmedv/expr/ast"
1012
"github.com/antonmedv/expr/checker"
1113
"github.com/antonmedv/expr/compiler"
1214
"github.com/antonmedv/expr/conf"
13-
"github.com/antonmedv/expr/file"
1415
"github.com/antonmedv/expr/parser"
1516
"github.com/antonmedv/expr/vm"
16-
"github.com/stretchr/testify/require"
1717
)
1818

1919
func TestRun_NilProgram(t *testing.T) {
@@ -282,7 +282,6 @@ func TestRun_TaggedFieldName(t *testing.T) {
282282

283283
func TestRun_OpInvalid(t *testing.T) {
284284
program := &vm.Program{
285-
Locations: []file.Location{{0, 0}},
286285
Bytecode: []vm.Opcode{vm.OpInvalid},
287286
Arguments: []int{0},
288287
}

0 commit comments

Comments
 (0)