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. Native bindings 61 * may either throw this directly (if called from a script) or set the NativeFunctionError flag 62 */ 63 class ScriptRuntimeException : Exception 64 { 65 import mildew.nodes: StatementNode; 66 import mildew.types.any: ScriptAny; 67 68 /// Constructor 69 this(string msg, string file = __FILE__, size_t line = __LINE__) 70 { 71 super(msg, file, line); 72 } 73 74 /// Returns a string containing the script code traceback as well as exception message. 75 override string toString() const 76 { 77 import std.conv: to; 78 79 string str = "ScriptRuntimeException: " ~ msg; 80 foreach(tb ; scriptTraceback) 81 { 82 str ~= "\n at line " ~ tb[0].to!string ~ ":" ~ tb[1]; 83 } 84 return str; 85 } 86 87 /// A chain of statements where the exception occurred 88 Tuple!(immutable size_t, string)[] scriptTraceback; 89 /// If it is thrown by a script, this is the value that was thrown 90 ScriptAny thrownValue = ScriptAny.UNDEFINED; 91 }