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 }