mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-24 13:30:18 +00:00
...
This commit is contained in:
parent
1d626cea88
commit
de16324601
@ -80,7 +80,6 @@ __NEXT_STEP:;
|
|||||||
TARGET(LOAD_FALSE) PUSH(False); DISPATCH();
|
TARGET(LOAD_FALSE) PUSH(False); DISPATCH();
|
||||||
TARGET(LOAD_INTEGER) PUSH(VAR(byte.arg)); DISPATCH();
|
TARGET(LOAD_INTEGER) PUSH(VAR(byte.arg)); DISPATCH();
|
||||||
TARGET(LOAD_ELLIPSIS) PUSH(Ellipsis); DISPATCH();
|
TARGET(LOAD_ELLIPSIS) PUSH(Ellipsis); DISPATCH();
|
||||||
TARGET(LOAD_BUILTIN_EVAL) PUSH(builtins->attr(m_eval)); DISPATCH();
|
|
||||||
TARGET(LOAD_FUNCTION) {
|
TARGET(LOAD_FUNCTION) {
|
||||||
FuncDecl_ decl = co->func_decls[byte.arg];
|
FuncDecl_ decl = co->func_decls[byte.arg];
|
||||||
bool is_simple = decl->starred_arg==-1 && decl->kwargs.size()==0 && !decl->code->is_generator;
|
bool is_simple = decl->starred_arg==-1 && decl->kwargs.size()==0 && !decl->code->is_generator;
|
||||||
@ -547,6 +546,11 @@ __NEXT_STEP:;
|
|||||||
TARGET(SETUP_DOCSTRING)
|
TARGET(SETUP_DOCSTRING)
|
||||||
TOP()->attr().set(__doc__, co_consts[byte.arg]);
|
TOP()->attr().set(__doc__, co_consts[byte.arg]);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
TARGET(FORMAT_STRING) {
|
||||||
|
_0 = POPX();
|
||||||
|
const Str& spec = CAST(Str&, co_consts[byte.arg]);
|
||||||
|
PUSH(VAR(format(spec, _0)));
|
||||||
|
} DISPATCH();
|
||||||
#if !PK_ENABLE_COMPUTED_GOTO
|
#if !PK_ENABLE_COMPUTED_GOTO
|
||||||
#if DEBUG_EXTRA_CHECK
|
#if DEBUG_EXTRA_CHECK
|
||||||
default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
|
default: throw std::runtime_error(fmt(OP_NAMES[byte.op], " is not implemented"));
|
||||||
|
|||||||
17
src/expr.h
17
src/expr.h
@ -536,10 +536,19 @@ struct FStringExpr: Expr{
|
|||||||
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
ctx->emit(OP_LOAD_BUILTIN_EVAL, BC_NOARG, line);
|
Str expr = m[1].str();
|
||||||
ctx->emit(OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE);
|
int conon = expr.index(":");
|
||||||
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(m[1].str())), line);
|
if(conon >= 0){
|
||||||
ctx->emit(OP_CALL, 1, line);
|
ctx->emit(
|
||||||
|
OP_LOAD_NAME,
|
||||||
|
StrName(expr.substr(0, conon)).index,
|
||||||
|
line
|
||||||
|
);
|
||||||
|
Str spec = expr.substr(conon+1);
|
||||||
|
ctx->emit(OP_FORMAT_STRING, ctx->add_const(VAR(spec)), line);
|
||||||
|
}else{
|
||||||
|
ctx->emit(OP_LOAD_NAME, StrName(expr).index, line);
|
||||||
|
}
|
||||||
size++;
|
size++;
|
||||||
i = (int)(m.position() + m.length());
|
i = (int)(m.position() + m.length());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ OPCODE(LOAD_TRUE)
|
|||||||
OPCODE(LOAD_FALSE)
|
OPCODE(LOAD_FALSE)
|
||||||
OPCODE(LOAD_INTEGER)
|
OPCODE(LOAD_INTEGER)
|
||||||
OPCODE(LOAD_ELLIPSIS)
|
OPCODE(LOAD_ELLIPSIS)
|
||||||
OPCODE(LOAD_BUILTIN_EVAL)
|
|
||||||
OPCODE(LOAD_FUNCTION)
|
OPCODE(LOAD_FUNCTION)
|
||||||
OPCODE(LOAD_NULL)
|
OPCODE(LOAD_NULL)
|
||||||
/**************************/
|
/**************************/
|
||||||
@ -111,4 +110,5 @@ OPCODE(RAISE)
|
|||||||
OPCODE(RE_RAISE)
|
OPCODE(RE_RAISE)
|
||||||
/**************************/
|
/**************************/
|
||||||
OPCODE(SETUP_DOCSTRING)
|
OPCODE(SETUP_DOCSTRING)
|
||||||
|
OPCODE(FORMAT_STRING)
|
||||||
#endif
|
#endif
|
||||||
@ -164,6 +164,10 @@ struct Str{
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Str substr(int start) const {
|
||||||
|
return substr(start, size - start);
|
||||||
|
}
|
||||||
|
|
||||||
char* c_str_dup() const {
|
char* c_str_dup() const {
|
||||||
char* p = (char*)malloc(size + 1);
|
char* p = (char*)malloc(size + 1);
|
||||||
memcpy(p, data, size);
|
memcpy(p, data, size);
|
||||||
@ -396,7 +400,6 @@ const StrName __setattr__ = StrName::get("__setattr__");
|
|||||||
const StrName __call__ = StrName::get("__call__");
|
const StrName __call__ = StrName::get("__call__");
|
||||||
const StrName __doc__ = StrName::get("__doc__");
|
const StrName __doc__ = StrName::get("__doc__");
|
||||||
|
|
||||||
const StrName m_eval = StrName::get("eval");
|
|
||||||
const StrName m_self = StrName::get("self");
|
const StrName m_self = StrName::get("self");
|
||||||
const StrName m_dict = StrName::get("dict");
|
const StrName m_dict = StrName::get("dict");
|
||||||
const StrName m_set = StrName::get("set");
|
const StrName m_set = StrName::get("set");
|
||||||
|
|||||||
55
src/vm.h
55
src/vm.h
@ -395,6 +395,7 @@ public:
|
|||||||
PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true);
|
PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true);
|
||||||
PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false);
|
PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false);
|
||||||
void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step);
|
void parse_int_slice(const Slice& s, int length, int& start, int& stop, int& step);
|
||||||
|
Str format(Str, PyObject*);
|
||||||
void setattr(PyObject* obj, StrName name, PyObject* value);
|
void setattr(PyObject* obj, StrName name, PyObject* value);
|
||||||
template<int ARGC>
|
template<int ARGC>
|
||||||
void bind_method(PyObject*, Str, NativeFuncC);
|
void bind_method(PyObject*, Str, NativeFuncC);
|
||||||
@ -641,6 +642,60 @@ inline PyObject* VM::asRepr(PyObject* obj){
|
|||||||
return call_method(obj, __repr__);
|
return call_method(obj, __repr__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Str VM::format(Str spec, PyObject* obj){
|
||||||
|
char type = spec.end()[-1];
|
||||||
|
int dot = -1;
|
||||||
|
int width, precision;
|
||||||
|
char align;
|
||||||
|
if(spec[0] == '>'){
|
||||||
|
align = '>';
|
||||||
|
spec = spec.substr(1);
|
||||||
|
dot = spec.index(".");
|
||||||
|
}else if(spec[0] == '<'){
|
||||||
|
align = '<';
|
||||||
|
spec = spec.substr(1);
|
||||||
|
dot = spec.index(".");
|
||||||
|
}else{
|
||||||
|
if(is_int(obj) || is_float(obj)) align = '>';
|
||||||
|
else align = '<';
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
if(dot >= 0){
|
||||||
|
width = Number::stoi(spec.substr(0, dot).str());
|
||||||
|
precision = Number::stoi(spec.substr(dot+1).str());
|
||||||
|
}else{
|
||||||
|
width = Number::stoi(spec.str());
|
||||||
|
precision = -1;
|
||||||
|
}
|
||||||
|
}catch(...){
|
||||||
|
ValueError("invalid format specifer");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type != 'f' && dot >= 0) ValueError("precision not allowed in the format specifier");
|
||||||
|
Str ret;
|
||||||
|
if(type == 'f'){
|
||||||
|
f64 val = num_to_float(obj);
|
||||||
|
if(precision < 0) precision = 6;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::fixed << std::setprecision(precision) << val;
|
||||||
|
ret = ss.str();
|
||||||
|
}else if(type == 'd'){
|
||||||
|
ret = std::to_string(CAST(i64, obj));
|
||||||
|
}else if(type == 's'){
|
||||||
|
ret = CAST(Str&, obj);
|
||||||
|
}else{
|
||||||
|
ret = CAST(Str&, asStr(obj));
|
||||||
|
}
|
||||||
|
if(width > ret.length()){
|
||||||
|
int pad = width - ret.length();
|
||||||
|
std::string padding(pad, ' ');
|
||||||
|
if(align == '>') ret = padding.c_str() + ret;
|
||||||
|
else ret = ret + padding.c_str();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
inline PyObject* VM::new_module(StrName name) {
|
inline PyObject* VM::new_module(StrName name) {
|
||||||
PyObject* obj = heap._new<DummyModule>(tp_module, DummyModule());
|
PyObject* obj = heap._new<DummyModule>(tp_module, DummyModule());
|
||||||
obj->attr().set(__name__, VAR(name.sv()));
|
obj->attr().set(__name__, VAR(name.sv()));
|
||||||
|
|||||||
@ -17,12 +17,29 @@ asds1321321321测试\测试'''
|
|||||||
|
|
||||||
assert s == 'asdasd\nasds1321321321测试\\测试'
|
assert s == 'asdasd\nasds1321321321测试\\测试'
|
||||||
|
|
||||||
assert f'123{2*2}56789' == '123456789'
|
t = 4
|
||||||
|
assert f'123{t}56789' == '123456789'
|
||||||
|
|
||||||
|
b = 123
|
||||||
s = f'''->->{s}<-<-
|
s = f'''->->{s}<-<-
|
||||||
{123}
|
{b}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
assert s == '->->asdasd\nasds1321321321测试\\测试<-<-\n123\n'
|
assert s == '->->asdasd\nasds1321321321测试\\测试<-<-\n123\n'
|
||||||
|
|
||||||
assert r''' ' ''' == " ' "
|
assert r''' ' ''' == " ' "
|
||||||
|
|
||||||
|
a = 10
|
||||||
|
assert f'{a}' == '10'
|
||||||
|
assert f'{a:>10}' == ' 10'
|
||||||
|
assert f'{a:<10}' == '10 '
|
||||||
|
assert f'{a:<10.2f}' == '10.00 '
|
||||||
|
assert f'{a:>10.2f}' == ' 10.00'
|
||||||
|
assert f'{a:3d}' == ' 10'
|
||||||
|
assert f'{a:10d}' == ' 10'
|
||||||
|
assert f'{a:1d}' == '10'
|
||||||
|
b = '123'
|
||||||
|
assert f'{b:10}' == '123 '
|
||||||
|
assert f'{b:>10}' == ' 123'
|
||||||
|
assert f'{b:1}' == '123'
|
||||||
|
assert f'{b:10s}' == '123 '
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user