1 /**
2  * This module contains the main function for the REPL. It also runs script files.
3  */
4 module app;
5 
6 import std.file: readText;
7 import std.stdio;
8 import std..string: strip;
9 
10 import arsd.terminal;
11 
12 import mildew.context;
13 import mildew.exceptions;
14 import mildew.interpreter;
15 import mildew.lexer;
16 import mildew.parser;
17 import mildew.types;
18 
19 /**
20  * This runs a script program and prints the appropriate error message when a script exception is caught.
21  */
22 void evaluateWithErrorChecking(Interpreter interpreter, in string code, in string fileName = "<stdin>")
23 {
24     try 
25     {
26         auto result = interpreter.evaluate(code);
27         writeln("The program successfully returned " ~ result.toString);
28     }
29     catch(ScriptCompileException ex)
30     {
31         writeln("In file " ~ fileName);
32         writefln("%s", ex);
33     }
34     catch(ScriptRuntimeException ex)
35     {
36         writeln("In file " ~ fileName);
37         writefln("%s", ex);
38         if(ex.thrownValue.type != ScriptAny.Type.UNDEFINED)
39             writefln("Value thrown: %s", ex.thrownValue);
40     }
41 }
42 
43 /**
44  * Main function for the REPL or interpreter. If no command line arguments are specified, it enters
45  * interactive REPL mode, otherwise it attempts to execute the first argument as a script file.
46  */
47 int main(string[] args)
48 {
49     auto terminal = Terminal(ConsoleOutputType.linear);
50     auto interpreter = new Interpreter();
51     interpreter.initializeStdlib();
52 
53     if(args.length > 1)
54     {
55         immutable fileName = args[1];
56         auto code = readText(fileName);
57         evaluateWithErrorChecking(interpreter, code, fileName);
58     }    
59     else
60     {
61         while(true)
62         {
63             try 
64             {
65                 string input = strip(terminal.getline("mildew> "));
66                 if(input == "#exit" || input == "")
67                     break;
68                 while(input.length > 0 && input[$-1]=='\\')
69                 {
70                     input = input[0..$-1];
71                     input ~= "\n" ~ strip(terminal.getline(">>> "));
72                 }
73                 writeln();
74                 evaluateWithErrorChecking(interpreter, input);
75             }
76             catch(UserInterruptionException ex)
77             {
78                 break;
79             }
80         }
81         writeln("");
82     }
83     return 0;
84 }