From b4a8969139c5b93ba59c76b4cd98ab3ff0f93649 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 23 Jan 2023 19:22:22 +0800 Subject: [PATCH] up --- amalgamate.py | 13 +- plugins/flutter/src/pocketpy.h | 235 +++++++++++++++------------------ plugins/godot/godot-cpp | 2 +- 3 files changed, 118 insertions(+), 132 deletions(-) diff --git a/amalgamate.py b/amalgamate.py index 96fd8151..486bd5ee 100644 --- a/amalgamate.py +++ b/amalgamate.py @@ -41,7 +41,7 @@ for seq in pipeline: with open("amalgamated/pocketpy.h", "wt", encoding='utf-8') as f: final_text = \ r'''/* - * Copyright (c) 2022 blueloveTH + * Copyright (c) 2023 blueloveTH * Distributed Under The LGPLv3 License */ @@ -55,7 +55,16 @@ os.system("g++ -o pocketpy amalgamated/main.cpp --std=c++17 -pthread") os.system("rm pocketpy") os.system("cp amalgamated/pocketpy.h plugins/flutter/src/pocketpy.h") -os.system('cp amalgamated/pocketpy.h "plugins/unity/My project/Assets/com.bl.pocketpy/Plugins/iOS/pocketpy.h"') + +unity_ios_header = 'plugins/unity/My project/Assets/com.bl.pocketpy/Plugins/iOS/pocketpy.h' +os.system(f'cp amalgamated/pocketpy.h "{unity_ios_header}"') + +# replace Distributed Under The LGPLv3 License +with open(unity_ios_header, "rt", encoding='utf-8') as f: + text = f.read() + text = text.replace("Distributed Under The LGPLv3 License", "Distributed Under The PocketPy Unity Exclusive License") +with open(unity_ios_header, "wt", encoding='utf-8') as f: + f.write(text) if os.path.exists("plugins/godot/godot-cpp/pocketpy"): os.system("cp amalgamated/pocketpy.h plugins/godot/godot-cpp/pocketpy/src/pocketpy.h") \ No newline at end of file diff --git a/plugins/flutter/src/pocketpy.h b/plugins/flutter/src/pocketpy.h index c6042555..0373d386 100644 --- a/plugins/flutter/src/pocketpy.h +++ b/plugins/flutter/src/pocketpy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 blueloveTH + * Copyright (c) 2023 blueloveTH * Distributed Under The LGPLv3 License */ @@ -3123,7 +3123,6 @@ constexpr _TokenType TK(const char* const token) { } #define TK_STR(t) __TOKENS[t] - const _TokenType __KW_BEGIN = TK("class"); const _TokenType __KW_END = TK("raise"); @@ -3142,9 +3141,7 @@ struct Token{ int line; //< Line number of the token (1 based). PyVar value; //< Literal value of the token. - const _Str str() const { - return _Str(start, length); - } + const _Str str() const { return _Str(start, length);} const _Str info() const { _StrStream ss; @@ -3194,8 +3191,10 @@ struct Parser { int brackets_level_1 = 0; int brackets_level_2 = 0; - Token nextToken(){ - if(nexts.empty()) return makeErrToken(); + Token next_token(){ + if(nexts.empty()){ + return Token{TK("@error"), token_start, (int)(curr_char - token_start), current_line}; + } Token t = nexts.front(); if(t.type == TK("@eof") && indents.size()>1){ nexts.pop(); @@ -3206,11 +3205,9 @@ struct Parser { return t; } - inline char peek_char() { - return *curr_char; - } + inline char peekchar() const{ return *curr_char; } - std::string_view lookahead(int n){ + std::string_view lookahead(int n) const{ const char* c = curr_char; for(int i=0; i 0 || brackets_level_1 > 0 || brackets_level_2 > 0) return true; - int spaces = eatSpaces(); - if(peek_char() == '#') skipLineComment(); - if(peek_char() == '\0' || peek_char() == '\n') return true; + int spaces = eat_spaces(); + if(peekchar() == '#') skip_line_comment(); + if(peekchar() == '\0' || peekchar() == '\n') return true; // https://docs.python.org/3/reference/lexical_analysis.html#indentation if(spaces > indents.top()){ indents.push(spaces); @@ -3252,15 +3249,15 @@ struct Parser { return true; } - char eatChar() { - char c = peek_char(); - if(c == '\n') throw std::runtime_error("eatChar() cannot consume a newline"); + char eatchar() { + char c = peekchar(); + if(c == '\n') throw std::runtime_error("eatchar() cannot consume a newline"); curr_char++; return c; } - char eatCharIncludeNewLine() { - char c = peek_char(); + char eatchar_include_newLine() { + char c = peekchar(); curr_char++; if (c == '\n'){ current_line++; @@ -3269,10 +3266,10 @@ struct Parser { return c; } - int eatName() { + int eat_name() { curr_char--; while(true){ - uint8_t c = peek_char(); + uint8_t c = peekchar(); int u8bytes = 0; if((c & 0b10000000) == 0b00000000) u8bytes = 1; else if((c & 0b11100000) == 0b11000000) u8bytes = 2; @@ -3311,11 +3308,11 @@ struct Parser { if(src->mode == JSON_MODE){ if(name == "true"){ - setNextToken(TK("True")); + set_next_token(TK("True")); } else if(name == "false"){ - setNextToken(TK("False")); + set_next_token(TK("False")); } else if(name == "null"){ - setNextToken(TK("None")); + set_next_token(TK("None")); } else { return 4; } @@ -3326,46 +3323,41 @@ struct Parser { if(name == "not"){ if(strncmp(curr_char, " in", 3) == 0){ curr_char += 3; - setNextToken(TK("not in")); + set_next_token(TK("not in")); return 0; } }else if(name == "is"){ if(strncmp(curr_char, " not", 4) == 0){ curr_char += 4; - setNextToken(TK("is not")); + set_next_token(TK("is not")); return 0; } } - setNextToken(__KW_MAP.at(name)); + set_next_token(__KW_MAP.at(name)); } else { - setNextToken(TK("@id")); + set_next_token(TK("@id")); } return 0; } - void skipLineComment() { + void skip_line_comment() { char c; - while ((c = peek_char()) != '\0') { + while ((c = peekchar()) != '\0') { if (c == '\n') return; - eatChar(); + eatchar(); } } // If the current char is [c] consume it and advance char by 1 and returns // true otherwise returns false. - bool matchChar(char c) { - if (peek_char() != c) return false; - eatCharIncludeNewLine(); + bool matchchar(char c) { + if (peekchar() != c) return false; + eatchar_include_newLine(); return true; } - // Returns an error token from the current position for reporting error. - Token makeErrToken() { - return Token{TK("@error"), token_start, (int)(curr_char - token_start), current_line}; - } - // Initialize the next token as the type. - void setNextToken(_TokenType type, PyVar value=nullptr) { + void set_next_token(_TokenType type, PyVar value=nullptr) { switch(type){ case TK("("): brackets_level_0++; break; @@ -3385,9 +3377,9 @@ struct Parser { }); } - void setNextTwoCharToken(char c, _TokenType one, _TokenType two) { - if (matchChar(c)) setNextToken(two); - else setNextToken(one); + void set_next_token_2(char c, _TokenType one, _TokenType two) { + if (matchchar(c)) set_next_token(two); + else set_next_token(one); } Parser(_Source src) { @@ -5104,16 +5096,10 @@ public: bool isCompilingClass = false; int lexingCnt = 0; VM* vm; - emhash8::HashMap<_TokenType, GrammarRule> rules; - _Code co() { - return codes.top(); - } - - CompileMode mode() { - return parser->src->mode; - } + _Code co() const{ return codes.top(); } + CompileMode mode() const{ return parser->src->mode;} Compiler(VM* vm, const char* source, _Str filename, CompileMode mode){ this->vm = vm; @@ -5179,7 +5165,7 @@ public: #undef NO_INFIX #define EXPR() parsePrecedence(PREC_TERNARY) // no '=' and ',' just a simple expression -#define EXPR_TUPLE() parsePrecedence(PREC_COMMA) // no '=', but ',' is allowed +#define EXPR_TUPLE() parsePrecedence(PREC_COMMA) // no '=', but ',' is allowed #define EXPR_ANY() parsePrecedence(PREC_ASSIGNMENT) } @@ -5188,19 +5174,19 @@ public: std::string_view sv = parser->lookahead(2); if(sv.size() == 2 && sv[0] == quote && sv[1] == quote) { quote3 = true; - parser->eatChar(); - parser->eatChar(); + parser->eatchar(); + parser->eatchar(); } std::vector buff; while (true) { - char c = parser->eatCharIncludeNewLine(); + char c = parser->eatchar_include_newLine(); if (c == quote){ if(quote3){ sv = parser->lookahead(2); if(sv.size() == 2 && sv[0] == quote && sv[1] == quote) { - parser->eatChar(); - parser->eatChar(); + parser->eatchar(); + parser->eatchar(); break; } buff.push_back(c); @@ -5222,7 +5208,7 @@ public: } } if (!raw && c == '\\') { - switch (parser->eatCharIncludeNewLine()) { + switch (parser->eatchar_include_newLine()) { case '"': buff.push_back('"'); break; case '\'': buff.push_back('\''); break; case '\\': buff.push_back('\\'); break; @@ -5241,9 +5227,9 @@ public: void eatString(char quote, StringType type) { _Str s = eatStringUntil(quote, type == RAW_STRING); if(type == F_STRING){ - parser->setNextToken(TK("@fstr"), vm->PyStr(s)); + parser->set_next_token(TK("@fstr"), vm->PyStr(s)); }else{ - parser->setNextToken(TK("@str"), vm->PyStr(s)); + parser->set_next_token(TK("@str"), vm->PyStr(s)); } } @@ -5257,17 +5243,17 @@ public: try{ if (std::regex_search(s, m, pattern)) { - // here is m.length()-1, since the first char is eaten by lexToken() - for(int j=0; jeatChar(); + // here is m.length()-1, since the first char was eaten by lexToken() + for(int j=0; jeatchar(); int base = 10; size_t size; if (m[1].matched) base = 16; if (m[2].matched) { if(base == 16) syntaxError("hex literal should not contain a dot"); - parser->setNextToken(TK("@num"), vm->PyFloat(std::stod(m[0], &size))); + parser->set_next_token(TK("@num"), vm->PyFloat(std::stod(m[0], &size))); } else { - parser->setNextToken(TK("@num"), vm->PyInt(std::stoll(m[0], &size, base))); + parser->set_next_token(TK("@num"), vm->PyInt(std::stoll(m[0], &size, base))); } if (size != m.length()) throw std::runtime_error("length mismatch"); } @@ -5285,94 +5271,94 @@ public: // Lex the next token and set it as the next token. void _lexToken() { parser->prev = parser->curr; - parser->curr = parser->nextToken(); + parser->curr = parser->next_token(); //_Str _info = parser->curr.info(); std::cout << _info << '[' << parser->current_line << ']' << std::endl; - while (parser->peek_char() != '\0') { + while (parser->peekchar() != '\0') { parser->token_start = parser->curr_char; - char c = parser->eatCharIncludeNewLine(); + char c = parser->eatchar_include_newLine(); switch (c) { case '\'': case '"': eatString(c, NORMAL_STRING); return; - case '#': parser->skipLineComment(); break; - case '{': parser->setNextToken(TK("{")); return; - case '}': parser->setNextToken(TK("}")); return; - case ',': parser->setNextToken(TK(",")); return; - case ':': parser->setNextToken(TK(":")); return; - case ';': parser->setNextToken(TK(";")); return; - case '(': parser->setNextToken(TK("(")); return; - case ')': parser->setNextToken(TK(")")); return; - case '[': parser->setNextToken(TK("[")); return; - case ']': parser->setNextToken(TK("]")); return; - case '%': parser->setNextTwoCharToken('=', TK("%"), TK("%=")); return; - case '&': parser->setNextTwoCharToken('=', TK("&"), TK("&=")); return; - case '|': parser->setNextTwoCharToken('=', TK("|"), TK("|=")); return; - case '^': parser->setNextTwoCharToken('=', TK("^"), TK("^=")); return; - case '?': parser->setNextToken(TK("?")); return; + case '#': parser->skip_line_comment(); break; + case '{': parser->set_next_token(TK("{")); return; + case '}': parser->set_next_token(TK("}")); return; + case ',': parser->set_next_token(TK(",")); return; + case ':': parser->set_next_token(TK(":")); return; + case ';': parser->set_next_token(TK(";")); return; + case '(': parser->set_next_token(TK("(")); return; + case ')': parser->set_next_token(TK(")")); return; + case '[': parser->set_next_token(TK("[")); return; + case ']': parser->set_next_token(TK("]")); return; + case '%': parser->set_next_token_2('=', TK("%"), TK("%=")); return; + case '&': parser->set_next_token_2('=', TK("&"), TK("&=")); return; + case '|': parser->set_next_token_2('=', TK("|"), TK("|=")); return; + case '^': parser->set_next_token_2('=', TK("^"), TK("^=")); return; + case '?': parser->set_next_token(TK("?")); return; case '.': { - if(parser->matchChar('.')) { - if(parser->matchChar('.')) { - parser->setNextToken(TK("...")); + if(parser->matchchar('.')) { + if(parser->matchchar('.')) { + parser->set_next_token(TK("...")); } else { syntaxError("invalid token '..'"); } } else { - parser->setNextToken(TK(".")); + parser->set_next_token(TK(".")); } return; } - case '=': parser->setNextTwoCharToken('=', TK("="), TK("==")); return; - case '+': parser->setNextTwoCharToken('=', TK("+"), TK("+=")); return; + case '=': parser->set_next_token_2('=', TK("="), TK("==")); return; + case '+': parser->set_next_token_2('=', TK("+"), TK("+=")); return; case '>': { - if(parser->matchChar('=')) parser->setNextToken(TK(">=")); - else if(parser->matchChar('>')) parser->setNextToken(TK(">>")); - else parser->setNextToken(TK(">")); + if(parser->matchchar('=')) parser->set_next_token(TK(">=")); + else if(parser->matchchar('>')) parser->set_next_token(TK(">>")); + else parser->set_next_token(TK(">")); return; } case '<': { - if(parser->matchChar('=')) parser->setNextToken(TK("<=")); - else if(parser->matchChar('<')) parser->setNextToken(TK("<<")); - else parser->setNextToken(TK("<")); + if(parser->matchchar('=')) parser->set_next_token(TK("<=")); + else if(parser->matchchar('<')) parser->set_next_token(TK("<<")); + else parser->set_next_token(TK("<")); return; } case '-': { - if(parser->matchChar('=')) parser->setNextToken(TK("-=")); - else if(parser->matchChar('>')) parser->setNextToken(TK("->")); - else parser->setNextToken(TK("-")); + if(parser->matchchar('=')) parser->set_next_token(TK("-=")); + else if(parser->matchchar('>')) parser->set_next_token(TK("->")); + else parser->set_next_token(TK("-")); return; } case '!': - if(parser->matchChar('=')) parser->setNextToken(TK("!=")); + if(parser->matchchar('=')) parser->set_next_token(TK("!=")); else syntaxError("expected '=' after '!'"); break; case '*': - if (parser->matchChar('*')) { - parser->setNextToken(TK("**")); // '**' + if (parser->matchchar('*')) { + parser->set_next_token(TK("**")); // '**' } else { - parser->setNextTwoCharToken('=', TK("*"), TK("*=")); + parser->set_next_token_2('=', TK("*"), TK("*=")); } return; case '/': - if(parser->matchChar('/')) { - parser->setNextTwoCharToken('=', TK("//"), TK("//=")); + if(parser->matchchar('/')) { + parser->set_next_token_2('=', TK("//"), TK("//=")); } else { - parser->setNextTwoCharToken('=', TK("/"), TK("/=")); + parser->set_next_token_2('=', TK("/"), TK("/=")); } return; case '\r': break; // just ignore '\r' - case ' ': case '\t': parser->eatSpaces(); break; + case ' ': case '\t': parser->eat_spaces(); break; case '\n': { - parser->setNextToken(TK("@eol")); - if(!parser->eatIndentation()) indentationError("unindent does not match any outer indentation level"); + parser->set_next_token(TK("@eol")); + if(!parser->eat_indentation()) indentationError("unindent does not match any outer indentation level"); return; } default: { if(c == 'f'){ - if(parser->matchChar('\'')) {eatString('\'', F_STRING); return;} - if(parser->matchChar('"')) {eatString('"', F_STRING); return;} + if(parser->matchchar('\'')) {eatString('\'', F_STRING); return;} + if(parser->matchchar('"')) {eatString('"', F_STRING); return;} }else if(c == 'r'){ - if(parser->matchChar('\'')) {eatString('\'', RAW_STRING); return;} - if(parser->matchChar('"')) {eatString('"', RAW_STRING); return;} + if(parser->matchchar('\'')) {eatString('\'', RAW_STRING); return;} + if(parser->matchchar('"')) {eatString('"', RAW_STRING); return;} } if (c >= '0' && c <= '9') { @@ -5380,7 +5366,7 @@ public: return; } - switch (parser->eatName()) + switch (parser->eat_name()) { case 0: break; case 1: syntaxError("invalid char: " + std::string(1, c)); @@ -5395,7 +5381,7 @@ public: } parser->token_start = parser->curr_char; - parser->setNextToken(TK("@eof")); + parser->set_next_token(TK("@eof")); } inline _TokenType peek() { @@ -5435,12 +5421,8 @@ public: } bool matchEndStatement() { - if (match(TK(";"))) { - matchNewLines(); - return true; - } - if (matchNewLines() || peek() == TK("@eof")) - return true; + if (match(TK(";"))) { matchNewLines(); return true; } + if (matchNewLines() || peek()==TK("@eof")) return true; if (peek() == TK("@dedent")) return true; return false; } @@ -5506,7 +5488,6 @@ public: EXPR_TUPLE(); emit(OP_STORE_REF); }else{ // a += (expr) -> a = a + (expr) - // TODO: optimization is needed for inplace operators emit(OP_DUP_TOP); EXPR(); switch (op) { @@ -5515,7 +5496,6 @@ public: case TK("*="): emit(OP_BINARY_OP, 2); break; case TK("/="): emit(OP_BINARY_OP, 3); break; case TK("//="): emit(OP_BINARY_OP, 4); break; - case TK("%="): emit(OP_BINARY_OP, 5); break; case TK("&="): emit(OP_BITWISE_OP, 2); break; case TK("|="): emit(OP_BITWISE_OP, 3); break; @@ -5592,9 +5572,7 @@ public: void exprUnaryOp() { _TokenType op = parser->prev.type; - matchNewLines(); parsePrecedence((Precedence)(PREC_UNARY + 1)); - switch (op) { case TK("-"): emit(OP_UNARY_NEGATIVE); break; case TK("not"): emit(OP_UNARY_NOT); break; @@ -5683,7 +5661,6 @@ __LISTCOMP: size++; matchNewLines(mode()==SINGLE_MODE); } while (match(TK(","))); - matchNewLines(); consume(TK("}")); if(size == 0 || parsing_dict) emit(OP_BUILD_MAP, size); @@ -6180,7 +6157,7 @@ __LISTCOMP: lineno = parser->current_line; cursor = parser->curr_char; } - if(parser->peek_char() == '\n') lineno--; + if(parser->peekchar() == '\n') lineno--; return parser->src->snapshot(lineno, cursor); } diff --git a/plugins/godot/godot-cpp b/plugins/godot/godot-cpp index 93115425..758b1c0f 160000 --- a/plugins/godot/godot-cpp +++ b/plugins/godot/godot-cpp @@ -1 +1 @@ -Subproject commit 931154255fe0463eefde933026623d3a805c8433 +Subproject commit 758b1c0f7fde1128968e56d21191d5bc0f9273df