1 /** 2 This module implements the exception classes that can be thrown by the script. These should be 3 caught and printed to provide meaningful information about why an exception was thrown while 4 parsing, compiling, or executing a script. 5 6 ──────────────────────────────────────────────────────────────────────────────── 7 8 Copyright (C) 2021 pillager86.rf.gd 9 10 This program is free software: you can redistribute it and/or modify it under 11 the terms of the GNU General Public License as published by the Free Software 12 Foundation, either version 3 of the License, or (at your option) any later 13 version. 14 15 This program is distributed in the hope that it will be useful, but WITHOUT ANY 16 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 17 PARTICULAR PURPOSE. See the GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License along with 20 this program. If not, see <https://www.gnu.org/licenses/>. 21 */ 22 module mildew.exceptions; 23 24 import std.typecons; 25 26 import mildew.lexer: Token; 27 28 /** 29 * This exception is thrown by the Lexer and Parser when an error occurs during tokenizing or parsing. 30 */ 31 class ScriptCompileException : Exception 32 { 33 /** 34 * Constructor. Token may be invalid when thrown by the Lexer. 35 */ 36 this(string msg, Token tok, string file = __FILE__, size_t line = __LINE__) 37 { 38 super(msg, file, line); 39 token = tok; 40 } 41 42 /** 43 * Returns a string that represents the error message and the token and the location of the token where 44 * the error occurred. 45 */ 46 override string toString() const 47 { 48 import std.format: format; 49 return format("ScriptCompileException: %s at token %s at %s", msg, token, token.position); 50 } 51 52 /** 53 * The offending token. This may have an invalid position field depending on why the error was thrown. 54 */ 55 Token token; 56 } 57 58 /** 59 * This exception is only thrown once a traceback of lines is collected from the script source code 60 * and there are no surrounding try-catch blocks around where the exception occurred. D bindings 61 * to native functions should not directly throw this, but instead set the NativeFunctionError 62 * flag and return. 63 */ 64 class ScriptRuntimeException : Exception 65 { 66 import mildew.nodes: StatementNode; 67 import mildew.types.any: ScriptAny; 68 69 /// Constructor 70 this(string msg, string file = __FILE__, size_t line = __LINE__) 71 { 72 super(msg, file, line); 73 } 74 75 /// Returns a string containing the script code traceback as well as exception message. 76 override string toString() const 77 { 78 import std.conv: to; 79 80 string str = "ScriptRuntimeException: " ~ msg; 81 foreach(tb ; scriptTraceback) 82 { 83 str ~= "\n at line " ~ tb[0].to!string ~ ":" ~ tb[1]; 84 } 85 return str; 86 } 87 88 /// A chain of statements where the exception occurred 89 Tuple!(immutable size_t, string)[] scriptTraceback; 90 /// If it is thrown by a script, this is the value that was thrown 91 ScriptAny thrownValue = ScriptAny.UNDEFINED; 92 }