summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2025-11-28 16:34:28 +0100
committerMarc Vertes <mvertes@free.fr>2025-11-28 16:34:28 +0100
commitfbc73922e9853d7e344e388f3fdfedb8fa323682 (patch)
tree17cab9c49babad09906a34f3c16ebb0558c4e948
parent22b020225ae77ca1cf9f9984817df9b7fd1aaa12 (diff)
doc: improve comments, pass lint
Also improve the setup of golangci-lint.
-rw-r--r--.golangci.yaml18
-rw-r--r--compiler/compiler.go1
-rw-r--r--interpreter/interpreter.go1
-rw-r--r--interpreter/interpreter_test.go1
-rw-r--r--main.go43
-rw-r--r--parser/package.go1
-rw-r--r--parser/symbol.go11
-rw-r--r--scanner/scan.go5
-rw-r--r--vm/vm.go9
9 files changed, 30 insertions, 60 deletions
diff --git a/.golangci.yaml b/.golangci.yaml
index bc1fbb6..34d9d92 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -4,30 +4,20 @@ linters:
- gocritic
- godot
- gosec
+ - ineffassign
- misspell
+ - modernize
- perfsprint
- prealloc
- predeclared
- reassign
- revive
+ - staticcheck
- unconvert
+ - unused
exclusions:
- generated: lax
presets:
- common-false-positives
- - legacy
- - std-error-handling
- - comments
- paths:
- - third_party$
- - builtin$
- - examples$
formatters:
enable:
- gofumpt
- exclusions:
- generated: lax
- paths:
- - third_party$
- - builtin$
- - examples$
diff --git a/compiler/compiler.go b/compiler/compiler.go
index f7c8a12..679a886 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -1,3 +1,4 @@
+// Package compiler implements a compiler targeting the vm.
package compiler
import (
diff --git a/interpreter/interpreter.go b/interpreter/interpreter.go
index 62b593b..032a66f 100644
--- a/interpreter/interpreter.go
+++ b/interpreter/interpreter.go
@@ -1,3 +1,4 @@
+// Package interpreter implements an interpreter.
package interpreter
import (
diff --git a/interpreter/interpreter_test.go b/interpreter/interpreter_test.go
index 71c7dd1..e48efdb 100644
--- a/interpreter/interpreter_test.go
+++ b/interpreter/interpreter_test.go
@@ -42,7 +42,6 @@ func gen(test etest) func(*testing.T) {
func run(t *testing.T, tests []etest) {
for _, test := range tests {
- test := test
t.Run("", gen(test))
}
}
diff --git a/main.go b/main.go
index b0ca700..0e95bd4 100644
--- a/main.go
+++ b/main.go
@@ -1,12 +1,11 @@
+// The parscan command interprets programs.
package main
import (
"flag"
"fmt"
- "io"
"log"
"os"
- "strings"
"github.com/mvertes/parscan/interpreter"
"github.com/mvertes/parscan/lang/golang"
@@ -19,7 +18,7 @@ func main() {
}
}
-func run(arg []string) (err error) {
+func run(arg []string) error {
var str string
rflag := flag.NewFlagSet("run", flag.ContinueOnError)
rflag.Usage = func() {
@@ -28,46 +27,26 @@ func run(arg []string) (err error) {
rflag.PrintDefaults()
}
rflag.StringVar(&str, "e", "", "string to eval")
- if err = rflag.Parse(arg); err != nil {
+ if err := rflag.Parse(arg); err != nil {
return err
}
args := rflag.Args()
interp := interpreter.NewInterpreter(golang.GoSpec)
-
- var in io.Reader
if str != "" {
- in = strings.NewReader(str)
- } else {
- in = os.Stdin
- }
- if len(args) > 0 {
- if in, err = os.Open(arg[0]); err != nil {
- return err
- }
- if i2, ok := in.(io.ReadCloser); ok {
- defer i2.Close()
- }
+ return evalStr(interp, str)
}
-
- if isatty(in) {
- return interp.Repl(in)
+ if len(args) == 0 {
+ return interp.Repl(os.Stdin)
}
-
- buf, err := io.ReadAll(in)
+ buf, err := os.ReadFile(arg[0])
if err != nil {
return err
}
- _, err = interp.Eval(string(buf))
- return err
+ return evalStr(interp, string(buf))
}
-// isatty returns true if the input stream is a tty (i.e. a character device).
-func isatty(in io.Reader) bool {
- s, ok := in.(interface{ Stat() (os.FileInfo, error) })
- if !ok {
- return false
- }
- stat, err := s.Stat()
- return err == nil && stat.Mode()&os.ModeCharDevice != 0
+func evalStr(i *interpreter.Interp, s string) error {
+ _, err := i.Eval(s)
+ return err
}
diff --git a/parser/package.go b/parser/package.go
index 67e2867..d1e326f 100644
--- a/parser/package.go
+++ b/parser/package.go
@@ -6,6 +6,7 @@ import (
"github.com/mvertes/parscan/vm"
)
+// Packages contains binary package references.
var Packages = map[string]map[string]vm.Value{
"fmt": fmtPkg,
}
diff --git a/parser/symbol.go b/parser/symbol.go
index 3aba4e5..3ad8fda 100644
--- a/parser/symbol.go
+++ b/parser/symbol.go
@@ -8,8 +8,10 @@ import (
"github.com/mvertes/parscan/vm"
)
+// SymKind represents the symbol kind.
type SymKind int
+// Symbol kinds.
const (
SymValue SymKind = iota // a value defined in the runtime
SymType // a type
@@ -22,8 +24,10 @@ const (
//go:generate stringer -type=SymKind
+// UnsetAddr denotes an unset symbol index (vs 0).
const UnsetAddr = -65535
+// Symbol structure used in parser and compiler.
type Symbol struct {
Kind SymKind
Index int // address of symbol in frame
@@ -35,6 +39,7 @@ type Symbol struct {
Used bool //
}
+// SymbolType returns the VM type of a symbol.
func SymbolType(s *Symbol) *vm.Type {
if s.Type != nil {
return s.Type
@@ -42,11 +47,7 @@ func SymbolType(s *Symbol) *vm.Type {
return vm.TypeOf(s.Value)
}
-// AddSym add a new named value at memory position i in the parser symbol table.
-// func (p *Parser) AddSym(i int, name string, v vm.Value) {
-// p.addSym(i, name, v, SymValue, nil, false)
-// }
-
+// AddSymbol adds a new named value at memory position i in the parser symbol table.
func (p *Parser) AddSymbol(i int, name string, v vm.Value, k SymKind, t *vm.Type, local bool) {
name = strings.TrimPrefix(name, "/")
p.Symbols[name] = &Symbol{Kind: k, Index: i, Local: local, Value: v, Type: t}
diff --git a/scanner/scan.go b/scanner/scan.go
index b5e9962..edd8b1c 100644
--- a/scanner/scan.go
+++ b/scanner/scan.go
@@ -155,10 +155,7 @@ func (sc *Scanner) Scan(src string, semiEOF bool) (tokens []Token, err error) {
func loc(s string, p int) string {
s = s[:p]
l := strings.Count(s, "\n")
- li := strings.LastIndex(s, "\n")
- if li < 0 {
- li = 0
- }
+ li := max(strings.LastIndex(s, "\n"), 0)
return fmt.Sprintf("%d:%d", 1+l, 1+len(s)-li)
}
diff --git a/vm/vm.go b/vm/vm.go
index f981415..18207f7 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -11,10 +11,8 @@ import (
const debug = true
-type (
- Op int // Op is a VM opcode (bytecode instruction).
- Pos int // Pos is the source code position of instruction
-)
+// Op is a VM opcode (bytecode instruction).
+type Op int
//go:generate stringer -type=Op
@@ -58,6 +56,9 @@ const (
Swap // --
)
+// Pos is the source code position of instruction.
+type Pos int
+
// Instruction represents a virtual machine bytecode instruction.
type Instruction struct {
Pos // position in source