summaryrefslogtreecommitdiff
path: root/src/sexpr/main.cpp
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-03-16 14:55:57 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-03-24 19:27:09 -0700
commitfe3d4ce758822d65a0a5d617b7b77df2dbc972d8 (patch)
treed048a7e356ba542ebc5647b1aedfce4b8257daa2 /src/sexpr/main.cpp
parentc812c92d1a1835f0bda783e709481188c8d92225 (diff)
downloadtmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.tar.gz
tmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.tar.bz2
tmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.tar.xz
tmwa-fe3d4ce758822d65a0a5d617b7b77df2dbc972d8.zip
Implement new magic frontend using sexpr
Diffstat (limited to 'src/sexpr/main.cpp')
-rw-r--r--src/sexpr/main.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/sexpr/main.cpp b/src/sexpr/main.cpp
new file mode 100644
index 0000000..7d63ddf
--- /dev/null
+++ b/src/sexpr/main.cpp
@@ -0,0 +1,130 @@
+#include <stack>
+#include <map>
+
+#include "../io/cxxstdio.hpp"
+
+#include "lexer.hpp"
+#include "parser.hpp"
+
+#include "../poison.hpp"
+
+enum Spacing
+{
+ LINES,
+ SIMPLE,
+ SPACES,
+ SPACES_1,
+ SPACES_2,
+ SPACES_3,
+ SPACES_4,
+};
+
+static
+void do_spacing(bool& first, Spacing& sp, int depth)
+{
+ if (first)
+ {
+ first = false;
+ return;
+ }
+ switch (sp)
+ {
+ case LINES:
+ PRINTF("\n%*s", (depth - 1) * 4, "");
+ return;
+ case SPACES:
+ case SIMPLE:
+ PRINTF(" ");
+ return;
+ case SPACES_1:
+ PRINTF(" ");
+ sp = LINES;
+ return;
+ case SPACES_2:
+ PRINTF(" ");
+ sp = SPACES_1;
+ return;
+ case SPACES_3:
+ PRINTF(" ");
+ sp = SPACES_2;
+ return;
+ case SPACES_4:
+ PRINTF(" ");
+ sp = SPACES_3;
+ return;
+ }
+}
+
+static
+void adjust_spacing(Spacing& sp, ZString val)
+{
+ std::map<ZString, Spacing> spaces =
+ {
+ {"BLOCK", LINES},
+ {"GUARD", LINES},
+ {"DISABLED", LINES},
+ {"PROCEDURE", SPACES_2},
+ {"SPELL", SPACES_4},
+ {"IF", SPACES_1},
+ {"set_script_variable", SPACES_2},
+ };
+ auto it = spaces.find(val);
+ if (it != spaces.end())
+ sp = it->second;
+}
+
+int main()
+{
+ if (1 == 1)
+ {
+ sexpr::Lexer lexer("/dev/stdin");
+ sexpr::SExpr sexpr;
+ while (sexpr::parse(lexer, sexpr))
+ {
+ PRINTF("");
+ }
+ if (lexer.peek() != sexpr::TOK_EOF)
+ {
+ lexer.span().error(STRPRINTF("Incomplete: %s: %s\n",
+ sexpr::token_name(lexer.peek()), lexer.val_string()));
+ }
+ return 0;
+ }
+
+ std::stack<Spacing> spacing;
+ spacing.push(LINES);
+ sexpr::Lexer lexer("/dev/stdin");
+ bool first = true;
+ while (sexpr::Lexeme tok = lexer.peek())
+ {
+ switch (tok)
+ {
+ case sexpr::TOK_OPEN:
+ if (spacing.top() == SIMPLE)
+ spacing.top() = LINES;
+ do_spacing(first, spacing.top(), spacing.size());
+ PRINTF("(");
+ spacing.push(SIMPLE);
+ first = true;
+ break;
+ case sexpr::TOK_CLOSE:
+ PRINTF(")");
+ spacing.pop();
+ first = false;
+ break;
+ case sexpr::TOK_STRING:
+ do_spacing(first, spacing.top(), spacing.size());
+ PRINTF("%s", sexpr::escape(lexer.val_string()));
+ break;
+ case sexpr::TOK_TOKEN:
+ do_spacing(first, spacing.top(), spacing.size());
+ PRINTF("%s", lexer.val_string());
+ adjust_spacing(spacing.top(), lexer.val_string());
+ break;
+ default:
+ abort();
+ }
+ lexer.adv();
+ }
+ PRINTF("\n");
+}