diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-03-16 14:55:57 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-03-24 19:27:09 -0700 |
commit | fe3d4ce758822d65a0a5d617b7b77df2dbc972d8 (patch) | |
tree | d048a7e356ba542ebc5647b1aedfce4b8257daa2 /src/sexpr/main.cpp | |
parent | c812c92d1a1835f0bda783e709481188c8d92225 (diff) | |
download | tmwa-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.cpp | 130 |
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"); +} |