summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-11-29 19:46:34 +0100
committerMarc Vertes <mvertes@free.fr>2025-11-29 19:46:34 +0100
commitf40a1c23467eef36f53635e525f8b25f591e8a45 (patch)
treebeae2442ecee1d734b9a676f7b176376a1d80af5
parentfbc73922e9853d7e344e388f3fdfedb8fa323682 (diff)
chore: shorter name for packages, simpilfy vm values
-rw-r--r--.golangci.yaml2
-rw-r--r--Makefile2
-rw-r--r--comp/compiler.go (renamed from compiler/compiler.go)36
-rw-r--r--interp/dump_test.go (renamed from interpreter/dump_test.go)20
-rw-r--r--interp/interpreter.go (renamed from interpreter/interpreter.go)16
-rw-r--r--interp/interpreter_test.go (renamed from interpreter/interpreter_test.go)8
-rw-r--r--interp/repl.go (renamed from interpreter/repl.go)2
-rw-r--r--main.go12
-rw-r--r--vm/type.go8
-rw-r--r--vm/vm.go60
-rw-r--r--vm/vm_test.go2
11 files changed, 85 insertions, 83 deletions
diff --git a/.golangci.yaml b/.golangci.yaml
index 34d9d92..ade2ad1 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -1,9 +1,11 @@
version: "2"
linters:
enable:
+ - errcheck
- gocritic
- godot
- gosec
+ - govet
- ineffassign
- misspell
- modernize
diff --git a/Makefile b/Makefile
index 70b2f3a..1d4e5c8 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ lint:
# Run tests with race detector, measure coverage.
test:
- go test -race -covermode=atomic -coverpkg=./... -coverprofile=cover.out ./interpreter
+ go test -race -covermode=atomic -coverpkg=./... -coverprofile=cover.out ./interp
# Open coverage info in browser
cover: test
diff --git a/compiler/compiler.go b/comp/compiler.go
index 679a886..610d4a1 100644
--- a/compiler/compiler.go
+++ b/comp/compiler.go
@@ -1,5 +1,5 @@
-// Package compiler implements a compiler targeting the vm.
-package compiler
+// Package comp implements a byte code generator targeting the vm.
+package comp
import (
"fmt"
@@ -43,8 +43,8 @@ func (c *Compiler) AddSym(name string, value vm.Value) int {
return p
}
-// Codegen generates vm code from parsed tokens.
-func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
+// Generate generates vm code and data from parsed tokens.
+func (c *Compiler) Generate(tokens parser.Tokens) (err error) {
log.Println("Codegen tokens:", tokens)
fixList := parser.Tokens{} // list of tokens to fix after all necessary information is gathered
stack := []*parser.Symbol{} // for symbolic evaluation, type checking, etc
@@ -69,7 +69,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
case lang.String:
s := t.Block()
- v := vm.Value{Data: reflect.ValueOf(s), Type: vm.TypeOf(s)}
+ v := vm.Value{Type: vm.TypeOf(s), Value: reflect.ValueOf(s)}
i, ok := c.strings[s]
if !ok {
i = len(c.Data)
@@ -136,7 +136,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
fallthrough // A symValue must be called through callX.
case lang.CallX:
- rtyp := pop().Value.Data.Type()
+ rtyp := pop().Value.Value.Type()
// TODO: pop input types (careful with variadic function).
for i := 0; i < rtyp.NumOut(); i++ {
push(&parser.Symbol{Type: &vm.Type{Rtype: rtyp.Out(i)}})
@@ -147,7 +147,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
log.Println("COMPOSITE")
/*
d := pop()
- switch d.typ.Rtype.Kind() {
+ switch d.Type.Rtype.Kind() {
case reflect.Struct:
// nf := d.typ.Rtype.NumField()
// emit(t.Pos, vm.New, d.index, c.typeSym(d.typ).index)
@@ -268,7 +268,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
t.Beg = len(c.Code)
fixList = append(fixList, t)
} else {
- i = int(s.Value.Data.Int()) - len(c.Code)
+ i = int(s.Value.Int()) - len(c.Code)
}
emit(t, vm.JumpFalse, i)
@@ -279,7 +279,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
t.Beg = len(c.Code)
fixList = append(fixList, t)
} else {
- i = int(s.Value.Data.Int()) - len(c.Code)
+ i = int(s.Value.Int()) - len(c.Code)
}
emit(t, vm.JumpSetFalse, i)
@@ -290,7 +290,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
t.Beg = len(c.Code)
fixList = append(fixList, t)
} else {
- i = int(s.Value.Data.Int()) - len(c.Code)
+ i = int(s.Value.Int()) - len(c.Code)
}
emit(t, vm.JumpSetTrue, i)
@@ -300,7 +300,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
t.Beg = len(c.Code)
fixList = append(fixList, t)
} else {
- i = int(s.Value.Data.Int()) - len(c.Code)
+ i = int(s.Value.Int()) - len(c.Code)
}
emit(t, vm.Jump, i)
@@ -341,7 +341,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
emit(t, vm.Return, t.Beg, t.End)
default:
- return fmt.Errorf("Codegen: unsupported token %v", t)
+ return fmt.Errorf("generate: unsupported token %v", t)
}
}
@@ -351,7 +351,7 @@ func (c *Compiler) Codegen(tokens parser.Tokens) (err error) {
if !ok {
return fmt.Errorf("label not found: %q", t.Str)
}
- c.Code[t.Beg].Arg[0] = int(s.Value.Data.Int()) - t.Beg
+ c.Code[t.Beg].Arg[0] = int(s.Value.Int()) - t.Beg
}
return err
}
@@ -365,7 +365,7 @@ func (c *Compiler) PrintCode() {
for name, sym := range c.Symbols {
if sym.Kind == parser.SymLabel || sym.Kind == parser.SymFunc {
- i := int(sym.Value.Data.Int())
+ i := int(sym.Value.Int())
labels[i] = append(labels[i], name)
}
if sym.Used {
@@ -423,7 +423,7 @@ func (c *Compiler) PrintData() {
fmt.Fprintln(os.Stderr, "# Data:")
for i, d := range c.Data {
- fmt.Fprintf(os.Stderr, "%4d %T %v %v\n", i, d.Data.Interface(), d.Data, dict[i])
+ fmt.Fprintf(os.Stderr, "%4d %T %v %v\n", i, d.Interface(), d.Value, dict[i])
}
}
@@ -469,7 +469,7 @@ func (c *Compiler) Dump() *Dump {
Name: e.name,
Kind: int(e.Kind),
Type: e.Type.Name,
- Value: d.Data.Interface(),
+ Value: d.Interface(),
}
}
return &Dump{Values: dv}
@@ -499,11 +499,11 @@ func (c *Compiler) ApplyDump(d *Dump) error {
return fmt.Errorf("index (%d) bigger than memory (%d)", dv.Index, len(c.Data))
}
- if !c.Data[dv.Index].Data.CanSet() {
+ if !c.Data[dv.Index].CanSet() {
return fmt.Errorf("value %v cannot be set", dv.Value)
}
- c.Data[dv.Index].Data.Set(reflect.ValueOf(dv.Value))
+ c.Data[dv.Index].Set(reflect.ValueOf(dv.Value))
}
return nil
}
diff --git a/interpreter/dump_test.go b/interp/dump_test.go
index d8fcc55..fbaa778 100644
--- a/interpreter/dump_test.go
+++ b/interp/dump_test.go
@@ -1,43 +1,43 @@
-package interpreter_test
+package interp_test
import (
"testing"
- "github.com/mvertes/parscan/interpreter"
+ "github.com/mvertes/parscan/interp"
"github.com/mvertes/parscan/lang/golang"
)
func TestDump(t *testing.T) {
initProgram := "var a int = 2+1; a"
- interp := interpreter.NewInterpreter(golang.GoSpec)
- r, e := interp.Eval(initProgram)
+ intp := interp.NewInterpreter(golang.GoSpec)
+ r, e := intp.Eval(initProgram)
t.Log(r, e)
if e != nil {
t.Fatal(e)
}
- r, e = interp.Eval("a = 100")
+ r, e = intp.Eval("a = 100")
t.Log(r, e)
if e != nil {
t.Fatal(e)
}
- d := interp.Dump()
+ d := intp.Dump()
t.Log(d)
- interp = interpreter.NewInterpreter(golang.GoSpec)
- r, e = interp.Eval(initProgram)
+ intp = interp.NewInterpreter(golang.GoSpec)
+ r, e = intp.Eval(initProgram)
t.Log(r, e)
if e != nil {
t.Fatal(e)
}
- e = interp.ApplyDump(d)
+ e = intp.ApplyDump(d)
if e != nil {
t.Fatal(e)
}
- r, e = interp.Eval("a = a + 1;a")
+ r, e = intp.Eval("a = a + 1;a")
t.Log(r, e)
if e != nil {
t.Fatal(e)
diff --git a/interpreter/interpreter.go b/interp/interpreter.go
index 032a66f..8d372c3 100644
--- a/interpreter/interpreter.go
+++ b/interp/interpreter.go
@@ -1,10 +1,10 @@
-// Package interpreter implements an interpreter.
-package interpreter
+// Package interp implements an interpreter.
+package interp
import (
"reflect"
- "github.com/mvertes/parscan/compiler"
+ "github.com/mvertes/parscan/comp"
"github.com/mvertes/parscan/lang"
"github.com/mvertes/parscan/vm"
)
@@ -13,13 +13,13 @@ const debug = true
// Interp represents the state of an interpreter.
type Interp struct {
- *compiler.Compiler
+ *comp.Compiler
*vm.Machine
}
// NewInterpreter returns a new interpreter.
func NewInterpreter(s *lang.Spec) *Interp {
- return &Interp{compiler.NewCompiler(s), &vm.Machine{}}
+ return &Interp{comp.NewCompiler(s), &vm.Machine{}}
}
// Eval evaluates code string and return the last produced value if any, or an error.
@@ -36,13 +36,13 @@ func (i *Interp) Eval(src string) (res reflect.Value, err error) {
if err != nil {
return res, err
}
- if err = i.Codegen(t); err != nil {
+ if err = i.Generate(t); err != nil {
return res, err
}
i.Push(i.Data[dataOffset:]...)
i.PushCode(i.Code[codeOffset:]...)
if s, ok := i.Symbols["main"]; ok {
- i.PushCode(vm.Instruction{Op: vm.Calli, Arg: []int{int(i.Data[s.Index].Data.Int())}})
+ i.PushCode(vm.Instruction{Op: vm.Calli, Arg: []int{int(i.Data[s.Index].Int())}})
}
i.PushCode(vm.Instruction{Op: vm.Exit})
i.SetIP(max(codeOffset, i.Entry))
@@ -51,5 +51,5 @@ func (i *Interp) Eval(src string) (res reflect.Value, err error) {
i.PrintCode()
}
err = i.Run()
- return i.Top().Data, err
+ return i.Top().Value, err
}
diff --git a/interpreter/interpreter_test.go b/interp/interpreter_test.go
index e48efdb..21e6274 100644
--- a/interpreter/interpreter_test.go
+++ b/interp/interpreter_test.go
@@ -1,11 +1,11 @@
-package interpreter_test
+package interp_test
import (
"fmt"
"log"
"testing"
- "github.com/mvertes/parscan/interpreter"
+ "github.com/mvertes/parscan/interp"
"github.com/mvertes/parscan/lang/golang"
)
@@ -24,9 +24,9 @@ func gen(test etest) func(*testing.T) {
if test.skip {
t.Skip()
}
- interp := interpreter.NewInterpreter(golang.GoSpec)
+ intp := interp.NewInterpreter(golang.GoSpec)
errStr := ""
- r, e := interp.Eval(test.src)
+ r, e := intp.Eval(test.src)
t.Log(r, e)
if e != nil {
errStr = e.Error()
diff --git a/interpreter/repl.go b/interp/repl.go
index 73af8a7..b8a5338 100644
--- a/interpreter/repl.go
+++ b/interp/repl.go
@@ -1,4 +1,4 @@
-package interpreter
+package interp
import (
"bufio"
diff --git a/main.go b/main.go
index 0e95bd4..634d053 100644
--- a/main.go
+++ b/main.go
@@ -7,7 +7,7 @@ import (
"log"
"os"
- "github.com/mvertes/parscan/interpreter"
+ "github.com/mvertes/parscan/interp"
"github.com/mvertes/parscan/lang/golang"
)
@@ -32,21 +32,21 @@ func run(arg []string) error {
}
args := rflag.Args()
- interp := interpreter.NewInterpreter(golang.GoSpec)
+ i := interp.NewInterpreter(golang.GoSpec)
if str != "" {
- return evalStr(interp, str)
+ return evalStr(i, str)
}
if len(args) == 0 {
- return interp.Repl(os.Stdin)
+ return i.Repl(os.Stdin)
}
buf, err := os.ReadFile(arg[0])
if err != nil {
return err
}
- return evalStr(interp, string(buf))
+ return evalStr(i, string(buf))
}
-func evalStr(i *interpreter.Interp, s string) error {
+func evalStr(i *interp.Interp, s string) error {
_, err := i.Eval(s)
return err
}
diff --git a/vm/type.go b/vm/type.go
index 7c33cd2..5f91eee 100644
--- a/vm/type.go
+++ b/vm/type.go
@@ -33,8 +33,8 @@ func (t *Type) Out(i int) *Type {
// Value is the representation of a runtime value.
type Value struct {
- Type *Type
- Data reflect.Value
+ *Type
+ reflect.Value
}
// NewValue returns an addressable zero value for the specified type.
@@ -42,7 +42,7 @@ func NewValue(typ *Type) Value {
if typ.Rtype.Kind() == reflect.Func {
typ = TypeOf(0) // Function value is its index in the code segment.
}
- return Value{Type: typ, Data: reflect.New(typ.Rtype).Elem()}
+ return Value{Type: typ, Value: reflect.New(typ.Rtype).Elem()}
}
// TypeOf returns the runtime type of v.
@@ -53,7 +53,7 @@ func TypeOf(v any) *Type {
// ValueOf returns the runtime value of v.
func ValueOf(v any) Value {
- return Value{Data: reflect.ValueOf(v)}
+ return Value{Value: reflect.ValueOf(v)}
}
// PointerTo returns the pointer type with element t.
diff --git a/vm/vm.go b/vm/vm.go
index 18207f7..7afe374 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -103,21 +103,21 @@ func (m *Machine) Run() (err error) {
ic++
switch c.Op {
case Add:
- mem[sp-2] = ValueOf(int(mem[sp-2].Data.Int() + mem[sp-1].Data.Int()))
+ mem[sp-2] = ValueOf(int(mem[sp-2].Int() + mem[sp-1].Int()))
mem = mem[:sp-1]
case Mul:
- mem[sp-2] = ValueOf(int(mem[sp-2].Data.Int() * mem[sp-1].Data.Int()))
+ mem[sp-2] = ValueOf(int(mem[sp-2].Int() * mem[sp-1].Int()))
mem = mem[:sp-1]
case Addr:
- mem[sp-1].Data = mem[sp-1].Data.Addr()
+ mem[sp-1].Value = mem[sp-1].Addr()
case Assign:
- mem[c.Arg[0]].Data.Set(mem[sp-1].Data)
+ mem[c.Arg[0]].Set(mem[sp-1].Value)
mem = mem[:sp-1]
case Fassign:
- mem[fp+c.Arg[0]-1].Data.Set(mem[sp-1].Data)
+ mem[fp+c.Arg[0]-1].Set(mem[sp-1].Value)
mem = mem[:sp-1]
case Call:
- nip := int(mem[sp-1].Data.Int())
+ nip := int(mem[sp-1].Int())
mem = append(mem[:sp-1], ValueOf(ip+1), ValueOf(fp))
ip = nip
fp = sp + 1
@@ -130,24 +130,24 @@ func (m *Machine) Run() (err error) {
case CallX: // Should be made optional.
in := make([]reflect.Value, c.Arg[0])
for i := range in {
- in[i] = mem[sp-2-i].Data
+ in[i] = mem[sp-2-i].Value
}
- f := mem[sp-1].Data
+ f := mem[sp-1].Value
mem = mem[:sp-c.Arg[0]-1]
for _, v := range f.Call(in) {
- mem = append(mem, Value{Data: v})
+ mem = append(mem, Value{Value: v})
}
case Deref:
- mem[sp-1].Data = mem[sp-1].Data.Elem()
+ mem[sp-1].Value = mem[sp-1].Value.Elem()
case Dup:
mem = append(mem, mem[c.Arg[0]])
case New:
mem[c.Arg[0]+fp-1] = NewValue(mem[c.Arg[1]].Type)
case Equal:
- mem[sp-2] = ValueOf(mem[sp-2].Data.Equal(mem[sp-1].Data))
+ mem[sp-2] = ValueOf(mem[sp-2].Equal(mem[sp-1].Value))
mem = mem[:sp-1]
case EqualSet:
- if mem[sp-2].Data.Equal(mem[sp-1].Data) {
+ if mem[sp-2].Equal(mem[sp-1].Value) {
// If equal then lhs and rhs are popped, replaced by test result, as in Equal.
mem[sp-2] = ValueOf(true)
mem = mem[:sp-1]
@@ -161,31 +161,31 @@ func (m *Machine) Run() (err error) {
case Fdup:
mem = append(mem, mem[c.Arg[0]+fp-1])
case Field:
- fv := mem[sp-1].Data.FieldByIndex(c.Arg)
+ fv := mem[sp-1].FieldByIndex(c.Arg)
if !fv.CanSet() {
// Normally private fields can not bet set via reflect. Override this limitation.
fv = reflect.NewAt(fv.Type(), unsafe.Pointer(fv.UnsafeAddr())).Elem()
}
- mem[sp-1].Data = fv
+ mem[sp-1].Value = fv
case Jump:
ip += c.Arg[0]
continue
case JumpTrue:
- cond := mem[sp-1].Data.Bool()
+ cond := mem[sp-1].Bool()
mem = mem[:sp-1]
if cond {
ip += c.Arg[0]
continue
}
case JumpFalse:
- cond := mem[sp-1].Data.Bool()
+ cond := mem[sp-1].Bool()
mem = mem[:sp-1]
if !cond {
ip += c.Arg[0]
continue
}
case JumpSetTrue:
- cond := mem[sp-1].Data.Bool()
+ cond := mem[sp-1].Bool()
if cond {
ip += c.Arg[0]
// Note that the stack is not modified if cond is true.
@@ -193,7 +193,7 @@ func (m *Machine) Run() (err error) {
}
mem = mem[:sp-1]
case JumpSetFalse:
- cond := mem[sp-1].Data.Bool()
+ cond := mem[sp-1].Bool()
if !cond {
ip += c.Arg[0]
// Note that the stack is not modified if cond is false.
@@ -201,40 +201,40 @@ func (m *Machine) Run() (err error) {
}
mem = mem[:sp-1]
case Greater:
- mem[sp-2] = ValueOf(mem[sp-1].Data.Int() > mem[sp-2].Data.Int())
+ mem[sp-2] = ValueOf(mem[sp-1].Int() > mem[sp-2].Int())
mem = mem[:sp-1]
case Lower:
- mem[sp-2] = ValueOf(mem[sp-1].Data.Int() < mem[sp-2].Data.Int())
+ mem[sp-2] = ValueOf(mem[sp-1].Int() < mem[sp-2].Int())
mem = mem[:sp-1]
case Loweri:
- mem[sp-1] = ValueOf(mem[sp-1].Data.Int() < int64(c.Arg[0]))
+ mem[sp-1] = ValueOf(mem[sp-1].Int() < int64(c.Arg[0]))
case Not:
- mem[sp-1] = ValueOf(!mem[sp-1].Data.Bool())
+ mem[sp-1] = ValueOf(!mem[sp-1].Bool())
case Pop:
mem = mem[:sp-c.Arg[0]]
case Push:
mem = append(mem, NewValue(TypeOf(0)))
- mem[sp].Data.SetInt(int64(c.Arg[0]))
+ mem[sp].SetInt(int64(c.Arg[0]))
case Grow:
mem = append(mem, make([]Value, c.Arg[0])...)
case Return:
- ip = int(mem[fp-2].Data.Int())
+ ip = int(mem[fp-2].Int())
ofp := fp
- fp = int(mem[fp-1].Data.Int())
+ fp = int(mem[fp-1].Int())
mem = append(mem[:ofp-c.Arg[0]-c.Arg[1]-1], mem[sp-c.Arg[0]:]...)
continue
case Sub:
- mem[sp-2] = ValueOf(int(mem[sp-1].Data.Int() - mem[sp-2].Data.Int()))
+ mem[sp-2] = ValueOf(int(mem[sp-1].Int() - mem[sp-2].Int()))
mem = mem[:sp-1]
case Subi:
- mem[sp-1] = ValueOf(int(mem[sp-1].Data.Int()) - c.Arg[0])
+ mem[sp-1] = ValueOf(int(mem[sp-1].Int()) - c.Arg[0])
case Swap:
mem[sp-2], mem[sp-1] = mem[sp-1], mem[sp-2]
case Index:
- mem[sp-2].Data = mem[sp-1].Data.Index(int(mem[sp-2].Data.Int()))
+ mem[sp-2].Value = mem[sp-1].Index(int(mem[sp-2].Int()))
mem = mem[:sp-1]
case Vassign:
- mem[sp-1].Data.Set(mem[sp-2].Data)
+ mem[sp-1].Set(mem[sp-2].Value)
mem = mem[:sp-2]
}
ip++
@@ -288,7 +288,7 @@ func Vstring(lv []Value) string {
if s != "[" {
s += " "
}
- s += fmt.Sprintf("%v", v.Data)
+ s += fmt.Sprintf("%v", v.Value)
}
return s + "]"
}
diff --git a/vm/vm_test.go b/vm/vm_test.go
index f7cbfbf..a968281 100644
--- a/vm/vm_test.go
+++ b/vm/vm_test.go
@@ -136,7 +136,7 @@ var tests = []struct {
},
start: 0, end: 1, mem: "[3]",
}, { // #10 -- Assign a variable.
- sym: []Value{{Type: TypeOf(0), Data: reflect.ValueOf(0)}},
+ sym: []Value{{Type: TypeOf(0), Value: reflect.ValueOf(0)}},
code: []Instruction{
{Op: Grow, Arg: []int{1}},
{Op: New, Arg: []int{2, 0}},