add 'r' string

This commit is contained in:
blueloveTH 2023-01-04 02:09:08 +08:00
parent 1dee1991a3
commit 43f70499a3
3 changed files with 22 additions and 9 deletions

View File

@ -1,3 +1,3 @@
rm -rf web/lib/ rm -rf web/lib/
mkdir -p web/lib/ mkdir -p web/lib/
em++ src/main.cpp -fno-rtti -fexceptions -sASYNCIFY_STACK_SIZE=131072 -O3 -sEXPORTED_FUNCTIONS=_pkpy_delete,_pkpy_new_repl,_pkpy_repl_input,_pkpy_repl_last_input_result,_pkpy_new_tvm,_pkpy_tvm_exec_async,_pkpy_tvm_get_state,_pkpy_tvm_read_jsonrpc_request,_pkpy_tvm_reset_state,_pkpy_tvm_terminate,_pkpy_tvm_write_jsonrpc_response,_pkpy_new_vm,_pkpy_vm_add_module,_pkpy_vm_eval,_pkpy_vm_exec,_pkpy_vm_get_global,_pkpy_vm_read_output -sASYNCIFY -sEXPORTED_RUNTIME_METHODS=ccall -sASYNCIFY_IMPORTS=pkpy_tvm_exec_async,pkpy_repl_input -o web/lib/pocketpy.js em++ src/main.cpp -fno-rtti -fexceptions -sASYNCIFY_STACK_SIZE=131072 -O2 -sEXPORTED_FUNCTIONS=_pkpy_delete,_pkpy_new_repl,_pkpy_repl_input,_pkpy_repl_last_input_result,_pkpy_new_tvm,_pkpy_tvm_exec_async,_pkpy_tvm_get_state,_pkpy_tvm_read_jsonrpc_request,_pkpy_tvm_reset_state,_pkpy_tvm_terminate,_pkpy_tvm_write_jsonrpc_response,_pkpy_new_vm,_pkpy_vm_add_module,_pkpy_vm_eval,_pkpy_vm_exec,_pkpy_vm_get_global,_pkpy_vm_read_output -sASYNCIFY -sEXPORTED_RUNTIME_METHODS=ccall -sASYNCIFY_IMPORTS=pkpy_tvm_exec_async,pkpy_repl_input -o web/lib/pocketpy.js

View File

@ -21,6 +21,8 @@ struct Loop {
Loop(int start) : start(start) {} Loop(int start) : start(start) {}
}; };
enum StringType { NORMAL_STRING, RAW_STRING, F_STRING };
class Compiler { class Compiler {
public: public:
pkpy::unique_ptr<Parser> parser; pkpy::unique_ptr<Parser> parser;
@ -112,13 +114,13 @@ public:
#define EXPR_ANY() parsePrecedence(PREC_ASSIGNMENT) #define EXPR_ANY() parsePrecedence(PREC_ASSIGNMENT)
} }
_Str eatStringUntil(char quote) { _Str eatStringUntil(char quote, bool raw) {
std::vector<char> buff; std::vector<char> buff;
while (true) { while (true) {
char c = parser->eatCharIncludeNewLine(); char c = parser->eatCharIncludeNewLine();
if (c == quote) break; if (c == quote) break;
if (c == '\0' || c == '\n') syntaxError("EOL while scanning string literal"); if (c == '\0' || c == '\n') syntaxError("EOL while scanning string literal");
if (c == '\\') { if (!raw && c == '\\') {
switch (parser->eatCharIncludeNewLine()) { switch (parser->eatCharIncludeNewLine()) {
case '"': buff.push_back('"'); break; case '"': buff.push_back('"'); break;
case '\'': buff.push_back('\''); break; case '\'': buff.push_back('\''); break;
@ -136,9 +138,9 @@ public:
return _Str(buff.data(), buff.size()); return _Str(buff.data(), buff.size());
} }
void eatString(char quote, bool fstr) { void eatString(char quote, StringType type) {
_Str s = eatStringUntil(quote); _Str s = eatStringUntil(quote, type == RAW_STRING);
if(fstr){ if(type == F_STRING){
parser->setNextToken(TK("@fstr"), vm->PyStr(s)); parser->setNextToken(TK("@fstr"), vm->PyStr(s));
}else{ }else{
parser->setNextToken(TK("@str"), vm->PyStr(s)); parser->setNextToken(TK("@str"), vm->PyStr(s));
@ -191,7 +193,7 @@ public:
parser->token_start = parser->current_char; parser->token_start = parser->current_char;
char c = parser->eatCharIncludeNewLine(); char c = parser->eatCharIncludeNewLine();
switch (c) { switch (c) {
case '\'': case '"': eatString(c, false); return; case '\'': case '"': eatString(c, NORMAL_STRING); return;
case '#': parser->skipLineComment(); break; case '#': parser->skipLineComment(); break;
case '{': parser->setNextToken(TK("{")); return; case '{': parser->setNextToken(TK("{")); return;
case '}': parser->setNextToken(TK("}")); return; case '}': parser->setNextToken(TK("}")); return;
@ -266,9 +268,13 @@ public:
} }
default: { default: {
if(c == 'f'){ if(c == 'f'){
if(parser->matchChar('\'')) {eatString('\'', true); return;} if(parser->matchChar('\'')) {eatString('\'', F_STRING); return;}
if(parser->matchChar('"')) {eatString('"', true); 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') { if (c >= '0' && c <= '9') {
eatNumber(); eatNumber();
return; return;

7
tests/_rawstring.py Normal file
View File

@ -0,0 +1,7 @@
a = r'1\232\\\13'
assert a == '1\\232\\\\\\13'
b = r'\'
assert len(b) == 3
assert b == '\\'