swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 1 | #include <stdio.h> |
2 | #include <string.h> | ||||
3 | |||||
4 | #include <QDebug> | ||||
5 | |||||
6 | #include "Repl.h" | ||||
7 | #include "Parser.h" | ||||
8 | #include "PPrint.h" | ||||
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 9 | #include "StdLib.h" |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 10 | |
11 | // JANK! librl isn't namespaced! | ||||
12 | namespace ReadLine | ||||
13 | { | ||||
14 | #include <readline/readline.h> | ||||
15 | #include <readline/history.h> | ||||
16 | } | ||||
17 | |||||
18 | |||||
19 | Repl::Repl() | ||||
20 | { | ||||
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 21 | StdLib().load(_eval); |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 22 | } |
23 | |||||
24 | char *Repl::prompt() | ||||
25 | { | ||||
26 | static char p[] = "\033[36mREFAL >\033[0m "; | ||||
27 | return p; | ||||
28 | } | ||||
29 | |||||
30 | QString Repl::readLine() | ||||
31 | { | ||||
32 | char *line = ReadLine::readline(prompt()); | ||||
33 | |||||
34 | if (!line) | ||||
35 | { | ||||
36 | _running = false; | ||||
37 | return ""; | ||||
38 | } | ||||
39 | |||||
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 40 | QString string = QString::fromUtf8(line); |
41 | |||||
42 | free(line); | ||||
43 | |||||
44 | return string; | ||||
45 | } | ||||
46 | |||||
swissChili | bd2a90d | 2021-12-09 10:36:14 -0800 | [diff] [blame] | 47 | void Repl::addHistory(QString line) |
48 | { | ||||
49 | ReadLine::add_history(line.toUtf8()); | ||||
50 | } | ||||
51 | |||||
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 52 | void Repl::start() |
53 | { | ||||
54 | while (_running) | ||||
55 | { | ||||
swissChili | bd2a90d | 2021-12-09 10:36:14 -0800 | [diff] [blame] | 56 | QString line = readLine().trimmed(); |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 57 | |
58 | QList<AstNode> expr; | ||||
59 | |||||
swissChili | c046cdf | 2021-12-09 19:59:51 -0800 | [diff] [blame] | 60 | if (!line.isEmpty()) |
61 | addHistory(line); | ||||
62 | |||||
63 | ParseResult ret; | ||||
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 64 | Parser parser{line}; |
swissChili | bd2a90d | 2021-12-09 10:36:14 -0800 | [diff] [blame] | 65 | |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 66 | if (trySpecialCase(line)) |
67 | {} | ||||
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 68 | else if ((ret = tryEvaluate(parser, &expr))) |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 69 | { |
70 | bool okay = true; | ||||
71 | QList<Token> out; | ||||
72 | |||||
swissChili | 2506b92 | 2022-02-15 21:07:20 -0800 | [diff] [blame] | 73 | for (const AstNode &node : qAsConst(expr)) |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 74 | { |
75 | RuntimeResult res = _eval.evaluate(node, VarContext()); | ||||
76 | |||||
77 | if (res.success()) | ||||
78 | { | ||||
79 | out.append(res.result()); | ||||
80 | } | ||||
81 | else | ||||
82 | { | ||||
83 | qDebug() << "Failed to evaluate" << node; | ||||
84 | qDebug() << res.message(); | ||||
85 | okay = false; | ||||
86 | break; | ||||
87 | } | ||||
88 | } | ||||
89 | |||||
90 | if (okay) | ||||
91 | { | ||||
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 92 | sout(pprint(out)); |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 93 | } |
94 | } | ||||
swissChili | c046cdf | 2021-12-09 19:59:51 -0800 | [diff] [blame] | 95 | else if (ret.status() == ParseResult::INCOMPLETE) |
96 | { | ||||
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 97 | qDebug() << "Parse error: incomplete input:"; |
98 | sout(pprint(ret, parser)); | ||||
swissChili | 2506b92 | 2022-02-15 21:07:20 -0800 | [diff] [blame] | 99 | ReadLine::rl_insert_text("Hello there!"); |
100 | ReadLine::rl_redisplay(); | ||||
swissChili | c046cdf | 2021-12-09 19:59:51 -0800 | [diff] [blame] | 101 | } |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 102 | else |
103 | { | ||||
swissChili | 2506b92 | 2022-02-15 21:07:20 -0800 | [diff] [blame] | 104 | qDebug() << "Parse error:" << ret.message(); |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 105 | } |
106 | } | ||||
107 | } | ||||
108 | |||||
swissChili | c046cdf | 2021-12-09 19:59:51 -0800 | [diff] [blame] | 109 | ParseResult Repl::trySpecialCase(QString line) |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 110 | { |
111 | if (line.startsWith(".")) | ||||
112 | { | ||||
113 | if (line == ".q" || line == ".quit") | ||||
114 | { | ||||
115 | _running = false; | ||||
116 | } | ||||
117 | else | ||||
118 | { | ||||
119 | qDebug().noquote() << "Unknown special command, try .help"; | ||||
120 | } | ||||
121 | |||||
122 | return true; | ||||
123 | } | ||||
124 | |||||
125 | return false; | ||||
126 | } | ||||
127 | |||||
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 128 | ParseResult Repl::tryEvaluate(Parser &parser, QList<AstNode> *expr) |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 129 | { |
swissChili | 323883d | 2022-02-20 16:35:23 -0800 | [diff] [blame] | 130 | Function func; |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 131 | |
swissChili | c046cdf | 2021-12-09 19:59:51 -0800 | [diff] [blame] | 132 | ParseResult ret; |
133 | |||||
swissChili | 2506b92 | 2022-02-15 21:07:20 -0800 | [diff] [blame] | 134 | if ((ret = parser.parseFunctionDefinition(&func))) |
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 135 | { |
136 | _eval.addFunction(func); | ||||
137 | *expr = {}; | ||||
138 | |||||
139 | return true; | ||||
140 | } | ||||
swissChili | c046cdf | 2021-12-09 19:59:51 -0800 | [diff] [blame] | 141 | else if (ret.status() == ParseResult::INCOMPLETE) |
142 | { | ||||
143 | return ret; | ||||
144 | } | ||||
145 | else | ||||
146 | { | ||||
147 | return parser.parseMany(expr); | ||||
148 | } | ||||
swissChili | 923bd53 | 2021-12-08 22:48:58 -0800 | [diff] [blame] | 149 | } |