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 or executing a script.
5  */
6 module mildew.exceptions;
7 
8 import mildew.lexer: Token;
9 
10 /**
11  * This exception is thrown by the Lexer and Parser when an error occurs during tokenizing or parsing.
12  */
13 class ScriptCompileException : Exception
14 {
15     /**
16      * Constructor. Token may be invalid when thrown by the Lexer.
17      */
18     this(string msg, Token tok, string file = __FILE__, size_t line = __LINE__)
19     {
20         super(msg, file, line);
21         token = tok;
22     }
23 
24     /**
25      * Returns a string that represents the error message and the token and the location of the token where
26      * the error occurred.
27      */
28     override string toString() const
29     {
30         import std.format: format;
31         return format("ScriptCompileException: %s at token %s at %s", msg, token, token.position);
32     }
33 
34     /**
35      * The offending token. This may have an invalid position field depending on why the error was thrown.
36      */
37     Token token;
38 }
39 
40 /**
41  * This exception is generated by the new keyword and stored in a VisitResult that propagates through the
42  * call stack so that traceback line numbers in the script can be added to it. It is only thrown when
43  * the calls get back to Interpreter.evaluate. This exception can also be "thrown" and caught
44  * by the script.
45  */
46 class ScriptRuntimeException : Exception
47 {
48     import mildew.nodes: StatementNode;
49     import mildew.types.any: ScriptAny;
50     
51     /// Constructor
52     this(string msg, string file = __FILE__, size_t line = __LINE__)
53     {
54         super(msg, file, line);
55     }
56 
57     /// Returns a string containing the script code traceback as well as exception message.
58     override string toString() const
59     {
60         import std.conv: to;
61 
62         string str = "ScriptRuntimeException: " ~ msg ~ "\n";
63         foreach(tb ; scriptTraceback)
64         {
65             str ~= " at line " ~ tb.line.to!string ~ ":" ~ tb.toString() ~ "\n";
66         }
67         return str;
68     }
69 
70     /// A chain of statement nodes where the exception occurred
71     StatementNode[] scriptTraceback;
72     /// If it is thrown by a script, this is the value that was thrown
73     ScriptAny thrownValue = ScriptAny.UNDEFINED; 
74 }