diff options
| author | Marc Vertes <mvertes@free.fr> | 2024-06-30 15:23:02 +0200 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2024-06-30 15:23:02 +0200 |
| commit | 0ad649db1e886f98002f4d90488a8e4adbac3de8 (patch) | |
| tree | 32be6a4cecf83487dd6a91e8a9aa1da709840b0f | |
| parent | 4acaa8e1630a359117d535a20b0af9554058d1e3 (diff) | |
improve parser errorsfix-untyped-assign
| -rw-r--r-- | .golangci.yaml | 3 | ||||
| -rw-r--r-- | parser/compiler.go | 8 | ||||
| -rw-r--r-- | parser/parse.go | 23 | ||||
| -rw-r--r-- | parser/type.go | 16 |
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()) } } |
