Fancy compiler errors
This commit is contained in:
parent
1d79aeaa0b
commit
56c36f01dd
2
lexer.go
2
lexer.go
@ -186,7 +186,7 @@ func (l *Lexer) nextToken() (string, error) {
|
||||
token += string(*l.nextRune())
|
||||
}
|
||||
|
||||
if len(token) == 0 && len(l.Runes) > 0 {
|
||||
if len(token) == 0 && len(l.Runes) != 0 {
|
||||
return string(*l.nextRune()), nil
|
||||
}
|
||||
|
||||
|
78
main.go
78
main.go
@ -4,25 +4,75 @@ package main
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const ERROR_LOG_LINES = 10
|
||||
|
||||
func countTabs(line string) int {
|
||||
tabs := 0
|
||||
for _, rune := range line {
|
||||
if rune == '\t' {
|
||||
tabs++
|
||||
}
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
func printCompilerError(file string, source string, err CompilerError) {
|
||||
sourceRunes := []rune(source)
|
||||
lines := strings.Split(source, "\n")
|
||||
line := 0
|
||||
col := 0
|
||||
var i uint64
|
||||
for i = 0; i < err.Position; i++ {
|
||||
col++
|
||||
if sourceRunes[i] == '\n' {
|
||||
line++
|
||||
col = 0
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Failed to compile: " + err.Message + " (at " + file + ":" + strconv.Itoa(line+1) + ":" + strconv.Itoa(col+1) + ")")
|
||||
|
||||
linesStart := max(0, line-ERROR_LOG_LINES)
|
||||
linesEnd := min(len(lines), line+ERROR_LOG_LINES+1)
|
||||
|
||||
for _, line := range lines[linesStart:line] {
|
||||
println(strings.Replace(line, "\t", " ", -1))
|
||||
}
|
||||
|
||||
tabs := countTabs(lines[line])
|
||||
println(strings.Repeat(" ", col+tabs*3) + "v--- error occurs here ---")
|
||||
|
||||
for _, line := range lines[line:linesEnd] {
|
||||
println(strings.Replace(line, "\t", " ", -1))
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
log.Fatalln("Usage: " + os.Args[0] + " <file>")
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(os.Args[1])
|
||||
file := os.Args[1]
|
||||
content, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalln("Cannot open input file.", err)
|
||||
}
|
||||
|
||||
tokens, err := lexer(string(content))
|
||||
source := string(content)
|
||||
|
||||
tokens, err := lexer(source)
|
||||
if err != nil {
|
||||
if c, ok := err.(CompilerError); ok {
|
||||
log.Fatalln(err, "\nv- here\n"+string([]rune(string(content))[c.Position:]))
|
||||
printCompilerError(file, source, c)
|
||||
} else {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Tokens:\n%+#v\n\n", tokens)
|
||||
@ -31,10 +81,12 @@ func main() {
|
||||
parsed, err := parser.parseFile()
|
||||
if err != nil {
|
||||
if c, ok := err.(CompilerError); ok {
|
||||
log.Fatalln(err, "\nv- here\n"+string([]rune(string(content))[c.Position:]))
|
||||
printCompilerError(file, source, c)
|
||||
} else {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Parsed:\n%+#v\n\n", parsed)
|
||||
@ -44,10 +96,14 @@ func main() {
|
||||
if len(errors) != 0 {
|
||||
for _, err = range errors {
|
||||
if c, ok := err.(CompilerError); ok {
|
||||
log.Fatalln(err, "\nv- here\n"+string([]rune(string(content))[c.Position:]))
|
||||
printCompilerError(file, source, c)
|
||||
} else {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Fatalln(err)
|
||||
if len(errors) != 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,10 +112,12 @@ func main() {
|
||||
wat, err := backendWAT(*parsed)
|
||||
if err != nil {
|
||||
if c, ok := err.(CompilerError); ok {
|
||||
log.Fatalln(err, "\nv- here\n"+string([]rune(string(content))[c.Position:]))
|
||||
printCompilerError(file, source, c)
|
||||
} else {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("WAT: " + wat)
|
||||
|
@ -802,7 +802,7 @@ func (p *Parser) expectFunction() (*ParsedFunction, error) {
|
||||
break
|
||||
}
|
||||
|
||||
if len(parameters) > 0 {
|
||||
if len(parameters) != 0 {
|
||||
_, err := p.expectSeparator(Separator_Comma)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -182,7 +182,7 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression, block *B
|
||||
|
||||
if fc.Parameters != nil {
|
||||
paramsErrors := v.validateExpression(fc.Parameters, block)
|
||||
if len(paramsErrors) > 0 {
|
||||
if len(paramsErrors) != 0 {
|
||||
errors = append(errors, paramsErrors...)
|
||||
return errors
|
||||
}
|
||||
@ -212,7 +212,7 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression, block *B
|
||||
neg := expr.Value.(NegateExpression)
|
||||
|
||||
valErrors := v.validateExpression(&neg.Value, block)
|
||||
if len(valErrors) > 0 {
|
||||
if len(valErrors) != 0 {
|
||||
errors = append(errors, valErrors...)
|
||||
return errors
|
||||
}
|
||||
@ -230,6 +230,9 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression, block *B
|
||||
|
||||
func (v *Validator) validateExpression(expr *Expression, block *Block) []error {
|
||||
errors := v.validatePotentiallyVoidExpression(expr, block)
|
||||
if len(errors) != 0 {
|
||||
return errors
|
||||
}
|
||||
|
||||
if expr.ValueType == nil {
|
||||
errors = append(errors, v.createError("expression must not evaluate to void", expr.Position))
|
||||
|
Loading…
Reference in New Issue
Block a user