summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2024-06-30 15:23:02 +0200
committerMarc Vertes <mvertes@free.fr>2024-06-30 15:23:02 +0200
commit0ad649db1e886f98002f4d90488a8e4adbac3de8 (patch)
tree32be6a4cecf83487dd6a91e8a9aa1da709840b0f
parent4acaa8e1630a359117d535a20b0af9554058d1e3 (diff)
improve parser errorsfix-untyped-assign
-rw-r--r--.golangci.yaml3
-rw-r--r--parser/compiler.go8
-rw-r--r--parser/parse.go23
-rw-r--r--parser/type.go16
4 files changed, 32 insertions, 18 deletions
diff --git a/.golangci.yaml b/.golangci.yaml
index 64e12a5..f2191fb 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -5,6 +5,9 @@ linters:
- gofumpt
- gosec
- misspell
+ - perfsprint
+ - prealloc
- predeclared
- reassign
- revive
+ - unconvert
diff --git a/parser/compiler.go b/parser/compiler.go
index aa16888..05462eb 100644
--- a/parser/compiler.go
+++ b/parser/compiler.go
@@ -268,7 +268,7 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) {
} else {
i = s.value.Data.Int() - int64(len(c.Code))
}
- emit(int64(t.Pos), vm.JumpSetTrue, int64(i))
+ emit(int64(t.Pos), vm.JumpSetTrue, i)
case lang.Goto:
var i int64
@@ -440,17 +440,17 @@ type DumpValue struct {
// This design choice allows the Virtual Machine (VM) to evolve its memory management strategies
// without compromising backward compatibility with dumps generated by previous versions.
func (c *Compiler) Dump() *Dump {
- var dv []*DumpValue
dict := c.symbolsByIndex()
+ dv := make([]*DumpValue, len(c.Data))
for i, d := range c.Data {
e := dict[i]
- dv = append(dv, &DumpValue{
+ dv[i] = &DumpValue{
Index: e.index,
Name: e.name,
Kind: int(e.kind),
Type: e.Type.Name,
Value: d.Data.Interface(),
- })
+ }
}
return &Dump{Values: dv}
diff --git a/parser/parse.go b/parser/parse.go
index 0061c4f..537b68e 100644
--- a/parser/parse.go
+++ b/parser/parse.go
@@ -29,6 +29,15 @@ type Parser struct {
clonum int // closure instance number
}
+// Parser errors.
+var (
+ ErrBody = errors.New("missign body")
+ ErrBreak = errors.New("invalid break statement")
+ ErrContinue = errors.New("invalid continue statement")
+ ErrFor = errors.New("invalid for statement")
+ ErrGoto = errors.New("invalid goto statement")
+)
+
// Scan performs lexical analysis on s and returns Tokens or an error.
func (p *Parser) Scan(s string, endSemi bool) (Tokens, error) {
return p.Scanner.Scan(s, endSemi)
@@ -122,12 +131,12 @@ func (p *Parser) parseBreak(in Tokens) (out Tokens, err error) {
label = p.breakLabel
case 2:
if in[1].Tok != lang.Ident {
- return nil, fmt.Errorf("invalid break statement")
+ return nil, ErrBreak
}
// TODO: check validity of user provided label
label = in[1].Str
default:
- return nil, fmt.Errorf("invalid break statement")
+ return nil, ErrBreak
}
out = Tokens{{Tok: lang.Goto, Str: label}}
return out, err
@@ -140,12 +149,12 @@ func (p *Parser) parseContinue(in Tokens) (out Tokens, err error) {
label = p.continueLabel
case 2:
if in[1].Tok != lang.Ident {
- return nil, fmt.Errorf("invalid continue statement")
+ return nil, ErrContinue
}
// TODO: check validity of user provided label
label = in[1].Str
default:
- return nil, fmt.Errorf("invalid continue statement")
+ return nil, ErrContinue
}
out = Tokens{{Tok: lang.Goto, Str: label}}
return out, err
@@ -153,7 +162,7 @@ func (p *Parser) parseContinue(in Tokens) (out Tokens, err error) {
func (p *Parser) parseGoto(in Tokens) (out Tokens, err error) {
if len(in) != 2 || in[1].Tok != lang.Ident {
- return nil, fmt.Errorf("invalid goto statement")
+ return nil, ErrGoto
}
// TODO: check validity of user provided label
return Tokens{{Tok: lang.Goto, Str: p.funcScope + "/" + in[1].Str}}, nil
@@ -171,7 +180,7 @@ func (p *Parser) parseFor(in Tokens) (out Tokens, err error) {
case 3:
init, cond, post = pre[0], pre[1], pre[2]
default:
- return nil, fmt.Errorf("invalild for statement")
+ return nil, ErrFor
}
breakLabel, continueLabel := p.breakLabel, p.continueLabel
p.pushScope("for" + fc)
@@ -247,7 +256,7 @@ func (p *Parser) parseFunc(in Tokens) (out Tokens, err error) {
bi := in.Index(lang.BraceBlock)
if bi < 0 {
- return out, fmt.Errorf("no function body")
+ return out, ErrBody
}
typ, err := p.parseTypeExpr(in[:bi])
if err != nil {
diff --git a/parser/type.go b/parser/type.go
index ba60e8f..e25431a 100644
--- a/parser/type.go
+++ b/parser/type.go
@@ -20,10 +20,12 @@ const (
// Type parsing error definitions.
var (
- ErrInvalidType = errors.New("invalid type")
- ErrMissingType = errors.New("missing type")
- ErrSyntax = errors.New("syntax error")
- ErrTypeNotImplemented = errors.New("not implemented")
+ ErrFuncType = errors.New("invalid function type")
+ ErrInvalidType = errors.New("invalid type")
+ ErrMissingType = errors.New("missing type")
+ ErrSize = errors.New("invalid size")
+ ErrSyntax = errors.New("syntax error")
+ ErrNotImplemented = errors.New("not implemented")
)
func (p *Parser) parseTypeExpr(in Tokens) (typ *vm.Type, err error) {
@@ -44,7 +46,7 @@ func (p *Parser) parseTypeExpr(in Tokens) (typ *vm.Type, err error) {
}
size, ok := constValue(cval).(int)
if !ok {
- return nil, fmt.Errorf("invalid size")
+ return nil, ErrSize
}
return vm.ArrayOf(size, typ), nil
}
@@ -71,7 +73,7 @@ func (p *Parser) parseTypeExpr(in Tokens) (typ *vm.Type, err error) {
case l >= 2 && in1.Tok == lang.ParenBlock:
indexArgs, out = 1, in[2:]
default:
- return nil, fmt.Errorf("invalid func signature")
+ return nil, ErrFuncType
}
// We can now parse function input and output parameter types.
@@ -125,7 +127,7 @@ func (p *Parser) parseTypeExpr(in Tokens) (typ *vm.Type, err error) {
return vm.StructOf(fields), nil
default:
- return nil, fmt.Errorf("%w: %v", ErrTypeNotImplemented, in[0].Name())
+ return nil, fmt.Errorf("%w: %v", ErrNotImplemented, in[0].Name())
}
}