mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
improve f-string
This commit is contained in:
parent
787df86311
commit
2698040f52
77
src/expr.cpp
77
src/expr.cpp
@ -379,7 +379,7 @@ namespace pkpy{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// name or name.name
|
// name or name.name
|
||||||
std::regex pattern(R"(^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*){0,1}$)");
|
PK_LOCAL_STATIC const std::regex pattern(R"(^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*){0,1}$)");
|
||||||
if(std::regex_match(expr.str(), pattern)){
|
if(std::regex_match(expr.str(), pattern)){
|
||||||
int dot = expr.index(".");
|
int dot = expr.index(".");
|
||||||
if(dot < 0){
|
if(dot < 0){
|
||||||
@ -402,19 +402,16 @@ namespace pkpy{
|
|||||||
|
|
||||||
void FStringExpr::emit_(CodeEmitContext* ctx){
|
void FStringExpr::emit_(CodeEmitContext* ctx){
|
||||||
VM* vm = ctx->vm;
|
VM* vm = ctx->vm;
|
||||||
PK_LOCAL_STATIC const std::regex pattern(R"(\{(.*?)\})");
|
int i = 0; // left index
|
||||||
std::cregex_iterator begin(src.begin(), src.end(), pattern);
|
int j = 0; // right index
|
||||||
std::cregex_iterator end;
|
int count = 0; // how many string parts
|
||||||
int size = 0;
|
bool flag = false; // true if we are in a expression
|
||||||
int i = 0;
|
|
||||||
for(auto it = begin; it != end; it++) {
|
while(j < src.size){
|
||||||
std::cmatch m = *it;
|
if(flag){
|
||||||
if (i < m.position()) {
|
if(src[j] == '}'){
|
||||||
Str literal = src.substr(i, m.position() - i);
|
// add expression
|
||||||
ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
Str expr = src.substr(i, j-i);
|
||||||
size++;
|
|
||||||
}
|
|
||||||
Str expr = m[1].str();
|
|
||||||
int conon = expr.index(":");
|
int conon = expr.index(":");
|
||||||
if(conon >= 0){
|
if(conon >= 0){
|
||||||
_load_simple_expr(ctx, expr.substr(0, conon));
|
_load_simple_expr(ctx, expr.substr(0, conon));
|
||||||
@ -423,15 +420,55 @@ namespace pkpy{
|
|||||||
}else{
|
}else{
|
||||||
_load_simple_expr(ctx, expr);
|
_load_simple_expr(ctx, expr);
|
||||||
}
|
}
|
||||||
size++;
|
flag = false;
|
||||||
i = (int)(m.position() + m.length());
|
count++;
|
||||||
}
|
}
|
||||||
if (i < src.length()) {
|
}else{
|
||||||
Str literal = src.substr(i, src.length() - i);
|
if(src[j] == '{'){
|
||||||
|
// look at next char
|
||||||
|
if(j+1 < src.size && src[j+1] == '{'){
|
||||||
|
// {{ -> {
|
||||||
|
j++;
|
||||||
|
ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR("{")), line);
|
||||||
|
count++;
|
||||||
|
}else{
|
||||||
|
// { -> }
|
||||||
|
flag = true;
|
||||||
|
i = j+1;
|
||||||
|
}
|
||||||
|
}else if(src[j] == '}'){
|
||||||
|
// look at next char
|
||||||
|
if(j+1 < src.size && src[j+1] == '}'){
|
||||||
|
// }} -> }
|
||||||
|
j++;
|
||||||
|
ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR("}")), line);
|
||||||
|
count++;
|
||||||
|
}else{
|
||||||
|
// } -> error
|
||||||
|
// throw std::runtime_error("f-string: unexpected }");
|
||||||
|
// just ignore
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// literal
|
||||||
|
i = j;
|
||||||
|
while(j < src.size && src[j] != '{' && src[j] != '}') j++;
|
||||||
|
Str literal = src.substr(i, j-i);
|
||||||
ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
||||||
size++;
|
count++;
|
||||||
|
continue; // skip j++
|
||||||
}
|
}
|
||||||
ctx->emit_(OP_BUILD_STRING, size, line);
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flag){
|
||||||
|
// literal
|
||||||
|
Str literal = src.substr(i, src.size-i);
|
||||||
|
ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->emit_(OP_BUILD_STRING, count, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ s = f'''->->{s}<-<-
|
|||||||
|
|
||||||
assert s == '->->asdasd\nasds1321321321测试\\测试<-<-\n123\n'
|
assert s == '->->asdasd\nasds1321321321测试\\测试<-<-\n123\n'
|
||||||
|
|
||||||
|
x = 1, 2, 3
|
||||||
|
assert f"""
|
||||||
|
a = {{{x[0]}, {x[1]}, {x[2]}}}""" == '\na = {1, 2, 3}'
|
||||||
|
|
||||||
assert r''' ' ''' == " ' "
|
assert r''' ' ''' == " ' "
|
||||||
|
|
||||||
a = 10
|
a = 10
|
||||||
@ -85,6 +89,27 @@ assert f'{"test"!r:*^10}' == "**'test'**"
|
|||||||
assert f'{"test"!r:*^11}' == "**'test'***"
|
assert f'{"test"!r:*^11}' == "**'test'***"
|
||||||
assert f'{12345!r:0>10}' == "0000012345"
|
assert f'{12345!r:0>10}' == "0000012345"
|
||||||
|
|
||||||
|
# test {{ and }}
|
||||||
|
assert f'' == ''
|
||||||
|
assert f'{{}}' == '{}'
|
||||||
|
assert f'{{{{}}}}' == '{{}}'
|
||||||
|
assert f'{{' == '{'
|
||||||
|
assert f'}}' == '}'
|
||||||
|
assert f'{{{{' == '{{'
|
||||||
|
assert f'}}}}' == '}}'
|
||||||
|
a = 123
|
||||||
|
assert f'={a}' == '=123'
|
||||||
|
assert f'{a}=' == '123='
|
||||||
|
assert f'--{a}--' == '--123--'
|
||||||
|
assert f'{{a}}' == '{a}'
|
||||||
|
assert f'{{{a}}}' == '{123}'
|
||||||
|
|
||||||
|
assert f'{{=}}{a}' == '{=}123'
|
||||||
|
assert f'{a}{{=}}' == '123{=}'
|
||||||
|
|
||||||
|
# assert f'}123' == '123' # ignore '}'
|
||||||
|
# assert f'{{{' == '{' # ignore '{'
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'A()'
|
return 'A()'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user