blob: 0bddf3d303fcf72c4794c3f4af3513bfa6b25f1d [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"
9
10// JANK! librl isn't namespaced!
11namespace ReadLine
12{
13#include <readline/readline.h>
14#include <readline/history.h>
15}
16
17
18Repl::Repl()
19{
20}
21
22char *Repl::prompt()
23{
24 static char p[] = "\033[36mREFAL >\033[0m ";
25 return p;
26}
27
28QString Repl::readLine()
29{
30 char *line = ReadLine::readline(prompt());
31
32 if (!line)
33 {
34 _running = false;
35 return "";
36 }
37
38 ReadLine::add_history(line);
39
40 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
swissChilibd2a90d2021-12-09 10:36:14 -080060 addHistory(line);
61
swissChili923bd532021-12-08 22:48:58 -080062 if (trySpecialCase(line))
63 {}
64 else if (tryEvaluate(line, &expr))
65 {
66 bool okay = true;
67 QList<Token> out;
68
69 for (const AstNode &node : expr)
70 {
71 RuntimeResult res = _eval.evaluate(node, VarContext());
72
73 if (res.success())
74 {
75 out.append(res.result());
76 }
77 else
78 {
79 qDebug() << "Failed to evaluate" << node;
80 qDebug() << res.message();
81 okay = false;
82 break;
83 }
84 }
85
86 if (okay)
87 {
swissChilibd2a90d2021-12-09 10:36:14 -080088 qDebug().noquote() << pprint(out);
swissChili923bd532021-12-08 22:48:58 -080089 }
90 }
91 else
92 {
93 qDebug() << "What?";
94 }
95 }
96}
97
98bool Repl::trySpecialCase(QString line)
99{
100 if (line.startsWith("."))
101 {
102 if (line == ".q" || line == ".quit")
103 {
104 _running = false;
105 }
106 else
107 {
108 qDebug().noquote() << "Unknown special command, try .help";
109 }
110
111 return true;
112 }
113
114 return false;
115}
116
117bool Repl::tryEvaluate(QString line, QList<AstNode> *expr)
118{
119 Parser parser(line);
120 Function func;
121
122 if (parser.parseFunctionDefinition(&func))
123 {
124 _eval.addFunction(func);
125 *expr = {};
126
127 return true;
128 }
129
swissChili847a78c2021-12-09 17:44:52 -0800130 if (!parser.parseMany(expr))
131 return false;
132
swissChili923bd532021-12-08 22:48:58 -0800133 parser.skip();
134
135 return parser.atEnd();
136}