/* Parse a long string or long comment (tv set to NULL). */ static void lex_longstring(LexState *ls, TValue *tv, int sep) { lex_savenext(ls); /* Skip second '['. */ if (lex_iseol(ls)) /* Skip initial newline. */ lex_newline(ls); for (;;) { switch (ls->c) { case LEX_EOF: lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM); break; case ']': if (lex_skipeq(ls) == sep) { lex_savenext(ls); /* Skip second ']'. */ goto endloop; } break; case '\n': case '\r': lex_save(ls, '\n'); lex_newline(ls); if (!tv) lj_buf_reset(&ls->sb); /* Don't waste space for comments. */ break; default: lex_savenext(ls); break; } } endloop: if (tv) { GCstr *str = lj_parse_keepstr(ls, sbufB(&ls->sb) + (2 + (MSize)sep), sbuflen(&ls->sb) - 2*(2 + (MSize)sep)); setstrV(ls->L, tv, str); } }
static void read_long_string(LexState *ls, TValue *tv, int sep) { save_and_next(ls); /* skip 2nd `[' */ if (currIsNewline(ls)) /* string starts with a newline? */ inclinenumber(ls); /* skip it */ for (;;) { switch (ls->current) { case END_OF_STREAM: lj_lex_error(ls, TK_eof, tv ? LJ_ERR_XLSTR : LJ_ERR_XLCOM); break; case ']': if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `]' */ goto endloop; } break; case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); if (!tv) lj_str_resetbuf(&ls->sb); /* avoid wasting space */ break; default: if (tv) save_and_next(ls); else next(ls); break; } } endloop: if (tv) { GCstr *str = lj_parse_keepstr(ls, ls->sb.buf + (2 + (MSize)sep), ls->sb.n - 2*(2 + (MSize)sep)); setstrV(ls->L, tv, str); } }
static void read_string(LexState *ls, int delim, TValue *tv) { save_and_next(ls); while (ls->current != delim) { switch (ls->current) { case END_OF_STREAM: lj_lex_error(ls, TK_eof, LJ_ERR_XSTR); continue; case '\n': case '\r': lj_lex_error(ls, TK_string, LJ_ERR_XSTR); continue; case '\\': { int c; next(ls); /* do not save the `\' */ switch (ls->current) { case 'a': c = '\a'; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue; case END_OF_STREAM: continue; /* will raise an error next loop */ default: if (!lj_ctype_isdigit(ls->current)) { save_and_next(ls); /* handles \\, \", \', and \? */ } else { /* \xxx */ int i = 0; c = 0; do { c = 10*c + (ls->current-'0'); next(ls); } while (++i<3 && lj_ctype_isdigit(ls->current)); if (c > UCHAR_MAX) lj_lex_error(ls, TK_string, LJ_ERR_XESC); save(ls, c); } continue; } save(ls, c); next(ls); continue; } default: save_and_next(ls); break; } } save_and_next(ls); /* skip delimiter */ setstrV(ls->L, tv, lj_parse_keepstr(ls, ls->sb.buf + 1, ls->sb.n - 2)); }
static int llex(LexState *ls, TValue *tv) { lj_str_resetbuf(&ls->sb); for (;;) { if (lj_char_isident(ls->current)) { GCstr *s; if (lj_char_isdigit(ls->current)) { /* Numeric literal. */ lex_number(ls, tv); return TK_number; } /* Identifier or reserved word. */ do { save_and_next(ls); } while (lj_char_isident(ls->current)); s = lj_parse_keepstr(ls, ls->sb.buf, ls->sb.n); setstrV(ls->L, tv, s); if (s->reserved > 0) /* Reserved word? */ return TK_OFS + s->reserved; return TK_name; } switch (ls->current) { case '\n': case '\r': inclinenumber(ls); continue; case ' ': case '\t': case '\v': case '\f': next(ls); continue; case '-': next(ls); if (ls->current != '-') return '-'; /* else is a comment */ next(ls); if (ls->current == '[') { int sep = skip_sep(ls); lj_str_resetbuf(&ls->sb); /* `skip_sep' may dirty the buffer */ if (sep >= 0) { read_long_string(ls, NULL, sep); /* long comment */ lj_str_resetbuf(&ls->sb); continue; } } /* else short comment */ while (!currIsNewline(ls) && ls->current != END_OF_STREAM) next(ls); continue; case '[': { int sep = skip_sep(ls); if (sep >= 0) { read_long_string(ls, tv, sep); return TK_string; } else if (sep == -1) { return '['; } else { lj_lex_error(ls, TK_string, LJ_ERR_XLDELIM); continue; } } case '=': next(ls); if (ls->current != '=') return '='; else { next(ls); return TK_eq; } case '<': next(ls); if (ls->current != '=') return '<'; else { next(ls); return TK_le; } case '>': next(ls); if (ls->current != '=') return '>'; else { next(ls); return TK_ge; } case '~': next(ls); if (ls->current != '=') return '~'; else { next(ls); return TK_ne; } case ':': next(ls); if (ls->current != ':') return ':'; else { next(ls); return TK_label; } case '"': case '\'': read_string(ls, ls->current, tv); return TK_string; case '.': save_and_next(ls); if (ls->current == '.') { next(ls); if (ls->current == '.') { next(ls); return TK_dots; /* ... */ } return TK_concat; /* .. */ } else if (!lj_char_isdigit(ls->current)) { return '.'; } else { lex_number(ls, tv); return TK_number; } case END_OF_STREAM: return TK_eof; default: { int c = ls->current; next(ls); return c; /* Single-char tokens (+ - / ...). */ } } } }
static void read_string(LexState *ls, int delim, TValue *tv) { save_and_next(ls); while (ls->current != delim) { switch (ls->current) { case END_OF_STREAM: lj_lex_error(ls, TK_eof, LJ_ERR_XSTR); continue; case '\n': case '\r': lj_lex_error(ls, TK_string, LJ_ERR_XSTR); continue; case '\\': { int c = next(ls); /* Skip the '\\'. */ switch (c) { case 'a': c = '\a'; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case 'x': /* Hexadecimal escape '\xXX'. */ c = (next(ls) & 15u) << 4; if (!lj_char_isdigit(ls->current)) { if (!lj_char_isxdigit(ls->current)) goto err_xesc; c += 9 << 4; } c += (next(ls) & 15u); if (!lj_char_isdigit(ls->current)) { if (!lj_char_isxdigit(ls->current)) goto err_xesc; c += 9; } break; case 'z': /* Skip whitespace. */ next(ls); while (lj_char_isspace(ls->current)) if (currIsNewline(ls)) inclinenumber(ls); else next(ls); continue; case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue; case '\\': case '\"': case '\'': break; case END_OF_STREAM: continue; default: if (!lj_char_isdigit(c)) goto err_xesc; c -= '0'; /* Decimal escape '\ddd'. */ if (lj_char_isdigit(next(ls))) { c = c*10 + (ls->current - '0'); if (lj_char_isdigit(next(ls))) { c = c*10 + (ls->current - '0'); if (c > 255) { err_xesc: lj_lex_error(ls, TK_string, LJ_ERR_XESC); } next(ls); } } save(ls, c); continue; } save(ls, c); next(ls); continue; } default: save_and_next(ls); break; } } save_and_next(ls); /* skip delimiter */ setstrV(ls->L, tv, lj_parse_keepstr(ls, ls->sb.buf + 1, ls->sb.n - 2)); }