mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
move str.join | add partial support of tuple
This commit is contained in:
parent
daf192b356
commit
a4dc943c7b
@ -4,20 +4,11 @@ const char* __BUILTINS_CODE = R"(
|
||||
def len(x):
|
||||
return x.__len__()
|
||||
|
||||
def __str4join(self, seq):
|
||||
s = ""
|
||||
for i in seq:
|
||||
s += str(i) + self # in Python3, it uses 'i' instead of 'str(i)'
|
||||
if len(self) > 0:
|
||||
s = s[:-len(self)]
|
||||
return s
|
||||
str.join = __str4join
|
||||
|
||||
def __str4__mul__(self, n):
|
||||
s = ""
|
||||
a = []
|
||||
for i in range(n):
|
||||
s += self
|
||||
return s
|
||||
a.append(self)
|
||||
return ''.join(a)
|
||||
str.__mul__ = __str4__mul__
|
||||
|
||||
def __str4split(self, sep):
|
||||
@ -40,9 +31,16 @@ def __list4__str__(self):
|
||||
a = []
|
||||
for i in self:
|
||||
a.append(str(i))
|
||||
return "[" + ", ".join(a) + "]"
|
||||
return '[' + ', '.join(a) + ']'
|
||||
list.__str__ = __list4__str__
|
||||
|
||||
def __tuple4__str__(self):
|
||||
a = []
|
||||
for i in self:
|
||||
a.append(str(i))
|
||||
return '(' + ', '.join(a) + ')'
|
||||
tuple.__str__ = __tuple4__str__
|
||||
|
||||
def __list4extend(self, other):
|
||||
for i in other:
|
||||
self.append(i)
|
||||
@ -91,7 +89,7 @@ class dict:
|
||||
if self._a[i][0] == key:
|
||||
return [True, i]
|
||||
i = ((5*i) + 1) % self._capacity
|
||||
return [False, i]
|
||||
return False,i
|
||||
|
||||
def __getitem__(self, key):
|
||||
ret = self.__probe(key)
|
||||
|
@ -72,12 +72,12 @@ public:
|
||||
|
||||
// http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||
#define METHOD(name) &Compiler::name
|
||||
#define NO_INFIX PREC_NONE
|
||||
for(_TokenType i=0; i<__TOKENS_LEN; i++) rules[i] = { nullptr, nullptr, PREC_NONE };
|
||||
#define NO_INFIX nullptr, PREC_NONE
|
||||
for(_TokenType i=0; i<__TOKENS_LEN; i++) rules[i] = { nullptr, NO_INFIX };
|
||||
rules[TK(".")] = { nullptr, METHOD(exprAttrib), PREC_ATTRIB };
|
||||
rules[TK("(")] = { METHOD(exprGrouping), METHOD(exprCall), PREC_CALL };
|
||||
rules[TK("[")] = { METHOD(exprList), METHOD(exprSubscript), PREC_SUBSCRIPT };
|
||||
rules[TK("{")] = { METHOD(exprMap), nullptr, NO_INFIX };
|
||||
rules[TK("{")] = { METHOD(exprMap), NO_INFIX };
|
||||
rules[TK("%")] = { nullptr, METHOD(exprBinaryOp), PREC_FACTOR };
|
||||
rules[TK("+")] = { nullptr, METHOD(exprBinaryOp), PREC_TERM };
|
||||
rules[TK("-")] = { METHOD(exprUnaryOp), METHOD(exprBinaryOp), PREC_TERM };
|
||||
@ -91,8 +91,6 @@ public:
|
||||
rules[TK("!=")] = { nullptr, METHOD(exprBinaryOp), PREC_EQUALITY };
|
||||
rules[TK(">=")] = { nullptr, METHOD(exprBinaryOp), PREC_COMPARISION };
|
||||
rules[TK("<=")] = { nullptr, METHOD(exprBinaryOp), PREC_COMPARISION };
|
||||
rules[TK("lambda")] = { METHOD(exprLambda), nullptr, NO_INFIX };
|
||||
rules[TK("None")] = { METHOD(exprValue), nullptr, NO_INFIX };
|
||||
rules[TK("in")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
|
||||
rules[TK("is")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
|
||||
rules[TK("not in")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
|
||||
@ -100,11 +98,13 @@ public:
|
||||
rules[TK("and") ] = { nullptr, METHOD(exprAnd), PREC_LOGICAL_AND };
|
||||
rules[TK("or")] = { nullptr, METHOD(exprOr), PREC_LOGICAL_OR };
|
||||
rules[TK("not")] = { METHOD(exprUnaryOp), nullptr, PREC_UNARY };
|
||||
rules[TK("True")] = { METHOD(exprValue), nullptr, NO_INFIX };
|
||||
rules[TK("False")] = { METHOD(exprValue), nullptr, NO_INFIX };
|
||||
rules[TK("@id")] = { METHOD(exprName), nullptr, NO_INFIX };
|
||||
rules[TK("@num")] = { METHOD(exprLiteral), nullptr, NO_INFIX };
|
||||
rules[TK("@str")] = { METHOD(exprLiteral), nullptr, NO_INFIX };
|
||||
rules[TK("True")] = { METHOD(exprValue), NO_INFIX };
|
||||
rules[TK("False")] = { METHOD(exprValue), NO_INFIX };
|
||||
rules[TK("lambda")] = { METHOD(exprLambda), NO_INFIX };
|
||||
rules[TK("None")] = { METHOD(exprValue), NO_INFIX };
|
||||
rules[TK("@id")] = { METHOD(exprName), NO_INFIX };
|
||||
rules[TK("@num")] = { METHOD(exprLiteral), NO_INFIX };
|
||||
rules[TK("@str")] = { METHOD(exprLiteral), NO_INFIX };
|
||||
#undef METHOD
|
||||
#undef NO_INFIX
|
||||
}
|
||||
@ -313,7 +313,7 @@ public:
|
||||
_TokenType assignment = parser->previous.type;
|
||||
matchNewLines();
|
||||
if (assignment == TK("=")) { // name = (expr);
|
||||
compileExpression();
|
||||
compileExpressionTuple();
|
||||
} else { // name += / -= / *= ... = (expr);
|
||||
emitCode(OP_LOAD_NAME, index);
|
||||
compileExpression();
|
||||
@ -392,7 +392,7 @@ public:
|
||||
|
||||
void exprGrouping() {
|
||||
matchNewLines();
|
||||
compileExpression();
|
||||
compileExpressionTuple();
|
||||
matchNewLines();
|
||||
consume(TK(")"));
|
||||
}
|
||||
@ -442,7 +442,7 @@ public:
|
||||
compileExpression();
|
||||
emitAssignOp(assignment);
|
||||
} else {
|
||||
compileExpression();
|
||||
compileExpressionTuple();
|
||||
}
|
||||
emitCode(OP_STORE_ATTR, index);
|
||||
} else {
|
||||
@ -488,7 +488,7 @@ public:
|
||||
if (assignment != TK("=")) {
|
||||
UNREACHABLE();
|
||||
} else {
|
||||
compileExpression();
|
||||
compileExpressionTuple();
|
||||
}
|
||||
emitCode(OP_STORE_SUBSCR);
|
||||
} else {
|
||||
@ -593,6 +593,17 @@ public:
|
||||
parsePrecedence(PREC_LOWEST);
|
||||
}
|
||||
|
||||
// Compiles an expression. Support tuple syntax.
|
||||
void compileExpressionTuple() {
|
||||
int size = 0;
|
||||
while (true) {
|
||||
compileExpression();
|
||||
size++;
|
||||
if (!match(TK(","))) break;
|
||||
}
|
||||
if(size > 1) emitCode(OP_BUILD_TUPLE, size);
|
||||
}
|
||||
|
||||
void compileIfStatement() {
|
||||
matchNewLines();
|
||||
compileExpression(); //< Condition.
|
||||
@ -642,7 +653,7 @@ public:
|
||||
const _Str& iterName = parser->previous.str();
|
||||
int iterIndex = getCode()->addName(iterName);
|
||||
consume(TK("in"));
|
||||
compileExpression();
|
||||
compileExpressionTuple();
|
||||
emitCode(OP_GET_ITER);
|
||||
Loop& loop = enterLoop(true);
|
||||
int patch = emitCode(OP_FOR_ITER);
|
||||
@ -672,7 +683,7 @@ public:
|
||||
if(matchEndStatement()){
|
||||
emitCode(OP_LOAD_NONE);
|
||||
}else{
|
||||
compileExpression();
|
||||
compileExpressionTuple();
|
||||
consumeEndStatement();
|
||||
}
|
||||
emitCode(OP_RETURN_VALUE);
|
||||
@ -706,7 +717,7 @@ public:
|
||||
} else if(match(TK("pass"))){
|
||||
consumeEndStatement();
|
||||
} else {
|
||||
compileExpression();
|
||||
compileExpressionTuple();
|
||||
consumeEndStatement();
|
||||
|
||||
// If last op is not an assignment, pop the result.
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <chrono>
|
||||
#include "pocketpy.h"
|
||||
|
||||
//#define PK_DEBUG
|
||||
#define PK_DEBUG
|
||||
//#define PK_DEBUG_TIME
|
||||
|
||||
class Timer{
|
||||
|
@ -26,7 +26,7 @@ constexpr const char* __TOKENS[] = {
|
||||
|
||||
const _TokenType __TOKENS_LEN = sizeof(__TOKENS) / sizeof(__TOKENS[0]);
|
||||
|
||||
constexpr _TokenType __tokenIndex(const char* token) {
|
||||
constexpr _TokenType TK(const char* const token) {
|
||||
for(int k=0; k<__TOKENS_LEN; k++){
|
||||
const char* i = __TOKENS[k];
|
||||
const char* j = token;
|
||||
@ -38,12 +38,10 @@ constexpr _TokenType __tokenIndex(const char* token) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define TK(s) __tokenIndex(s)
|
||||
#define TK_STR(t) __TOKENS[t]
|
||||
|
||||
const _TokenType __KW_BEGIN = __tokenIndex("class");
|
||||
const _TokenType __KW_END = __tokenIndex("raise");
|
||||
const _TokenType __KW_BEGIN = TK("class");
|
||||
const _TokenType __KW_END = TK("raise");
|
||||
|
||||
const std::unordered_map<std::string_view, _TokenType> __KW_MAP = [](){
|
||||
std::unordered_map<std::string_view, _TokenType> map;
|
||||
|
@ -277,6 +277,17 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
||||
return vm->PyBool(_self.str().rfind(_suffix.str()) == _self.str().length() - _suffix.str().length());
|
||||
});
|
||||
|
||||
_vm->bindMethod("str", "join", [](VM* vm, PyVarList args) {
|
||||
const _Str& _self = vm->PyStr_AS_C(args[0]);
|
||||
const PyVarList& _list = vm->PyList_AS_C(args[1]);
|
||||
_StrStream ss;
|
||||
for(int i = 0; i < _list.size(); i++){
|
||||
if(i > 0) ss << _self;
|
||||
ss << vm->PyStr_AS_C(vm->asStr(_list[i]));
|
||||
}
|
||||
return vm->PyStr(ss);
|
||||
});
|
||||
|
||||
/************ PyList ************/
|
||||
_vm->bindMethod("list", "__iter__", [](VM* vm, PyVarList args) {
|
||||
vm->__checkType(args.at(0), vm->_tp_list);
|
||||
|
Loading…
x
Reference in New Issue
Block a user