aboutsummaryrefslogtreecommitdiffstats
path: root/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parser.cpp')
-rw-r--r--parser.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/parser.cpp b/parser.cpp
new file mode 100644
index 0000000..f80721a
--- /dev/null
+++ b/parser.cpp
@@ -0,0 +1,92 @@
+#include "parser.hpp"
+
+#include <cctype>
+#include <iostream>
+
+std::string name;
+
+static bool isname(char ch) {
+ return !isspace(ch) && ch != ')';
+}
+
+static std::string_view extractName(std::string_view sv)
+{
+ name.clear();
+
+ while (!sv.empty()) {
+ const auto ch = sv.front();
+
+ if (isname(ch)) {
+ name += ch;
+ sv.remove_prefix(1);
+ } else {
+ break;
+ }
+ }
+
+ return sv;
+}
+
+std::pair<std::string_view, Token> nextToken(std::string_view sv)
+{
+ if (sv.empty())
+ return {sv, Token::none};
+
+ while (std::isspace(sv.front()))
+ sv.remove_prefix(1);
+
+ if (sv.empty())
+ return {sv, Token::none};
+
+ const auto ch = sv.front();
+ if (ch == ';') {
+ return {{}, Token::none};
+ } else if (ch == '(') {
+ return {sv.substr(1), Token::ThunkOpen};
+ } else if (ch == ')') {
+ return {sv.substr(1), Token::ThunkClose};
+ } else if (ch == '\'') {
+ return {extractName(sv.substr(1)), Token::Quote};
+ } else if (ch == '$') {
+ return {extractName(sv.substr(1)), Token::PopVar};
+ } else if (ch == '^') {
+ return {extractName(sv.substr(1)), Token::PushVar};
+ } else if (isdigit(ch) || (ch == '-' && sv.size() > 1 && isdigit(sv[1]))) {
+ return {extractName(sv), Token::Number};
+ } else if (isname(ch)) {
+ return {extractName(sv), Token::Var};
+ }
+
+ return {sv, Token::none};
+}
+
+void printToken(Token tok)
+{
+ switch (tok) {
+ case Token::ThunkOpen:
+ std::cout << "ThunkOpen ";
+ break;
+ case Token::ThunkClose:
+ std::cout << "ThunkClose ";
+ break;
+ case Token::Quote:
+ std::cout << "Quote ";
+ break;
+ case Token::PopVar:
+ std::cout << "PopVar ";
+ break;
+ case Token::PushVar:
+ std::cout << "PushVar ";
+ break;
+ case Token::Var:
+ std::cout << "Var ";
+ break;
+ case Token::Number:
+ std::cout << "Number ";
+ break;
+ case Token::none:
+ //std::cout << "none ";
+ break;
+ }
+}
+