diff --git a/plugins/flutter/CHANGELOG.md b/plugins/flutter/CHANGELOG.md index 59806075..1ff4acf6 100644 --- a/plugins/flutter/CHANGELOG.md +++ b/plugins/flutter/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.6.1+3 +## 0.6.1+4 + Break change diff --git a/plugins/flutter/pubspec.yaml b/plugins/flutter/pubspec.yaml index a75a460d..e3f42dd0 100644 --- a/plugins/flutter/pubspec.yaml +++ b/plugins/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: pocketpy description: A lightweight Python interpreter for game engines. -version: 0.6.1+3 +version: 0.6.1+4 homepage: https://pocketpy.dev repository: https://github.com/blueloveth/pocketpy diff --git a/plugins/flutter/src/pocketpy.h b/plugins/flutter/src/pocketpy.h index 7daa31a2..fcce575b 100644 --- a/plugins/flutter/src/pocketpy.h +++ b/plugins/flutter/src/pocketpy.h @@ -3276,6 +3276,15 @@ struct Parser { return *current_char; } + std::string_view lookahead(int n){ + const char* c = current_char; + for(int i=0; i parser; @@ -5193,13 +5204,45 @@ public: #define EXPR_ANY() parsePrecedence(PREC_ASSIGNMENT) } - _Str eatStringUntil(char quote) { + _Str eatStringUntil(char quote, bool raw) { + bool quote3 = false; + std::string_view sv = parser->lookahead(2); + if(sv.size() == 2 && sv[0] == quote && sv[1] == quote) { + quote3 = true; + parser->eatChar(); + parser->eatChar(); + } + std::vector buff; while (true) { char c = parser->eatCharIncludeNewLine(); - if (c == quote) break; - if (c == '\0' || c == '\n') syntaxError("EOL while scanning string literal"); - if (c == '\\') { + if (c == quote){ + if(quote3){ + sv = parser->lookahead(2); + if(sv.size() == 2 && sv[0] == quote && sv[1] == quote) { + parser->eatChar(); + parser->eatChar(); + break; + } + buff.push_back(c); + } else { + break; + } + } + if (c == '\0'){ + if(quote3 && parser->src->mode == SINGLE_MODE){ + throw NeedMoreLines(false); + } + syntaxError("EOL while scanning string literal"); + } + if (c == '\n'){ + if(!quote3) syntaxError("EOL while scanning string literal"); + else{ + buff.push_back(c); + continue; + } + } + if (!raw && c == '\\') { switch (parser->eatCharIncludeNewLine()) { case '"': buff.push_back('"'); break; case '\'': buff.push_back('\''); break; @@ -5207,7 +5250,6 @@ public: case 'n': buff.push_back('\n'); break; case 'r': buff.push_back('\r'); break; case 't': buff.push_back('\t'); break; - case '\n': case '\r': break; default: syntaxError("invalid escape character"); } } else { @@ -5217,9 +5259,9 @@ public: return _Str(buff.data(), buff.size()); } - void eatString(char quote, bool fstr) { - _Str s = eatStringUntil(quote); - if(fstr){ + void eatString(char quote, StringType type) { + _Str s = eatStringUntil(quote, type == RAW_STRING); + if(type == F_STRING){ parser->setNextToken(TK("@fstr"), vm->PyStr(s)); }else{ parser->setNextToken(TK("@str"), vm->PyStr(s)); @@ -5272,7 +5314,7 @@ public: parser->token_start = parser->current_char; char c = parser->eatCharIncludeNewLine(); switch (c) { - case '\'': case '"': eatString(c, false); return; + case '\'': case '"': eatString(c, NORMAL_STRING); return; case '#': parser->skipLineComment(); break; case '{': parser->setNextToken(TK("{")); return; case '}': parser->setNextToken(TK("}")); return; @@ -5347,9 +5389,13 @@ public: } default: { if(c == 'f'){ - if(parser->matchChar('\'')) {eatString('\'', true); return;} - if(parser->matchChar('"')) {eatString('"', true); 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 (c >= '0' && c <= '9') { eatNumber(); return; diff --git a/plugins/godot/godot-cpp b/plugins/godot/godot-cpp index 2ddb3949..f79c819e 160000 --- a/plugins/godot/godot-cpp +++ b/plugins/godot/godot-cpp @@ -1 +1 @@ -Subproject commit 2ddb39495bb1078d5686b35a19645fd6ab4690ee +Subproject commit f79c819e0928bddb2714875db6ba142e04f6a4fd