From 73f770552cacf81ddd3665be8cfeb1ebe87c29e5 Mon Sep 17 00:00:00 2001 From: q66 Date: Thu, 22 Sep 2016 00:20:23 +0200 Subject: [PATCH] clean up parser a bit --- src/cs_gen.cc | 141 +++++++++++++++++++++++--------------------------- src/cs_vm.hh | 11 +++- 2 files changed, 75 insertions(+), 77 deletions(-) diff --git a/src/cs_gen.cc b/src/cs_gen.cc index e31df13..fa0451e 100644 --- a/src/cs_gen.cc +++ b/src/cs_gen.cc @@ -8,50 +8,11 @@ namespace cscript { -static ostd::ConstCharRange cs_debug_line( - ostd::ConstCharRange p, ostd::ConstCharRange srcf, ostd::ConstCharRange srcs, - ostd::ConstCharRange fmt, ostd::CharRange buf -) { - if (srcs.empty()) { - return fmt; - } - ostd::Size num = 1; - ostd::ConstCharRange line(srcs); - for (;;) { - ostd::ConstCharRange end = ostd::find(line, '\n'); - if (!end.empty()) { - line = ostd::slice_until(line, end); - } - if (&p[0] >= &line[0] && &p[0] <= &line[line.size()]) { - ostd::CharRange r(buf); - if (!srcf.empty()) { - ostd::format(r, "%s:%d: %s", srcf, num, fmt); - } else { - ostd::format(r, "%d: %s", num, fmt); - } - r.put('\0'); - return buf.data(); /* trigger strlen */ - } - if (end.empty()) { - break; - } - line = end; - line.pop_front(); - ++num; - } - return fmt; -} - template static void cs_error_line( - GenState &gs, ostd::ConstCharRange p, ostd::ConstCharRange fmt, A &&...args + GenState &gs, ostd::ConstCharRange fmt, A &&...args ) { - ostd::Array buf; - auto rfmt = cs_debug_line( - p, gs.src_file, gs.src_str, fmt, - ostd::CharRange(buf.data(), buf.size()) - ); - throw CsErrorException(gs.cs, rfmt, ostd::forward(args)...); + throw CsErrorException(gs.cs, fmt, ostd::forward(args)...); } static ostd::ConstCharRange cs_parse_str(ostd::ConstCharRange str) { @@ -94,7 +55,7 @@ ostd::ConstCharRange GenState::get_str() { done: auto ret = ostd::ConstCharRange(beg, source); if (current() != '\"') { - cs_error_line(*this, ln, "unfinished string '%s'", ln); + cs_error_line(*this, "unfinished string '%s'", ln); } next_char(); return ret; @@ -111,13 +72,51 @@ CsString GenState::get_str_dup(bool unescape) { return ostd::move(app.get()); } -static inline void skipcomments(char const *&p) { +ostd::ConstCharRange GenState::read_macro_name() { + char const *op = source; + char c = current(); + if (!isalpha(c) && (c != '_')) { + return nullptr; + } + for (; isalnum(c) || (c == '_'); c = current()) { + next_char(); + } + return ostd::ConstCharRange(op, source); +} + +char GenState::skip_until(ostd::ConstCharRange chars) { + char c = current(); + while (c && ostd::find(chars, c).empty()) { + next_char(); + c = current(); + } + return c; +} + +char GenState::skip_until(char cf) { + char c = current(); + while (c && (c != cf)) { + next_char(); + c = current(); + } + return c; +} + +static bool cs_is_hspace(char c) { + return (c == ' ') || (c == '\t') || (c == '\r'); +} + +void GenState::skip_comments() { for (;;) { - p += strspn(p, " \t\r"); - if (p[0] != '/' || p[1] != '/') { - break; + for (char c = current(); cs_is_hspace(c); c = current()) { + next_char(); + } + if ((current() != '/') || (current(1) != '/')) { + return; + } + while (current() != '\n') { + next_char(); } - p += strcspn(p, "\n\0"); } } @@ -596,7 +595,6 @@ done: static bool compileblocksub(GenState &gs, int prevargs) { CsString lookup; - char const *op; switch (gs.current()) { case '(': if (!compilearg(gs, CsValCany, prevargs)) { @@ -613,11 +611,7 @@ static bool compileblocksub(GenState &gs, int prevargs) { lookup = gs.get_str_dup(); goto lookupid; default: { - op = gs.source; - while (isalnum(gs.current()) || gs.current() == '_') { - gs.next_char(); - } - lookup = ostd::ConstCharRange(op, gs.source - op); + lookup = gs.read_macro_name(); if (lookup.empty()) { return false; } @@ -656,14 +650,12 @@ done: } static void compileblockmain(GenState &gs, int wordtype, int prevargs) { - char const *line = gs.source, *start = gs.source; + char const *start = gs.source; int concs = 0; for (int brak = 1; brak;) { - gs.source += strcspn(gs.source, "@\"/[]\0"); - char c = gs.current(); - switch (c) { + switch (gs.skip_until("@\"/[]")) { case '\0': - cs_error_line(gs, line, "missing \"]\""); + cs_error_line(gs, "missing \"]\""); return; case '\"': gs.get_str(); @@ -671,7 +663,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) { case '/': gs.next_char(); if (gs.current() == '/') { - gs.source += strcspn(gs.source, "\n\0"); + gs.skip_until('\n'); } break; case '[': @@ -692,7 +684,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) { if (brak > level) { continue; } else if (brak < level) { - cs_error_line(gs, line, "too many @s"); + cs_error_line(gs, "too many @s"); return; } if (!concs && prevargs >= MaxResults) { @@ -817,7 +809,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) { static bool compilearg( GenState &gs, int wordtype, int prevargs, CsString *word ) { - skipcomments(gs.source); + gs.skip_comments(); switch (gs.current()) { case '\"': switch (wordtype) { @@ -1309,16 +1301,15 @@ static void compile_and_or( } static void compilestatements(GenState &gs, int rettype, int brak, int prevargs) { - char const *line = gs.source; CsString idname; for (;;) { - skipcomments(gs.source); + gs.skip_comments(); idname.clear(); bool more = compilearg(gs, CsValWord, prevargs, &idname); if (!more) { goto endstatement; } - skipcomments(gs.source); + gs.skip_comments(); if (gs.current() == '=') { switch (gs.source[1]) { case '/': @@ -1525,30 +1516,30 @@ endstatement: if (more) { while (compilearg(gs, CsValPop)); } - gs.source += strcspn(gs.source, ")];/\n\0"); - char c = gs.next_char(); - switch (c) { + switch (gs.skip_until(")];/\n")) { case '\0': - if (c != brak) { - cs_error_line( - gs, line, "missing \"%c\"", char(brak) - ); + if (gs.current() != brak) { + cs_error_line(gs, "missing \"%c\"", char(brak)); return; } - gs.source--; return; case ')': case ']': - if (c == brak) { + if (gs.current() == brak) { + gs.next_char(); return; } - cs_error_line(gs, line, "unexpected \"%c\"", c); + cs_error_line(gs, "unexpected \"%c\"", gs.current()); return; case '/': + gs.next_char(); if (gs.current() == '/') { - gs.source += strcspn(gs.source, "\n\0"); + gs.skip_until('\n'); } goto endstatement; + default: + gs.next_char(); + break; } } } diff --git a/src/cs_vm.hh b/src/cs_vm.hh index ec41a44..e2d744e 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -218,9 +218,16 @@ struct GenState { return *source++; } - char current() { - return *source; + char current(int ahead = 0) { + return source[ahead]; } + + ostd::ConstCharRange read_macro_name(); + + char skip_until(ostd::ConstCharRange chars); + char skip_until(char cf); + + void skip_comments(); }; CsString intstr(CsInt v);