blob: cef5ed7c717bdc8e4a79e84177a357e29bdf1006 [file] [log] [blame]
swissChili923bd532021-12-08 22:48:58 -08001#include <stdio.h>
2#include <string.h>
3
4#include <QDebug>
5
6#include "Repl.h"
7#include "Parser.h"
8#include "PPrint.h"
swissChili323883d2022-02-20 16:35:23 -08009#include "StdLib.h"
swissChili923bd532021-12-08 22:48:58 -080010
11// JANK! librl isn't namespaced!
12namespace ReadLine
13{
14#include <readline/readline.h>
15#include <readline/history.h>
16}
17
18
19Repl::Repl()
20{
swissChili323883d2022-02-20 16:35:23 -080021 StdLib().load(_eval);
swissChili923bd532021-12-08 22:48:58 -080022}
23
24char *Repl::prompt()
25{
26 static char p[] = "\033[36mREFAL >\033[0m ";
27 return p;
28}
29
30QString Repl::readLine()
31{
32 char *line = ReadLine::readline(prompt());
33
34 if (!line)
35 {
36 _running = false;
37 return "";
38 }
39
swissChili923bd532021-12-08 22:48:58 -080040 QString string = QString::fromUtf8(line);
41
42 free(line);
43
44 return string;
45}
46
swissChilibd2a90d2021-12-09 10:36:14 -080047void Repl::addHistory(QString line)
48{
49 ReadLine::add_history(line.toUtf8());
50}
51
swissChili923bd532021-12-08 22:48:58 -080052void Repl::start()
53{
54 while (_running)
55 {
swissChilibd2a90d2021-12-09 10:36:14 -080056 QString line = readLine().trimmed();
swissChili923bd532021-12-08 22:48:58 -080057
58 QList<AstNode> expr;
59
swissChilic046cdf2021-12-09 19:59:51 -080060 if (!line.isEmpty())
61 addHistory(line);
62
63 ParseResult ret;
swissChili323883d2022-02-20 16:35:23 -080064 Parser parser{line};
swissChilibd2a90d2021-12-09 10:36:14 -080065
swissChili923bd532021-12-08 22:48:58 -080066 if (trySpecialCase(line))
67 {}
swissChili323883d2022-02-20 16:35:23 -080068 else if ((ret = tryEvaluate(parser, &expr)))
swissChili923bd532021-12-08 22:48:58 -080069 {
70 bool okay = true;
71 QList<Token> out;
72
swissChili2506b922022-02-15 21:07:20 -080073 for (const AstNode &node : qAsConst(expr))
swissChili923bd532021-12-08 22:48:58 -080074 {
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 {
swissChili323883d2022-02-20 16:35:23 -080092 sout(pprint(out));
swissChili923bd532021-12-08 22:48:58 -080093 }
94 }
swissChilic046cdf2021-12-09 19:59:51 -080095 else if (ret.status() == ParseResult::INCOMPLETE)
96 {
swissChili323883d2022-02-20 16:35:23 -080097 qDebug() << "Parse error: incomplete input:";
98 sout(pprint(ret, parser));
swissChili2506b922022-02-15 21:07:20 -080099 ReadLine::rl_insert_text("Hello there!");
100 ReadLine::rl_redisplay();
swissChilic046cdf2021-12-09 19:59:51 -0800101 }
swissChili923bd532021-12-08 22:48:58 -0800102 else
103 {
swissChili2506b922022-02-15 21:07:20 -0800104 qDebug() << "Parse error:" << ret.message();
swissChili923bd532021-12-08 22:48:58 -0800105 }
106 }
107}
108
swissChilic046cdf2021-12-09 19:59:51 -0800109ParseResult Repl::trySpecialCase(QString line)
swissChili923bd532021-12-08 22:48:58 -0800110{
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
swissChili323883d2022-02-20 16:35:23 -0800128ParseResult Repl::tryEvaluate(Parser &parser, QList<AstNode> *expr)
swissChili923bd532021-12-08 22:48:58 -0800129{
swissChili323883d2022-02-20 16:35:23 -0800130 Function func;
swissChili923bd532021-12-08 22:48:58 -0800131
swissChilic046cdf2021-12-09 19:59:51 -0800132 ParseResult ret;
133
swissChili2506b922022-02-15 21:07:20 -0800134 if ((ret = parser.parseFunctionDefinition(&func)))
swissChili923bd532021-12-08 22:48:58 -0800135 {
136 _eval.addFunction(func);
137 *expr = {};
138
139 return true;
140 }
swissChilic046cdf2021-12-09 19:59:51 -0800141 else if (ret.status() == ParseResult::INCOMPLETE)
142 {
143 return ret;
144 }
145 else
146 {
147 return parser.parseMany(expr);
148 }
swissChili923bd532021-12-08 22:48:58 -0800149}