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 ~ "\n";
81         foreach(tb ; scriptTraceback)
82         {
83             str ~= " at line " ~ tb[0].to!string ~ ":" ~ tb[1] ~ "\n";
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 }