blob: 415602f08ac87a1df2bcb747df9d6355e2786926 [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
47void Repl::start()
48{
49 while (_running)
50 {
51 QString line = readLine();
52
53 line = line.trimmed();
54
55 QList<AstNode> expr;
56
57 if (trySpecialCase(line))
58 {}
59 else if (tryEvaluate(line, &expr))
60 {
61 bool okay = true;
62 QList<Token> out;
63
64 for (const AstNode &node : expr)
65 {
66 RuntimeResult res = _eval.evaluate(node, VarContext());
67
68 if (res.success())
69 {
70 out.append(res.result());
71 }
72 else
73 {
74 qDebug() << "Failed to evaluate" << node;
75 qDebug() << res.message();
76 okay = false;
77 break;
78 }
79 }
80
81 if (okay)
82 {
83 qDebug() << pprint(out);
84 }
85 }
86 else
87 {
88 qDebug() << "What?";
89 }
90 }
91}
92
93bool Repl::trySpecialCase(QString line)
94{
95 if (line.startsWith("."))
96 {
97 if (line == ".q" || line == ".quit")
98 {
99 _running = false;
100 }
101 else
102 {
103 qDebug().noquote() << "Unknown special command, try .help";
104 }
105
106 return true;
107 }
108
109 return false;
110}
111
112bool Repl::tryEvaluate(QString line, QList<AstNode> *expr)
113{
114 Parser parser(line);
115 Function func;
116
117 if (parser.parseFunctionDefinition(&func))
118 {
119 _eval.addFunction(func);
120 *expr = {};
121
122 return true;
123 }
124
125 *expr = parser.parseMany<AstNode>();
126 parser.skip();
127
128 return parser.atEnd();
129}