diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..76f1264 --- /dev/null +++ b/.hgignore @@ -0,0 +1,3 @@ +syntax:glob +mojobasic_version.h +cmake-build diff --git a/LICENSE.txt b/LICENSE.txt index a2aa472..08c3cef 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1 +1,71 @@ -You have no license to use this code at this time. \ No newline at end of file + + Copyright (c) 2015-2017 Ryan C. Gordon. + + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from + the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software in a + product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + + Ryan C. Gordon + + + +Internally, MojoBASIC uses LLVM, which has the following license: + +============================================================================== +LLVM Release License +============================================================================== +University of Illinois/NCSA +Open Source License + +Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign. +All rights reserved. + +Developed by: + + LLVM Team + + University of Illinois at Urbana-Champaign + + http://llvm.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + diff --git a/mojobasic_lexer.cpp b/mojobasic_lexer.cpp new file mode 100644 index 0000000..6116703 --- /dev/null +++ b/mojobasic_lexer.cpp @@ -0,0 +1,738 @@ +/* Generated by re2c 0.13.5 */ +/** + * MojoBASIC; a modern reimplementation of QuickBASIC. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +// This started as a copy/paste from MojoShader, which was written by Ryan and +// is also under the zlib license. https://icculus.org/mojoshader/ + +// This was originally based on examples/pp-c.re from re2c: http://re2c.org/ +// re2c is public domain code. +// +// You build mojobasic_lexer.cpp from the .re file with re2c... +// re2c -is -o mojobasic_lexer.cpp mojobasic_lexer.re +// +// Changes to the lexer are done to the .re file, not the C++ code! + +#define __MOJOBASIC_INTERNAL__ 1 +#include "mojobasic_internal.h" + +typedef unsigned char uchar; + +#define YYMAXFILL 5 +#define RET(t) return update_state(s, eoi, cursor, token, (Token) t) +#define YYCTYPE uchar +#define YYCURSOR cursor +#define YYLIMIT limit +#define YYMARKER s->lexer_marker +#define YYFILL(n) { if ((n) == 1) { cursor = sentinel; limit = cursor + YYMAXFILL; eoi = 1; } } + +static uchar sentinel[YYMAXFILL]; + +static Token update_state(IncludeState *s, int eoi, const uchar *cur, + const uchar *tok, const Token val) +{ + if (eoi) + { + s->bytes_left = 0; + s->source = (const char *) s->source_base + s->orig_length; + if ( (tok >= sentinel) && (tok < (sentinel+YYMAXFILL)) ) + s->token = s->source; + else + s->token = (const char *) tok; + } // if + else + { + s->bytes_left -= (unsigned int) (cur - ((const uchar *) s->source)); + s->source = (const char *) cur; + s->token = (const char *) tok; + } // else + s->tokenlen = (unsigned int) (s->source - s->token); + s->tokenval = val; + return val; +} // update_state + +Token preprocessor_lexer(IncludeState *s) +{ + const uchar *cursor = (const uchar *) s->source; + const uchar *token = cursor; + const uchar *matchptr; + const uchar *limit = cursor + s->bytes_left; + int eoi = 0; + + + +scanner_loop: + if (YYLIMIT == YYCURSOR) YYFILL(1); + token = cursor; + + +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + + if ((YYLIMIT - YYCURSOR) < 5) YYFILL(5); + yych = *YYCURSOR; + if (yych <= '-') { + if (yych <= '"') { + if (yych <= '\f') { + if (yych <= 0x08) { + if (yych <= 0x00) goto yy46; + goto yy53; + } else { + if (yych == '\n') goto yy50; + goto yy48; + } + } else { + if (yych <= 0x1F) { + if (yych <= '\r') goto yy52; + goto yy53; + } else { + if (yych <= ' ') goto yy48; + if (yych <= '!') goto yy53; + goto yy13; + } + } + } else { + if (yych <= '(') { + if (yych <= '%') { + if (yych <= '#') goto yy44; + goto yy53; + } else { + if (yych <= '&') goto yy7; + if (yych >= '(') goto yy18; + } + } else { + if (yych <= '*') { + if (yych <= ')') goto yy20; + goto yy28; + } else { + if (yych <= '+') goto yy26; + if (yych <= ',') goto yy22; + goto yy24; + } + } + } + } else { + if (yych <= '@') { + if (yych <= ';') { + if (yych <= '/') { + if (yych <= '.') goto yy11; + goto yy30; + } else { + if (yych <= '9') goto yy9; + if (yych <= ':') goto yy36; + goto yy40; + } + } else { + if (yych <= '=') { + if (yych <= '<') goto yy14; + goto yy38; + } else { + if (yych <= '>') goto yy16; + if (yych <= '?') goto yy42; + goto yy53; + } + } + } else { + if (yych <= '\\') { + if (yych <= 'R') { + if (yych <= 'Q') goto yy6; + goto yy4; + } else { + if (yych <= 'Z') goto yy6; + if (yych <= '[') goto yy53; + goto yy32; + } + } else { + if (yych <= '_') { + if (yych <= ']') goto yy53; + if (yych <= '^') goto yy34; + goto yy6; + } else { + if (yych <= '`') goto yy53; + if (yych <= 'z') goto yy6; + goto yy53; + } + } + } + } + ++YYCURSOR; + { goto singlelinecomment; } +yy4: + ++YYCURSOR; + if ((yych = *YYCURSOR) == 'E') goto yy101; + goto yy99; +yy5: + { RET(TOKEN_IDENTIFIER); } +yy6: + yych = *++YYCURSOR; + goto yy99; +yy7: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'H') goto yy93; + if (yych == 'O') goto yy92; +yy8: + { goto bad_chars; } +yy9: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy77; +yy10: + { RET(TOKEN_INT_LITERAL); } +yy11: + ++YYCURSOR; + if ((yych = *YYCURSOR) <= '/') goto yy12; + if (yych <= '9') goto yy68; +yy12: + { RET(TOKEN_DOT); } +yy13: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '\n') goto yy8; + if (yych == '\r') goto yy8; + goto yy64; +yy14: + ++YYCURSOR; + if ((yych = *YYCURSOR) <= '<') goto yy15; + if (yych <= '=') goto yy61; + if (yych <= '>') goto yy59; +yy15: + { RET(TOKEN_LESSTHAN); } +yy16: + ++YYCURSOR; + if ((yych = *YYCURSOR) == '=') goto yy57; + { RET(TOKEN_GREATERTHAN); } +yy18: + ++YYCURSOR; + { RET(TOKEN_LPAREN); } +yy20: + ++YYCURSOR; + { RET(TOKEN_RPAREN); } +yy22: + ++YYCURSOR; + { RET(TOKEN_COMMA); } +yy24: + ++YYCURSOR; + { RET(TOKEN_MINUS); } +yy26: + ++YYCURSOR; + { RET(TOKEN_PLUS); } +yy28: + ++YYCURSOR; + { RET(TOKEN_STAR); } +yy30: + ++YYCURSOR; + { RET(TOKEN_SLASH); } +yy32: + ++YYCURSOR; + { RET(TOKEN_BACKSLASH); } +yy34: + ++YYCURSOR; + { RET(TOKEN_EXPONENT); } +yy36: + ++YYCURSOR; + { RET(TOKEN_COLON); } +yy38: + ++YYCURSOR; + { RET(TOKEN_ASSIGN); } +yy40: + ++YYCURSOR; + { RET(TOKEN_SEMICOLON); } +yy42: + ++YYCURSOR; + { RET(TOKEN_QUESTION); } +yy44: + ++YYCURSOR; + { RET(TOKEN_HASH); } +yy46: + ++YYCURSOR; + { if (eoi) { RET(TOKEN_EOI); } goto bad_chars; } +yy48: + ++YYCURSOR; + yych = *YYCURSOR; + goto yy56; +yy49: + { if (s->report_whitespace) RET(TOKEN_WHITESPACE); goto scanner_loop; } +yy50: + ++YYCURSOR; +yy51: + { s->position.line++; RET(TOKEN_NEWLINE); } +yy52: + yych = *++YYCURSOR; + if (yych == '\n') goto yy54; + goto yy51; +yy53: + yych = *++YYCURSOR; + goto yy8; +yy54: + yych = *++YYCURSOR; + goto yy51; +yy55: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy56: + if (yych <= '\n') { + if (yych == '\t') goto yy55; + goto yy49; + } else { + if (yych <= '\f') goto yy55; + if (yych == ' ') goto yy55; + goto yy49; + } +yy57: + ++YYCURSOR; + { RET(TOKEN_GEQ); } +yy59: + ++YYCURSOR; + { RET(TOKEN_NEQ); } +yy61: + ++YYCURSOR; + { RET(TOKEN_LEQ); } +yy63: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy64: + if (yych <= '\f') { + if (yych != '\n') goto yy63; + } else { + if (yych <= '\r') goto yy65; + if (yych == '"') goto yy66; + goto yy63; + } +yy65: + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy8; + } else { + goto yy10; + } + } else { + goto yy70; + } +yy66: + ++YYCURSOR; + { RET(TOKEN_STRING_LITERAL); } +yy68: + yyaccept = 2; + YYMARKER = ++YYCURSOR; + if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; + if (yych <= 'D') { + if (yych <= '/') goto yy70; + if (yych <= '9') goto yy68; + } else { + if (yych <= 'E') goto yy71; + if (yych == 'e') goto yy71; + } +yy70: + { RET(TOKEN_FLOAT_LITERAL); } +yy71: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy65; + } else { + if (yych <= '-') goto yy72; + if (yych <= '/') goto yy65; + if (yych <= '9') goto yy73; + goto yy65; + } +yy72: + yych = *++YYCURSOR; + if (yych <= '/') goto yy65; + if (yych >= ':') goto yy65; +yy73: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy70; + if (yych <= '9') goto yy73; + goto yy70; +yy75: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yy84; + if (yych == 'e') goto yy84; + goto yy83; +yy76: + yyaccept = 1; + YYMARKER = ++YYCURSOR; + if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); + yych = *YYCURSOR; +yy77: + if (yych <= '9') { + if (yych == '.') goto yy75; + if (yych <= '/') goto yy10; + goto yy76; + } else { + if (yych <= 'E') { + if (yych <= 'D') goto yy10; + } else { + if (yych != 'e') goto yy10; + } + } + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy65; + } else { + if (yych <= '-') goto yy79; + if (yych <= '/') goto yy65; + if (yych <= '9') goto yy80; + goto yy65; + } +yy79: + yych = *++YYCURSOR; + if (yych <= '/') goto yy65; + if (yych >= ':') goto yy65; +yy80: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy70; + if (yych <= '9') goto yy80; + goto yy70; +yy82: + yyaccept = 2; + YYMARKER = ++YYCURSOR; + if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3); + yych = *YYCURSOR; +yy83: + if (yych <= 'D') { + if (yych <= '/') goto yy70; + if (yych <= '9') goto yy82; + goto yy70; + } else { + if (yych <= 'E') goto yy88; + if (yych == 'e') goto yy88; + goto yy70; + } +yy84: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy65; + } else { + if (yych <= '-') goto yy85; + if (yych <= '/') goto yy65; + if (yych <= '9') goto yy86; + goto yy65; + } +yy85: + yych = *++YYCURSOR; + if (yych <= '/') goto yy65; + if (yych >= ':') goto yy65; +yy86: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy70; + if (yych <= '9') goto yy86; + goto yy70; +yy88: + yych = *++YYCURSOR; + if (yych <= ',') { + if (yych != '+') goto yy65; + } else { + if (yych <= '-') goto yy89; + if (yych <= '/') goto yy65; + if (yych <= '9') goto yy90; + goto yy65; + } +yy89: + yych = *++YYCURSOR; + if (yych <= '/') goto yy65; + if (yych >= ':') goto yy65; +yy90: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy70; + if (yych <= '9') goto yy90; + goto yy70; +yy92: + yych = *++YYCURSOR; + if (yych <= '/') goto yy65; + if (yych <= '7') goto yy96; + goto yy65; +yy93: + yych = *++YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy65; + if (yych >= ':') goto yy65; + } else { + if (yych <= 'F') goto yy94; + if (yych <= '`') goto yy65; + if (yych >= 'g') goto yy65; + } +yy94: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy10; + if (yych <= '9') goto yy94; + goto yy10; + } else { + if (yych <= 'F') goto yy94; + if (yych <= '`') goto yy10; + if (yych <= 'f') goto yy94; + goto yy10; + } +yy96: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy10; + if (yych <= '7') goto yy96; + goto yy10; +yy98: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy99: + if (yych <= '?') { + if (yych <= '"') { + if (yych != '!') goto yy5; + } else { + if (yych <= '&') goto yy100; + if (yych <= '/') goto yy5; + if (yych <= '9') goto yy98; + goto yy5; + } + } else { + if (yych <= '^') { + if (yych <= '@') goto yy100; + if (yych <= 'Z') goto yy98; + goto yy5; + } else { + if (yych == '`') goto yy5; + if (yych <= 'z') goto yy98; + goto yy5; + } + } +yy100: + yych = *++YYCURSOR; + goto yy5; +yy101: + yych = *++YYCURSOR; + if (yych != 'M') goto yy99; + yych = *++YYCURSOR; + if (yych <= '&') { + if (yych <= '\r') { + if (yych <= '\t') { + if (yych <= 0x08) goto yy5; + } else { + if (yych <= '\n') goto yy106; + if (yych >= '\r') goto yy108; + } + } else { + if (yych <= ' ') { + if (yych <= 0x1F) goto yy5; + } else { + if (yych == '"') goto yy5; + goto yy100; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= '/') goto yy5; + goto yy98; + } else { + if (yych <= '?') goto yy5; + if (yych <= '@') goto yy100; + goto yy98; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy5; + goto yy98; + } else { + if (yych <= '`') goto yy5; + if (yych <= 'z') goto yy98; + goto yy5; + } + } + } +yy103: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '\n') { + if (yych == '\t') goto yy103; + } else { + if (yych <= '\f') goto yy103; + if (yych == ' ') goto yy103; + } + { goto singlelinecomment; } +yy106: + ++YYCURSOR; +yy107: + { s->position.line++; RET(TOKEN_NEWLINE); } +yy108: + ++YYCURSOR; + if ((yych = *YYCURSOR) == '\n') goto yy106; + goto yy107; +} + + +singlelinecomment: + if (YYLIMIT == YYCURSOR) YYFILL(1); + matchptr = cursor; + + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '\f') { + if (yych == '\t') goto yy111; + if (yych <= '\n') goto yy115; + } else { + if (yych <= ' ') { + if (yych <= 0x1F) goto yy115; + } else { + if (yych == '$') goto yy113; + goto yy115; + } + } +yy111: + ++YYCURSOR; + yych = *YYCURSOR; + goto yy118; +yy112: + { goto singlelinecomment; } +yy113: + ++YYCURSOR; + { RET(TOKEN_METACOMMAND); } +yy115: + ++YYCURSOR; + { cursor = matchptr; goto singlelinecomment_loop; } +yy117: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy118: + if (yych <= '\n') { + if (yych == '\t') goto yy117; + goto yy112; + } else { + if (yych <= '\f') goto yy117; + if (yych == ' ') goto yy117; + goto yy112; + } +} + + +singlelinecomment_loop: + if (YYLIMIT == YYCURSOR) YYFILL(1); + matchptr = cursor; + + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '\n') { + if (yych <= 0x00) goto yy124; + if (yych <= '\t') goto yy126; + } else { + if (yych == '\r') goto yy123; + goto yy126; + } + ++YYCURSOR; +yy122: + { + s->position.line++; + if (s->report_comments) + { + cursor = matchptr; // so we RET(TOKEN_NEWLINE) next. + RET(TOKEN_SINGLE_COMMENT); + } + token = matchptr; + RET(TOKEN_NEWLINE); + } +yy123: + yych = *++YYCURSOR; + if (yych == '\n') goto yy128; + goto yy122; +yy124: + ++YYCURSOR; + { + if (eoi) + { + if (s->report_comments) + RET(TOKEN_SINGLE_COMMENT); + else + RET(TOKEN_EOI); + } + goto singlelinecomment_loop; + } +yy126: + ++YYCURSOR; + { goto singlelinecomment_loop; } +yy128: + ++YYCURSOR; + yych = *YYCURSOR; + goto yy122; +} + + +bad_chars: + if (YYLIMIT == YYCURSOR) YYFILL(1); + +{ + YYCTYPE yych; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '#') { + if (yych <= '\r') { + if (yych <= 0x00) goto yy133; + if (yych <= 0x08) goto yy135; + } else { + if (yych <= 0x1F) goto yy135; + if (yych == '"') goto yy135; + } + } else { + if (yych <= '@') { + if (yych <= '$') goto yy135; + if (yych >= '@') goto yy135; + } else { + if (yych == '`') goto yy135; + if (yych >= 0x7F) goto yy135; + } + } + ++YYCURSOR; + { cursor--; RET(TOKEN_BAD_CHARS); } +yy133: + ++YYCURSOR; + { + if (eoi) + { + assert( !((token >= sentinel) && + (token < sentinel+YYMAXFILL)) ); + eoi = 0; + cursor = (uchar *) s->source_base + s->orig_length; + RET(TOKEN_BAD_CHARS); // next call will be EOI. + } + goto bad_chars; + } +yy135: + ++YYCURSOR; + { goto bad_chars; } +} + + + assert(0 && "Shouldn't hit this code"); + RET(TOKEN_UNKNOWN); +} // preprocessor_lexer + +// end of mojobasic_lexer.re (or .cpp) ... +