aboutsummaryrefslogtreecommitdiff
path: root/pkg/lang/parser
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/parser')
-rw-r--r--pkg/lang/parser/errors.go60
-rw-r--r--pkg/lang/parser/exprs.go8
-rw-r--r--pkg/lang/parser/parser.go7
-rw-r--r--pkg/lang/parser/stmts.go8
4 files changed, 74 insertions, 9 deletions
diff --git a/pkg/lang/parser/errors.go b/pkg/lang/parser/errors.go
new file mode 100644
index 0000000..a020e01
--- /dev/null
+++ b/pkg/lang/parser/errors.go
@@ -0,0 +1,60 @@
+package parser
+
+import (
+ "fmt"
+ "jinx/pkg/lang/scanner/token"
+ "jinx/pkg/libs/source"
+)
+
+type ErrFunctionNoThisAllowed struct {
+ At source.Loc
+}
+
+func (e ErrFunctionNoThisAllowed) Error() string {
+ return fmt.Sprintf("non-method function cannot have 'this' as parameter at %v", e.At)
+}
+
+type ErrFunctionLiteralNoThisAllowed struct {
+ At source.Loc
+}
+
+func (e ErrFunctionLiteralNoThisAllowed) Error() string {
+ return fmt.Sprintf("function literal cannot have 'this' as parameter at %v", e.At)
+}
+
+type ErrExpectedToken struct {
+ At source.Loc
+ Wanted token.TokenKind
+ Got token.Token
+}
+
+func (e ErrExpectedToken) Error() string {
+ return fmt.Sprintf("unexpected token %v, wanted %v at %v", e.Got, e.Wanted, e.At)
+}
+
+type ErrExpectedStatementEnd struct {
+ At source.Loc
+ Got token.Token
+}
+
+func (e ErrExpectedStatementEnd) Error() string {
+ return fmt.Sprintf("expected statement end, got %v at %v", e.Got, e.At)
+}
+
+type ErrExpectedUnitExpressionStart struct {
+ At source.Loc
+ Got token.Token
+}
+
+func (e ErrExpectedUnitExpressionStart) Error() string {
+ return fmt.Sprintf("unexpected token %v, wanted unit expression start at %v", e.Got, e.At)
+}
+
+type ErrExpectedValueLiteral struct {
+ At source.Loc
+ Got token.Token
+}
+
+func (e ErrExpectedValueLiteral) Error() string {
+ return fmt.Sprintf("unexpected token %v, wanted value literal %v", e.Got, e.At)
+}
diff --git a/pkg/lang/parser/exprs.go b/pkg/lang/parser/exprs.go
index 48d1a8c..1603838 100644
--- a/pkg/lang/parser/exprs.go
+++ b/pkg/lang/parser/exprs.go
@@ -1,7 +1,6 @@
package parser
import (
- "fmt"
"jinx/pkg/lang/ast"
"jinx/pkg/lang/scanner/token"
)
@@ -207,7 +206,8 @@ func (p *Parser) parseUnitExpr() (ast.Expr, error) {
case token.KwTrue, token.KwFalse, token.KwNull, token.KwThis:
return p.parseValueLitExpr()
default:
- panic(fmt.Errorf("unexpected token '%v', wanted unit expression start", p.peek().Kind))
+ tok := p.peek()
+ return ast.Expr{}, ErrExpectedUnitExpressionStart{tok.At, tok}
}
}
@@ -250,7 +250,7 @@ func (p *Parser) parseFnLitExpr() (ast.Expr, error) {
}
if hasThis {
- return ast.Expr{}, fmt.Errorf("function literal cannot have 'this' parameter")
+ return ast.Expr{}, ErrFunctionLiteralNoThisAllowed{fnTok.At}
}
// TODO: Also parse just an expression
@@ -406,6 +406,6 @@ func (p *Parser) parseValueLitExpr() (ast.Expr, error) {
Value: ast.ExprThis{},
}, nil
default:
- panic(fmt.Errorf("unexpected token '%v', wanted value literal", tok))
+ return ast.Expr{}, ErrExpectedValueLiteral{At: tok.At, Got: tok}
}
}
diff --git a/pkg/lang/parser/parser.go b/pkg/lang/parser/parser.go
index 0ff4b09..d939e4b 100644
--- a/pkg/lang/parser/parser.go
+++ b/pkg/lang/parser/parser.go
@@ -1,7 +1,6 @@
package parser
import (
- "fmt"
"jinx/pkg/lang/ast"
"jinx/pkg/lang/scanner/token"
)
@@ -88,7 +87,11 @@ func (p *Parser) next() token.Token {
func (p *Parser) expect(kind token.TokenKind) (token.Token, error) {
tok := p.next()
if tok.Kind != kind {
- return token.Token{}, fmt.Errorf("expected '%v', got '%v'", kind, tok.Kind)
+ return token.Token{}, ErrExpectedToken{
+ At: tok.At,
+ Wanted: kind,
+ Got: tok,
+ }
}
return tok, nil
diff --git a/pkg/lang/parser/stmts.go b/pkg/lang/parser/stmts.go
index c20f7a0..fe5c65b 100644
--- a/pkg/lang/parser/stmts.go
+++ b/pkg/lang/parser/stmts.go
@@ -1,7 +1,6 @@
package parser
import (
- "fmt"
"jinx/pkg/lang/ast"
"jinx/pkg/lang/scanner/token"
)
@@ -154,7 +153,7 @@ func (p *Parser) parseFnDeclStmt() (ast.Stmt, error) {
}
if hasThis {
- return ast.Stmt{}, fmt.Errorf("function cannot have 'this' as a parameter")
+ return ast.Stmt{}, ErrFunctionNoThisAllowed{At: fnTok.At}
}
block, err := p.parseBlock()
@@ -640,7 +639,10 @@ func (p *Parser) parseEmptyStmt() (ast.Stmt, error) {
func (p *Parser) parseStmtEnd() error {
tok := p.peek()
if !tok.CanEndStmt() {
- return fmt.Errorf("wanted statement end, received: '%v'", tok.Kind)
+ return ErrExpectedStatementEnd{
+ At: tok.At,
+ Got: tok,
+ }
}
p.next()
return nil