Fix parser, matcher
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 472fecc..8274f8f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,7 @@
Core
REQUIRED)
-add_executable(REFAL main.cpp Token.cpp Token.h Matcher.cpp Matcher.h VarContext.cpp VarContext.h Parser.cpp Parser.h AstNode.cpp AstNode.h)
+add_executable(REFAL main.cpp Token.cpp Token.h Matcher.cpp Matcher.h VarContext.cpp VarContext.h Parser.cpp Parser.h AstNode.cpp AstNode.h Evaluator.cpp Evaluator.h)
target_link_libraries(REFAL
Qt::Core
)
diff --git a/Evaluator.cpp b/Evaluator.cpp
new file mode 100644
index 0000000..70ed91b
--- /dev/null
+++ b/Evaluator.cpp
@@ -0,0 +1,2 @@
+#include "Evaluator.h"
+
diff --git a/Evaluator.h b/Evaluator.h
new file mode 100644
index 0000000..3eaef52
--- /dev/null
+++ b/Evaluator.h
@@ -0,0 +1,5 @@
+#pragma once
+
+class Evaluator {
+public:
+};
diff --git a/Matcher.cpp b/Matcher.cpp
index 427bd76..42fd155 100644
--- a/Matcher.cpp
+++ b/Matcher.cpp
@@ -9,6 +9,11 @@
return MatchResult{true, context};
}
+ if (pattern.empty() && !data.empty())
+ {
+ return MatchResult{false, context};
+ }
+
Token ph = pattern.first();
Token dataHead = data.first();
pattern.removeFirst();
diff --git a/Parser.cpp b/Parser.cpp
index 2d6b992..9233fbd 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -31,20 +31,22 @@
get();
}
-bool Parser::parseSymbol(AstNode *node)
+template <typename T>
+bool Parser::parseSymbol(T *node)
{
skip();
if (peek().isLetter())
{
- *node = AstNode(get());
+ *node = T(get());
return true;
}
return false;
}
-bool Parser::parseIdentifier(AstNode *node)
+template <typename T>
+bool Parser::parseIdentifier(T *node)
{
skip();
@@ -57,14 +59,15 @@
buffer += get();
}
- *node = AstNode(buffer);
+ *node = T(buffer);
return true;
}
return false;
}
-bool Parser::parseNumber(AstNode *node)
+template <typename T>
+bool Parser::parseNumber(T *node)
{
skip();
@@ -75,14 +78,15 @@
while (peek().isDigit())
buffer += get();
- *node = AstNode(buffer.toInt());
+ *node = T(buffer.toInt());
return true;
}
return false;
}
-bool Parser::parseVariable(AstNode *node)
+template <typename T>
+bool Parser::parseVariable(T *node)
{
skip();
@@ -96,11 +100,16 @@
{
get();
- AstNode identNode;
+ T nameNode;
- if (parseIdentifier(&identNode))
+ if (parseIdentifier(&nameNode))
{
- *node = AstNode(type, identNode.name());
+ *node = T(type, nameNode.name());
+ return true;
+ }
+ else if (parseSymbol(&nameNode))
+ {
+ *node = T(type, QString(nameNode.symbol()));
return true;
}
}
@@ -110,20 +119,11 @@
return false;
}
-bool Parser::parseOne(AstNode *node)
+template <typename T>
+QList<T> Parser::parseMany()
{
- return parseFunction(node) ||
- parseVariable(node) ||
- parseNumber(node) ||
- parseIdentifier(node) ||
- parseSymbol(node) ||
- parseParens(node);
-}
-
-QList<AstNode> Parser::parseMany()
-{
- QList<AstNode> nodes;
- AstNode next;
+ QList<T > nodes;
+ T next;
while (parseOne(&next))
{
@@ -133,7 +133,8 @@
return nodes;
}
-bool Parser::parseParens(AstNode *node)
+template <typename T>
+bool Parser::parseParens(T *node)
{
skip();
@@ -144,8 +145,8 @@
get();
- QList<AstNode> many = parseMany();
- *node = AstNode(many);
+ QList<T> many = parseMany<T>();
+ *node = T(many);
skip();
if (peek() != ')')
@@ -177,7 +178,7 @@
return false;
}
- QList<AstNode> body = parseMany();
+ QList<AstNode> body = parseMany<AstNode>();
*node = AstNode(head.name(), body);
skip();
@@ -191,3 +192,24 @@
return true;
}
+
+template <>
+bool Parser::parseOne<Token>(Token *node)
+{
+ return parseVariable(node) ||
+ parseNumber(node) ||
+ parseIdentifier(node) ||
+ parseSymbol(node) ||
+ parseParens(node);
+}
+
+template <>
+bool Parser::parseOne<AstNode>(AstNode *node)
+{
+ return parseFunction(node) ||
+ parseVariable(node) ||
+ parseNumber(node) ||
+ parseIdentifier(node) ||
+ parseSymbol(node) ||
+ parseParens(node);
+}
diff --git a/Parser.h b/Parser.h
index 52cafac..fb56701 100644
--- a/Parser.h
+++ b/Parser.h
@@ -2,6 +2,7 @@
#include <QString>
+#include "Token.h"
#include "AstNode.h"
class Parser
@@ -15,16 +16,36 @@
void skip();
- bool parseSymbol(AstNode *node);
- bool parseIdentifier(AstNode *node);
- bool parseNumber(AstNode *node);
- bool parseVariable(AstNode *node);
- bool parseParens(AstNode *node);
+ template <typename T>
+ bool parseSymbol(T *node);
+
+ template <typename T>
+ bool parseIdentifier(T *node);
+
+ template <typename T>
+ bool parseNumber(T *node);
+
+ template <typename T>
+ bool parseVariable(T *node);
+
+ template <typename T>
+ bool parseParens(T *node);
+
bool parseFunction(AstNode *node);
- QList<AstNode> parseMany();
- bool parseOne(AstNode *node);
+
+ template <typename T>
+ QList<T> parseMany();
+
+ template <typename T>
+ bool parseOne(T *node);
private:
int _pos = 0;
QString _input;
};
+
+template <>
+bool Parser::parseOne<Token>(Token *node);
+
+template <>
+bool Parser::parseOne<AstNode>(AstNode *node);
diff --git a/Token.h b/Token.h
index 76020ef..dfa0223 100644
--- a/Token.h
+++ b/Token.h
@@ -27,6 +27,7 @@
char varType() const;
const QString &name() const;
+ QChar symbol() const;
operator QString() const;
@@ -196,3 +197,9 @@
static const QString typeNames[] = {"SYMBOL", "IDENT", "PAREN", "VAR"};
return typeNames[type];
}
+
+template <typename T>
+QChar TokenBase<T>::symbol() const
+{
+ return _charVal;
+}
diff --git a/main.cpp b/main.cpp
index fc9d547..8ef1fb4 100644
--- a/main.cpp
+++ b/main.cpp
@@ -25,11 +25,19 @@
}
}
-void testParse(QString string)
+void testMatch(QString data, QString pattern, bool shouldBe = true)
+{
+ Parser dataParser(data),
+ patternParser(pattern);
+
+ testMatch(pattern + " = " + data, shouldBe, match(dataParser.parseMany<Token>(), patternParser.parseMany<Token>(), VarContext()));
+}
+
+void testParseAst(QString string)
{
Parser parser{string};
- QList<AstNode> result = parser.parseMany();
+ QList<AstNode> result = parser.parseMany<AstNode>();
qDebug() << "\033[36mParse\033[0m" << string << result;
}
@@ -84,22 +92,23 @@
testMatch("(s.a) e.Middle s.a = (y)f MiddleStuff y", true,
match(parenTest1, parenthesized, VarContext()));
+ // testMatch("(y)f Middle-stuff y", "(s.a) e.Middle s.a");
- testMatch("(a) = (a)", true,
- match({Token({Token('a')})}, {Token({Token('a')})}, VarContext()));
+ testMatch("(a)", "(a)");
}
void testAllParses()
{
- testParse("all symbols");
- testParse("Identifier symbols Identifier");
- testParse("s.A");
- testParse("(s.A) Variable-quoted");
- testParse("<Func-name a b (c)>");
- testParse("<Prout hi>");
- testParse("(Prout hi)");
- testParse("(<Prout hi>)");
- testParse("<If T Then (<Prout hi>) Else (<Prout sorry>)>");
+ testParseAst("all symbols");
+ testParseAst("Identifier symbols Identifier");
+ testParseAst("s.A");
+ testParseAst("(s.A) Variable-quoted");
+ testParseAst("<Func-name a b (c)>");
+ testParseAst("<Prout hi>");
+ testParseAst("(Prout hi)");
+ testParseAst("(<Prout hi>)");
+ testParseAst("<If T Then (<Prout hi>) Else (<Prout sorry>)>");
+ testParseAst("(s.a) e.Middle s.a");
}
int main(int argc, char *argv[])
diff --git a/notes.txt b/notes.txt
index d101e9c..f9d7a80 100644
--- a/notes.txt
+++ b/notes.txt
@@ -6,3 +6,12 @@
When parsing e.* variables check the min length of the remaining tokens. If
we have `e.1 s.2' for instance, we can tell right away how long `e.1' wil
have to be.
+
+
+EVALUATION
+
+ There are several parts to evaluation:
+
+ - Pattern matching and delegation (which sentence of a function do we choose to evaluate)
+ - Expression evaluation (how do we expand an AstNode stream into a Token stream)
+
\ No newline at end of file