# Copyright 2022 Mattia Giambirtone & All Contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## Utilities to print formatted error messages to stderr import ../frontend/compiler import ../frontend/parser import ../frontend/lexer import ../util/serializer import std/os import std/terminal import std/strutils import std/strformat proc print*(exc: CompileError) = ## Prints a formatted error message ## for compilation errors to stderr var file = exc.file if file notin ["", ""]: file = relativePath(exc.file, getCurrentDir()) let line = exc.compiler.getSource().splitLines()[exc.line - 1].strip(chars={'\n'}) let fn = exc.compiler.getCurrentFunction() let node = exc.node let pos = node.getRelativeBoundaries() stderr.styledWrite(fgRed, styleBright, "Error in ", fgYellow, &"{file}:{exc.line}:{pos.start}") if not fn.isNil() and fn.kind == funDecl: stderr.styledWrite(fgRed, styleBright, " in function ", fgYellow, FunDecl(fn).name.token.lexeme) stderr.styledWriteLine(styleBright, fgDefault, ": ", exc.msg) stderr.styledWrite(fgRed, styleBright, "Source line: ", resetStyle, fgDefault, line[0..", ""]: file = relativePath(exc.file, getCurrentDir()) let line = exc.parser.getSource().splitLines()[exc.line - 1].strip(chars={'\n'}) let pos = exc.token.relPos stderr.styledWriteLine(fgRed, styleBright, "Error in ", fgYellow, &"{file}:{exc.line}:{pos.start}", fgDefault, ": " & exc.msg) stderr.styledWrite(fgRed, styleBright, "Source line: ", resetStyle, fgDefault, line[0..", ""]: file = relativePath(exc.file, getCurrentDir()) let line = exc.lexer.getSource().splitLines()[exc.line - 1].strip(chars={'\n'}) let pos = exc.pos stderr.styledWriteLine(fgRed, styleBright, "Error in ", fgYellow, &"{file}:{exc.line}:{pos.start}", fgDefault, ": " & exc.msg) stderr.styledWrite(fgRed, styleBright, "Source line: ", resetStyle, fgDefault, line[0..", ""]: file = relativePath(exc.file, getCurrentDir()) stderr.styledWriteLine(fgRed, styleBright, "Error while (de-)serializing ", fgYellow, file, fgDefault, &": {exc.msg}") proc print*(exc: IOError, file: string) = ## Prints a formatted error message ## for nim I/O errors to stderr var file = file if file notin ["", ""]: file = relativePath(file, getCurrentDir()) stderr.styledWriteLine(fgRed, styleBright, "Error while trying to read ", fgYellow, file, fgDefault, &": {exc.msg}") proc print*(exc: OSError, file: string, errno: OSErrorCode) = ## Prints a formatted error message ## for nim OS errors to stderr var file = file if file notin ["", ""]: file = relativePath(file, getCurrentDir()) stderr.styledWriteLine(fgRed, styleBright, "Error while trying to read ", fgYellow, file, fgDefault, &": {exc.msg} ({osErrorMsg(errno)})", fgRed, "[errno ", fgYellow, $errno, fgRed, "]")