Skip to content

Commit

Permalink
Improve type error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
algorandskiy authored and pzbitskiy committed Apr 6, 2022
1 parent d9cf7fd commit 9eedfc8
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 31 deletions.
8 changes: 4 additions & 4 deletions compiler/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -968,20 +968,20 @@ func (n *funCallNode) getTypeQuadruple() (exprType, exprType, exprType, exprType
return tph, tpl, rtpl, rtph, err
}

func (n *funCallNode) checkBuiltinArgs() (err error) {
func (n *funCallNode) checkBuiltinArgs() (argErrorPos int, err error) {
args := n.children()
for i, arg := range args {
tp, err := argOpTypeFromSpec(n.name, i)
if err != nil {
return err
return i, err
}
argExpr := arg.(ExprNodeIf)
actualType, err := argExpr.getType()
if err != nil {
return err
return i, err
}
if tp != unknownType && actualType != unknownType && actualType != tp {
return fmt.Errorf("incompatible types: (exp) %s vs %s (actual) in expr '%s'", tp, actualType, n)
return i, fmt.Errorf("incompatible types: (exp) %s vs %s (actual) in expr '%s'", tp, actualType, n)
}
}
return
Expand Down
4 changes: 2 additions & 2 deletions compiler/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,12 @@ func (err *ParserError) String() (msg string) {
}
switch err.errorType {
case semanticError:
msg = fmt.Sprintf("error at %sline %d, col %d near token \"%s\"", filename, err.line, err.column, err.token)
msg = fmt.Sprintf("error at %sline %d, col %d near token '%s'", filename, err.line, err.column, err.token)
lines := append([]string{msg}, err.excerpt...)
lines = append(lines, err.msg)
msg = strings.Join(lines, "\n")
case syntaxError:
msg = fmt.Sprintf("syntax error at %sline %d, col %d near token \"%s\"", filename, err.line, err.column, err.token)
msg = fmt.Sprintf("syntax error at %sline %d, col %d near token '%s'", filename, err.line, err.column, err.token)
lines := append([]string{msg}, err.excerpt...)
msg = strings.Join(lines, "\n")
case ambiguityError:
Expand Down
39 changes: 20 additions & 19 deletions compiler/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,10 @@ func (l *treeNodeListener) EnterTermAssert(ctx *gen.TermAssertContext) {
listener := newExprListener(l.ctx, l.parent)
exprNode := listener.funCallEnterImpl(name, []gen.IExprContext{ctx.Expr()})

err := exprNode.checkBuiltinArgs()
_, err := exprNode.checkBuiltinArgs()
if err != nil {
parser := ctx.GetParser()
token := ctx.ASSERT().GetSymbol()
token := ctx.Expr().GetStart()
rule := ctx.GetRuleContext()
reportError(err.Error(), parser, token, rule)
return
Expand Down Expand Up @@ -602,10 +602,10 @@ func (l *treeNodeListener) EnterDoLog(ctx *gen.DoLogContext) {
listener := newExprListener(l.ctx, l.parent)
exprNode := listener.funCallEnterImpl(name, []gen.IExprContext{ctx.Expr()})

err := exprNode.checkBuiltinArgs()
_, err := exprNode.checkBuiltinArgs()
if err != nil {
parser := ctx.GetParser()
token := ctx.LOG().GetSymbol()
token := ctx.Expr().GetStart()
rule := ctx.GetRuleContext()
reportError(err.Error(), parser, token, rule)
return
Expand Down Expand Up @@ -1018,7 +1018,7 @@ func (l *exprListener) EnterBuiltinFunCall(ctx *gen.BuiltinFunCallContext) {
}
}

err := exprNode.checkBuiltinArgs()
_, err := exprNode.checkBuiltinArgs()
if err != nil {
parser := ctx.GetParser()
token := ctx.BUILTINFUNC().GetSymbol()
Expand Down Expand Up @@ -1102,8 +1102,9 @@ func (l *treeNodeListener) EnterBuiltinVarStatement(ctx *gen.BuiltinVarStatement
listener := newExprListener(l.ctx, l.parent)
exprNode := listener.funCallEnterImpl(tealOpName, exprs)

err := exprNode.checkBuiltinArgs()
errPos, err := exprNode.checkBuiltinArgs()
if err != nil {
token := exprs[errPos].GetStart()
reportError(err.Error(), ctx.GetParser(), token, ctx.GetRuleContext())
return
}
Expand Down Expand Up @@ -1177,10 +1178,10 @@ func (l *exprListener) EnterEcDsaFunCall(ctx *gen.EcDsaFunCallContext) {
field := ctx.ECDSACURVE().GetText()
exprNode := l.funCallEnterImpl(name, ctx.AllExpr(), field)

err := exprNode.checkBuiltinArgs()
errPos, err := exprNode.checkBuiltinArgs()
if err != nil {
parser := ctx.GetParser()
token := ctx.ECDSAVERIFY().GetSymbol()
token := ctx.Expr(errPos).GetStart()
rule := ctx.GetRuleContext()
reportError(err.Error(), parser, token, rule)
return
Expand Down Expand Up @@ -1221,7 +1222,7 @@ func (l *exprListener) EnterExtractFunCall(ctx *gen.ExtractFunCallContext) {
}
}

err := exprNode.checkBuiltinArgs()
_, err := exprNode.checkBuiltinArgs()
if err != nil {
parser := ctx.GetParser()
token := ctx.EXTRACT().GetSymbol()
Expand Down Expand Up @@ -1276,9 +1277,9 @@ func (l *exprListener) EnterTupleExpr(ctx *gen.TupleExprContext) {

exprNode := l.funCallEnterImpl(name, ctx.AllExpr(), field)

err := exprNode.checkBuiltinArgs()
errPos, err := exprNode.checkBuiltinArgs()
if err != nil {
token := ctx.GetParser().GetCurrentToken()
token := ctx.Expr(errPos).GetStart()
reportError(err.Error(), ctx.GetParser(), token, ctx.GetRuleContext())
return
}
Expand Down Expand Up @@ -1315,9 +1316,9 @@ func (l *exprListener) EnterBuiltinVarTupleExpr(ctx *gen.BuiltinVarTupleExprCont

exprNode := l.funCallEnterImpl(name, ctx.AllExpr())

err := exprNode.checkBuiltinArgs()
errPos, err := exprNode.checkBuiltinArgs()
if err != nil {
token := ctx.GetParser().GetCurrentToken()
token := ctx.Expr(errPos).GetStart()
reportError(err.Error(), ctx.GetParser(), token, ctx.GetRuleContext())
return
}
Expand All @@ -1339,9 +1340,9 @@ func (l *exprListener) EnterAccountsBalanceExpr(ctx *gen.AccountsBalanceExprCont
}
exprNode := l.funCallEnterImpl(name, []gen.IExprContext{ctx.Expr()})

err := exprNode.checkBuiltinArgs()
_, err := exprNode.checkBuiltinArgs()
if err != nil {
token := ctx.GetParser().GetCurrentToken()
token := ctx.Expr().GetStart()
reportError(err.Error(), ctx.GetParser(), token, ctx.GetRuleContext())
return
}
Expand All @@ -1357,9 +1358,9 @@ func (l *exprListener) EnterAccountsSingleMethodsExpr(ctx *gen.AccountsSingleMet
}
exprNode := l.funCallEnterImpl(name, ctx.AllExpr())

err := exprNode.checkBuiltinArgs()
errPos, err := exprNode.checkBuiltinArgs()
if err != nil {
token := ctx.GetParser().GetCurrentToken()
token := ctx.Expr(errPos).GetStart()
reportError(err.Error(), ctx.GetParser(), token, ctx.GetRuleContext())
return
}
Expand All @@ -1378,9 +1379,9 @@ func (l *exprListener) EnterAppsSingleMethodsExpr(ctx *gen.AppsSingleMethodsExpr

exprNode := l.funCallEnterImpl(name, []gen.IExprContext{ctx.Expr(1)})

err := exprNode.checkBuiltinArgs()
_, err := exprNode.checkBuiltinArgs()
if err != nil {
token := ctx.GetParser().GetCurrentToken()
token := ctx.Expr(1).GetStart()
reportError(err.Error(), ctx.GetParser(), token, ctx.GetRuleContext())
return
}
Expand Down
12 changes: 6 additions & 6 deletions compiler/syntax_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ function logic() {
a.Equal(1, len(errors))
a.Equal("let e = if a > 0 {1} else {}", errors[0].excerpt[0])
a.Equal(" -----^-----", errors[0].excerpt[1])
msg := `syntax error at line 2, col 27 near token "}"
msg := `syntax error at line 2, col 27 near token '}'
let e = if a > 0 {1} else {}
-----^-----`
a.Equal(msg, errors[0].String())
Expand All @@ -123,7 +123,7 @@ let e = if a > 0 {1} else {}
a.Equal(1, len(errors))
a.Equal("a = 33", errors[0].excerpt[0])
a.Equal("^-----", errors[0].excerpt[1])
msg = `syntax error at line 1, col 0 near token "a"
msg = `syntax error at line 1, col 0 near token 'a'
a = 33
^-----`
a.Equal(msg, errors[0].String())
Expand All @@ -135,7 +135,7 @@ a = 33
a.Equal(1, len(errors))
a.Equal("let a = 33bbb", errors[0].excerpt[0])
a.Equal(" -----^-----", errors[0].excerpt[1])
msg = `syntax error at line 1, col 10 near token "bbb"
msg = `syntax error at line 1, col 10 near token 'bbb'
let a = 33bbb
-----^-----`
a.Equal(msg, errors[0].String())
Expand All @@ -155,7 +155,7 @@ function logic() {
a.Equal(1, len(errors))
a.Equal(" if e == 1 {", errors[0].excerpt[0])
a.Equal(" -----^-----", errors[0].excerpt[1])
msg = `error at line 3, col 4 near token "e"
msg = `error at line 3, col 4 near token 'e'
if e == 1 {
-----^-----
ident not found`
Expand All @@ -178,7 +178,7 @@ function logic() {
a.Equal(1, len(errors))
a.Equal(" x = 2", errors[0].excerpt[0])
a.Equal(" -----^-----", errors[0].excerpt[1])
msg = `error at line 6, col 2 near token "x"
msg = `error at line 6, col 2 near token 'x'
x = 2
-----^-----
incompatible types: (var) byte[] vs uint64 (expr)`
Expand All @@ -197,7 +197,7 @@ function logic() {
a.Equal(1, len(errors))
a.Equal(` e = "123"`, errors[0].excerpt[0])
a.Equal("----^-----", errors[0].excerpt[1])
msg = `error at line 4, col 1 near token "e"
msg = `error at line 4, col 1 near token 'e'
e = "123"
----^-----
incompatible types: (var) uint64 vs byte[] (expr)`
Expand Down

0 comments on commit 9eedfc8

Please sign in to comment.