diff --git a/build_wasm.sh b/build_wasm.sh index 4993d859..38f46ea0 100644 --- a/build_wasm.sh +++ b/build_wasm.sh @@ -1,3 +1,3 @@ rm -rf 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 \ No newline at end of file +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 \ No newline at end of file diff --git a/src/compiler.h b/src/compiler.h index e3aed30d..c4647469 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -21,6 +21,8 @@ struct Loop { Loop(int start) : start(start) {} }; +enum StringType { NORMAL_STRING, RAW_STRING, F_STRING }; + class Compiler { public: pkpy::unique_ptr parser; @@ -112,13 +114,13 @@ public: #define EXPR_ANY() parsePrecedence(PREC_ASSIGNMENT) } - _Str eatStringUntil(char quote) { + _Str eatStringUntil(char quote, bool raw) { 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 (!raw && c == '\\') { switch (parser->eatCharIncludeNewLine()) { case '"': buff.push_back('"'); break; case '\'': buff.push_back('\''); break; @@ -136,9 +138,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)); @@ -191,7 +193,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; @@ -266,9 +268,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/tests/_rawstring.py b/tests/_rawstring.py new file mode 100644 index 00000000..8ca00e19 --- /dev/null +++ b/tests/_rawstring.py @@ -0,0 +1,7 @@ +a = r'1\232\\\13' + +assert a == '1\\232\\\\\\13' + +b = r'测\试' +assert len(b) == 3 +assert b == '测\\试' \ No newline at end of file