pocketpy.cpp 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743
  1. #include "pocketpy/pocketpy.h"
  2. namespace pkpy{
  3. #ifdef PK_USE_CJSON
  4. void add_module_cjson(VM* vm);
  5. #endif
  6. void init_builtins(VM* _vm) {
  7. #define BIND_NUM_ARITH_OPT(name, op) \
  8. _vm->bind##name(VM::tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
  9. if(is_int(rhs)) return VAR(_CAST(i64, lhs) op _CAST(i64, rhs)); \
  10. if(is_float(rhs)) return VAR(_CAST(i64, lhs) op _CAST(f64, rhs)); \
  11. return vm->NotImplemented; \
  12. }); \
  13. _vm->bind##name(VM::tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
  14. if(is_float(rhs)) return VAR(_CAST(f64, lhs) op _CAST(f64, rhs)); \
  15. if(is_int(rhs)) return VAR(_CAST(f64, lhs) op _CAST(i64, rhs)); \
  16. return vm->NotImplemented; \
  17. });
  18. BIND_NUM_ARITH_OPT(__add__, +)
  19. BIND_NUM_ARITH_OPT(__sub__, -)
  20. BIND_NUM_ARITH_OPT(__mul__, *)
  21. #undef BIND_NUM_ARITH_OPT
  22. #define BIND_NUM_LOGICAL_OPT(name, op) \
  23. _vm->bind##name(VM::tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
  24. i64 val; \
  25. if(try_cast_int(rhs, &val)) return VAR(_CAST(i64, lhs) op val); \
  26. if(is_float(rhs)) return VAR(_CAST(i64, lhs) op _CAST(f64, rhs)); \
  27. return vm->NotImplemented; \
  28. }); \
  29. _vm->bind##name(VM::tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
  30. i64 val; \
  31. if(try_cast_int(rhs, &val)) return VAR(_CAST(f64, lhs) op val); \
  32. if(is_float(rhs)) return VAR(_CAST(f64, lhs) op _CAST(f64, rhs)); \
  33. return vm->NotImplemented; \
  34. });
  35. BIND_NUM_LOGICAL_OPT(__eq__, ==)
  36. BIND_NUM_LOGICAL_OPT(__lt__, <)
  37. BIND_NUM_LOGICAL_OPT(__le__, <=)
  38. BIND_NUM_LOGICAL_OPT(__gt__, >)
  39. BIND_NUM_LOGICAL_OPT(__ge__, >=)
  40. #undef BIND_NUM_ARITH_OPT
  41. #undef BIND_NUM_LOGICAL_OPT
  42. // builtin functions
  43. _vm->bind_func<-1>(_vm->builtins, "super", [](VM* vm, ArgsView args) {
  44. PyObject* class_arg = nullptr;
  45. PyObject* self_arg = nullptr;
  46. if(args.size() == 2){
  47. class_arg = args[0];
  48. self_arg = args[1];
  49. }else if(args.size() == 0){
  50. FrameId frame = vm->top_frame();
  51. if(frame->_callable != nullptr){
  52. class_arg = PK_OBJ_GET(Function, frame->_callable)._class;
  53. if(frame->_locals.size() > 0) self_arg = frame->_locals[0];
  54. }
  55. if(class_arg == nullptr || self_arg == nullptr){
  56. vm->TypeError("super(): unable to determine the class context, use super(class, self) instead");
  57. }
  58. }else{
  59. vm->TypeError("super() takes 0 or 2 arguments");
  60. }
  61. vm->check_non_tagged_type(class_arg, vm->tp_type);
  62. Type type = PK_OBJ_GET(Type, class_arg);
  63. if(!vm->isinstance(self_arg, type)){
  64. StrName _0 = _type_name(vm, vm->_tp(self_arg));
  65. StrName _1 = _type_name(vm, type);
  66. vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape());
  67. }
  68. return vm->heap.gcnew<Super>(vm->tp_super, self_arg, vm->_all_types[type].base);
  69. });
  70. _vm->bind_func<1>(_vm->builtins, "staticmethod", [](VM* vm, ArgsView args) {
  71. PyObject* func = args[0];
  72. vm->check_non_tagged_type(func, vm->tp_function);
  73. return vm->heap.gcnew<StaticMethod>(vm->tp_staticmethod, args[0]);
  74. });
  75. _vm->bind_func<1>(_vm->builtins, "classmethod", [](VM* vm, ArgsView args) {
  76. PyObject* func = args[0];
  77. vm->check_non_tagged_type(func, vm->tp_function);
  78. return vm->heap.gcnew<ClassMethod>(vm->tp_classmethod, args[0]);
  79. });
  80. _vm->bind_func<2>(_vm->builtins, "isinstance", [](VM* vm, ArgsView args) {
  81. if(is_non_tagged_type(args[1], vm->tp_tuple)){
  82. Tuple& types = _CAST(Tuple&, args[1]);
  83. for(PyObject* type : types){
  84. vm->check_non_tagged_type(type, vm->tp_type);
  85. if(vm->isinstance(args[0], PK_OBJ_GET(Type, type))) return vm->True;
  86. }
  87. return vm->False;
  88. }
  89. vm->check_non_tagged_type(args[1], vm->tp_type);
  90. Type type = PK_OBJ_GET(Type, args[1]);
  91. return VAR(vm->isinstance(args[0], type));
  92. });
  93. _vm->bind_func<2>(_vm->builtins, "issubclass", [](VM* vm, ArgsView args) {
  94. vm->check_non_tagged_type(args[0], vm->tp_type);
  95. vm->check_non_tagged_type(args[1], vm->tp_type);
  96. return VAR(vm->issubclass(PK_OBJ_GET(Type, args[0]), PK_OBJ_GET(Type, args[1])));
  97. });
  98. _vm->bind_func<0>(_vm->builtins, "globals", [](VM* vm, ArgsView args) {
  99. PyObject* mod = vm->top_frame()->_module;
  100. return VAR(MappingProxy(mod));
  101. });
  102. _vm->bind(_vm->builtins, "round(x, ndigits=0)", [](VM* vm, ArgsView args) {
  103. f64 x = CAST(f64, args[0]);
  104. int ndigits = CAST(int, args[1]);
  105. if(ndigits == 0){
  106. return x >= 0 ? VAR((i64)(x + 0.5)) : VAR((i64)(x - 0.5));
  107. }
  108. if(ndigits < 0) vm->ValueError("ndigits should be non-negative");
  109. if(x >= 0){
  110. return VAR((i64)(x * std::pow(10, ndigits) + 0.5) / std::pow(10, ndigits));
  111. }else{
  112. return VAR((i64)(x * std::pow(10, ndigits) - 0.5) / std::pow(10, ndigits));
  113. }
  114. });
  115. _vm->bind_func<1>(_vm->builtins, "abs", [](VM* vm, ArgsView args) {
  116. if(is_int(args[0])) return VAR(std::abs(_CAST(i64, args[0])));
  117. if(is_float(args[0])) return VAR(std::abs(_CAST(f64, args[0])));
  118. vm->TypeError("bad operand type for abs()");
  119. return vm->None;
  120. });
  121. _vm->bind_func<1>(_vm->builtins, "id", [](VM* vm, ArgsView args) {
  122. PyObject* obj = args[0];
  123. if(is_tagged(obj)) return vm->None;
  124. return VAR(PK_BITS(obj));
  125. });
  126. _vm->bind_func<1>(_vm->builtins, "callable", [](VM* vm, ArgsView args) {
  127. Type cls = vm->_tp(args[0]);
  128. switch(cls.index){
  129. case VM::tp_function.index: return vm->True;
  130. case VM::tp_native_func.index: return vm->True;
  131. case VM::tp_bound_method.index: return vm->True;
  132. case VM::tp_type.index: return vm->True;
  133. }
  134. bool ok = vm->find_name_in_mro(cls, __call__) != nullptr;
  135. return VAR(ok);
  136. });
  137. _vm->bind_func<1>(_vm->builtins, "__import__", [](VM* vm, ArgsView args) {
  138. const Str& name = CAST(Str&, args[0]);
  139. return vm->py_import(name);
  140. });
  141. _vm->bind_func<2>(_vm->builtins, "divmod", [](VM* vm, ArgsView args) {
  142. if(is_int(args[0])){
  143. i64 lhs = _CAST(i64, args[0]);
  144. i64 rhs = CAST(i64, args[1]);
  145. if(rhs == 0) vm->ZeroDivisionError();
  146. auto res = std::div(lhs, rhs);
  147. return VAR(Tuple({VAR(res.quot), VAR(res.rem)}));
  148. }else{
  149. return vm->call_method(args[0], __divmod__, args[1]);
  150. }
  151. });
  152. _vm->bind(_vm->builtins, "eval(__source, __globals=None)", [](VM* vm, ArgsView args) {
  153. CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE, true);
  154. PyObject* globals = args[1];
  155. if(globals == vm->None){
  156. FrameId frame = vm->top_frame();
  157. return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
  158. }
  159. vm->check_non_tagged_type(globals, vm->tp_mappingproxy);
  160. PyObject* obj = PK_OBJ_GET(MappingProxy, globals).obj;
  161. return vm->_exec(code, obj);
  162. });
  163. _vm->bind(_vm->builtins, "exec(__source, __globals=None)", [](VM* vm, ArgsView args) {
  164. CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE, true);
  165. PyObject* globals = args[1];
  166. if(globals == vm->None){
  167. FrameId frame = vm->top_frame();
  168. vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
  169. return vm->None;
  170. }
  171. vm->check_non_tagged_type(globals, vm->tp_mappingproxy);
  172. PyObject* obj = PK_OBJ_GET(MappingProxy, globals).obj;
  173. vm->_exec(code, obj);
  174. return vm->None;
  175. });
  176. _vm->bind(_vm->builtins, "exit(code=0)", [](VM* vm, ArgsView args) {
  177. std::exit(CAST(int, args[0]));
  178. return vm->None;
  179. });
  180. _vm->bind_func<1>(_vm->builtins, "repr", [](VM* vm, ArgsView args){
  181. return vm->py_repr(args[0]);
  182. });
  183. _vm->bind_func<1>(_vm->builtins, "len", [](VM* vm, ArgsView args){
  184. const PyTypeInfo* ti = vm->_inst_type_info(args[0]);
  185. if(ti->m__len__) return VAR(ti->m__len__(vm, args[0]));
  186. return vm->call_method(args[0], __len__);
  187. });
  188. _vm->bind_func<1>(_vm->builtins, "hash", [](VM* vm, ArgsView args){
  189. i64 value = vm->py_hash(args[0]);
  190. return VAR(value);
  191. });
  192. _vm->bind_func<1>(_vm->builtins, "chr", [](VM* vm, ArgsView args) {
  193. i64 i = CAST(i64, args[0]);
  194. if (i < 0 || i >= 128) vm->ValueError("chr() arg not in [0, 128)");
  195. return VAR(std::string(1, (char)i));
  196. });
  197. _vm->bind_func<1>(_vm->builtins, "ord", [](VM* vm, ArgsView args) {
  198. const Str& s = CAST(Str&, args[0]);
  199. if (s.length()!=1) vm->TypeError("ord() expected an ASCII character");
  200. return VAR((i64)(s[0]));
  201. });
  202. _vm->bind_func<2>(_vm->builtins, "hasattr", [](VM* vm, ArgsView args) {
  203. return VAR(vm->getattr(args[0], CAST(Str&, args[1]), false) != nullptr);
  204. });
  205. _vm->bind_func<3>(_vm->builtins, "setattr", [](VM* vm, ArgsView args) {
  206. vm->setattr(args[0], CAST(Str&, args[1]), args[2]);
  207. return vm->None;
  208. });
  209. _vm->bind_func<-1>(_vm->builtins, "getattr", [](VM* vm, ArgsView args) {
  210. if(args.size()!=2 && args.size()!=3) vm->TypeError("getattr() takes 2 or 3 arguments");
  211. StrName name = CAST(Str&, args[1]);
  212. PyObject* val = vm->getattr(args[0], name, false);
  213. if(val == nullptr){
  214. if(args.size()==2) vm->AttributeError(args[0], name);
  215. return args[2];
  216. }
  217. return val;
  218. });
  219. _vm->bind_func<2>(_vm->builtins, "delattr", [](VM* vm, ArgsView args) {
  220. vm->delattr(args[0], CAST(Str&, args[1]));
  221. return vm->None;
  222. });
  223. _vm->bind_func<1>(_vm->builtins, "hex", [](VM* vm, ArgsView args) {
  224. std::stringstream ss; // hex
  225. ss << std::hex << CAST(i64, args[0]);
  226. return VAR("0x" + ss.str());
  227. });
  228. _vm->bind_func<1>(_vm->builtins, "iter", [](VM* vm, ArgsView args) {
  229. return vm->py_iter(args[0]);
  230. });
  231. _vm->bind_func<1>(_vm->builtins, "next", [](VM* vm, ArgsView args) {
  232. return vm->py_next(args[0]);
  233. });
  234. _vm->bind_func<1>(_vm->builtins, "bin", [](VM* vm, ArgsView args) {
  235. SStream ss;
  236. i64 x = CAST(i64, args[0]);
  237. if(x < 0){ ss << "-"; x = -x; }
  238. ss << "0b";
  239. std::string bits;
  240. while(x){
  241. bits += (x & 1) ? '1' : '0';
  242. x >>= 1;
  243. }
  244. std::reverse(bits.begin(), bits.end());
  245. if(bits.empty()) bits = "0";
  246. ss << bits;
  247. return VAR(ss.str());
  248. });
  249. _vm->bind_func<1>(_vm->builtins, "dir", [](VM* vm, ArgsView args) {
  250. std::set<StrName> names;
  251. if(!is_tagged(args[0]) && args[0]->is_attr_valid()){
  252. std::vector<StrName> keys = args[0]->attr().keys();
  253. names.insert(keys.begin(), keys.end());
  254. }
  255. const NameDict& t_attr = vm->_t(args[0])->attr();
  256. std::vector<StrName> keys = t_attr.keys();
  257. names.insert(keys.begin(), keys.end());
  258. List ret;
  259. for (StrName name : names) ret.push_back(VAR(name.sv()));
  260. return VAR(std::move(ret));
  261. });
  262. // tp_object
  263. _vm->bind__repr__(VM::tp_object, [](VM* vm, PyObject* obj) {
  264. if(is_tagged(obj)) PK_FATAL_ERROR();
  265. std::stringstream ss; // hex
  266. ss << "<" << OBJ_NAME(vm->_t(obj)) << " object at 0x";
  267. ss << std::hex << reinterpret_cast<intptr_t>(obj) << ">";
  268. return VAR(ss.str());
  269. });
  270. _vm->bind__eq__(VM::tp_object, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  271. return VAR(lhs == rhs);
  272. });
  273. _vm->cached_object__new__ = _vm->bind_constructor<1>(_vm->_t(VM::tp_object), [](VM* vm, ArgsView args) {
  274. vm->check_non_tagged_type(args[0], vm->tp_type);
  275. Type t = PK_OBJ_GET(Type, args[0]);
  276. return vm->heap.gcnew<DummyInstance>(t);
  277. });
  278. _vm->bind_method<0>(VM::tp_object, "_enable_instance_dict", [](VM* vm, ArgsView args){
  279. PyObject* self = args[0];
  280. if(is_tagged(self)){
  281. vm->TypeError("object: tagged object cannot enable instance dict");
  282. }
  283. if(self->is_attr_valid()){
  284. vm->TypeError("object: instance dict is already enabled");
  285. }
  286. self->_enable_instance_dict();
  287. return vm->None;
  288. });
  289. // tp_type
  290. _vm->bind_constructor<2>(_vm->_t(VM::tp_type), PK_LAMBDA(vm->_t(args[1])));
  291. // tp_range
  292. _vm->bind_constructor<-1>(_vm->_t(VM::tp_range), [](VM* vm, ArgsView args) {
  293. args._begin += 1; // skip cls
  294. Range r;
  295. switch (args.size()) {
  296. case 1: r.stop = CAST(i64, args[0]); break;
  297. case 2: r.start = CAST(i64, args[0]); r.stop = CAST(i64, args[1]); break;
  298. case 3: r.start = CAST(i64, args[0]); r.stop = CAST(i64, args[1]); r.step = CAST(i64, args[2]); break;
  299. default: vm->TypeError("expected 1-3 arguments, got " + std::to_string(args.size()));
  300. }
  301. return VAR(r);
  302. });
  303. _vm->bind__iter__(VM::tp_range, [](VM* vm, PyObject* obj) { return VAR_T(RangeIter, PK_OBJ_GET(Range, obj)); });
  304. // tp_nonetype
  305. _vm->bind__repr__(_vm->_tp(_vm->None), [](VM* vm, PyObject* obj) {
  306. return VAR("None");
  307. });
  308. // tp_float / tp_float
  309. _vm->bind__truediv__(VM::tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  310. f64 value = CAST_F(rhs);
  311. return VAR(_CAST(f64, lhs) / value);
  312. });
  313. _vm->bind__truediv__(VM::tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  314. f64 value = CAST_F(rhs);
  315. return VAR(_CAST(i64, lhs) / value);
  316. });
  317. auto py_number_pow = [](VM* vm, PyObject* lhs_, PyObject* rhs_) {
  318. i64 lhs, rhs;
  319. if(try_cast_int(lhs_, &lhs) && try_cast_int(rhs_, &rhs)){
  320. if(rhs < 0) {
  321. if(lhs == 0) vm->ZeroDivisionError("0.0 cannot be raised to a negative power");
  322. return VAR((f64)std::pow(lhs, rhs));
  323. }
  324. i64 ret = 1;
  325. while(rhs){
  326. if(rhs & 1) ret *= lhs;
  327. lhs *= lhs;
  328. rhs >>= 1;
  329. }
  330. return VAR(ret);
  331. }else{
  332. return VAR((f64)std::pow(CAST_F(lhs_), CAST_F(rhs_)));
  333. }
  334. };
  335. _vm->bind__pow__(VM::tp_int, py_number_pow);
  336. _vm->bind__pow__(VM::tp_float, py_number_pow);
  337. _vm->bind_constructor<-1>(_vm->_t(VM::tp_int), [](VM* vm, ArgsView args) {
  338. if(args.size() == 1+0) return VAR(0);
  339. // 1 arg
  340. if(args.size() == 1+1){
  341. if (is_type(args[1], vm->tp_float)) return VAR((i64)CAST(f64, args[1]));
  342. if (is_type(args[1], vm->tp_int)) return args[1];
  343. if (is_type(args[1], vm->tp_bool)) return VAR(_CAST(bool, args[1]) ? 1 : 0);
  344. }
  345. if(args.size() > 1+2) vm->TypeError("int() takes at most 2 arguments");
  346. // 2 args
  347. if (is_type(args[1], vm->tp_str)) {
  348. int base = 10;
  349. if(args.size() == 1+2) base = CAST(i64, args[2]);
  350. const Str& s = CAST(Str&, args[1]);
  351. i64 val;
  352. if(!parse_int(s.sv(), &val, base)){
  353. vm->ValueError("invalid literal for int(): " + s.escape());
  354. }
  355. return VAR(val);
  356. }
  357. vm->TypeError("invalid arguments for int()");
  358. return vm->None;
  359. });
  360. _vm->bind__floordiv__(VM::tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) {
  361. i64 rhs = CAST(i64, rhs_);
  362. if(rhs == 0) vm->ZeroDivisionError();
  363. return VAR(_CAST(i64, lhs_) / rhs);
  364. });
  365. _vm->bind__mod__(VM::tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) {
  366. i64 rhs = CAST(i64, rhs_);
  367. if(rhs == 0) vm->ZeroDivisionError();
  368. return VAR(_CAST(i64, lhs_) % rhs);
  369. });
  370. _vm->bind__repr__(VM::tp_int, [](VM* vm, PyObject* obj) { return VAR(std::to_string(_CAST(i64, obj))); });
  371. _vm->bind__neg__(VM::tp_int, [](VM* vm, PyObject* obj) { return VAR(-_CAST(i64, obj)); });
  372. _vm->bind__hash__(VM::tp_int, [](VM* vm, PyObject* obj) { return _CAST(i64, obj); });
  373. _vm->bind__invert__(VM::tp_int, [](VM* vm, PyObject* obj) { return VAR(~_CAST(i64, obj)); });
  374. #define INT_BITWISE_OP(name, op) \
  375. _vm->bind##name(VM::tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
  376. return VAR(_CAST(i64, lhs) op CAST(i64, rhs)); \
  377. });
  378. INT_BITWISE_OP(__lshift__, <<)
  379. INT_BITWISE_OP(__rshift__, >>)
  380. INT_BITWISE_OP(__and__, &)
  381. INT_BITWISE_OP(__or__, |)
  382. INT_BITWISE_OP(__xor__, ^)
  383. #undef INT_BITWISE_OP
  384. _vm->bind_constructor<-1>(_vm->_t(VM::tp_float), [](VM* vm, ArgsView args) {
  385. if(args.size() == 1+0) return VAR(0.0);
  386. if(args.size() > 1+1) vm->TypeError("float() takes at most 1 argument");
  387. // 1 arg
  388. if (is_type(args[1], vm->tp_int)) return VAR((f64)CAST(i64, args[1]));
  389. if (is_type(args[1], vm->tp_float)) return args[1];
  390. if (is_type(args[1], vm->tp_bool)) return VAR(_CAST(bool, args[1]) ? 1.0 : 0.0);
  391. if (is_type(args[1], vm->tp_str)) {
  392. const Str& s = CAST(Str&, args[1]);
  393. if(s == "inf") return VAR(INFINITY);
  394. if(s == "-inf") return VAR(-INFINITY);
  395. double float_out;
  396. char* p_end;
  397. try{
  398. float_out = std::strtod(s.data, &p_end);
  399. PK_ASSERT(p_end == s.end());
  400. }catch(...){
  401. vm->ValueError("invalid literal for float(): " + s.escape());
  402. }
  403. return VAR(float_out);
  404. }
  405. vm->TypeError("invalid arguments for float()");
  406. return vm->None;
  407. });
  408. _vm->bind__hash__(VM::tp_float, [](VM* vm, PyObject* obj) {
  409. f64 val = _CAST(f64, obj);
  410. return (i64)std::hash<f64>()(val);
  411. });
  412. _vm->bind__neg__(VM::tp_float, [](VM* vm, PyObject* obj) { return VAR(-_CAST(f64, obj)); });
  413. _vm->bind__repr__(VM::tp_float, [](VM* vm, PyObject* obj) {
  414. f64 val = _CAST(f64, obj);
  415. SStream ss;
  416. ss << val;
  417. return VAR(ss.str());
  418. });
  419. // tp_str
  420. _vm->bind_constructor<2>(_vm->_t(VM::tp_str), PK_LAMBDA(vm->py_str(args[1])));
  421. _vm->bind__hash__(VM::tp_str, [](VM* vm, PyObject* obj) {
  422. return (i64)_CAST(Str&, obj).hash();
  423. });
  424. _vm->bind__add__(VM::tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  425. return VAR(_CAST(Str&, lhs) + CAST(Str&, rhs));
  426. });
  427. _vm->bind__len__(VM::tp_str, [](VM* vm, PyObject* obj) {
  428. return (i64)_CAST(Str&, obj).u8_length();
  429. });
  430. _vm->bind__mul__(VM::tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  431. const Str& self = _CAST(Str&, lhs);
  432. i64 n = CAST(i64, rhs);
  433. SStream ss;
  434. for(i64 i = 0; i < n; i++) ss << self.sv();
  435. return VAR(ss.str());
  436. });
  437. _vm->bind_method<1>(VM::tp_str, "__rmul__", [](VM* vm, ArgsView args) {
  438. const Str& self = _CAST(Str&, args[0]);
  439. i64 n = CAST(i64, args[1]);
  440. SStream ss;
  441. for(i64 i = 0; i < n; i++) ss << self.sv();
  442. return VAR(ss.str());
  443. });
  444. _vm->bind__contains__(VM::tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  445. const Str& self = _CAST(Str&, lhs);
  446. return VAR(self.index(CAST(Str&, rhs)) != -1);
  447. });
  448. _vm->bind__str__(VM::tp_str, [](VM* vm, PyObject* obj) { return obj; });
  449. _vm->bind__iter__(VM::tp_str, [](VM* vm, PyObject* obj) { return VAR_T(StringIter, obj); });
  450. _vm->bind__repr__(VM::tp_str, [](VM* vm, PyObject* obj) {
  451. const Str& self = _CAST(Str&, obj);
  452. return VAR(self.escape(true));
  453. });
  454. #define BIND_CMP_STR(name, op) \
  455. _vm->bind##name(VM::tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
  456. if(!is_non_tagged_type(rhs, vm->tp_str)) return vm->NotImplemented; \
  457. return VAR(_CAST(Str&, lhs) op _CAST(Str&, rhs)); \
  458. });
  459. BIND_CMP_STR(__eq__, ==)
  460. BIND_CMP_STR(__lt__, <)
  461. BIND_CMP_STR(__le__, <=)
  462. BIND_CMP_STR(__gt__, >)
  463. BIND_CMP_STR(__ge__, >=)
  464. #undef BIND_CMP_STR
  465. _vm->bind__getitem__(VM::tp_str, [](VM* vm, PyObject* obj, PyObject* index) {
  466. const Str& self = _CAST(Str&, obj);
  467. if(is_non_tagged_type(index, vm->tp_slice)){
  468. const Slice& s = _CAST(Slice&, index);
  469. int start, stop, step;
  470. vm->parse_int_slice(s, self.u8_length(), start, stop, step);
  471. return VAR(self.u8_slice(start, stop, step));
  472. }
  473. int i = CAST(int, index);
  474. i = vm->normalized_index(i, self.u8_length());
  475. return VAR(self.u8_getitem(i));
  476. });
  477. _vm->bind(_vm->_t(VM::tp_str), "replace(self, old, new, count=-1)", [](VM* vm, ArgsView args) {
  478. const Str& self = _CAST(Str&, args[0]);
  479. const Str& old = CAST(Str&, args[1]);
  480. if(old.empty()) vm->ValueError("empty substring");
  481. const Str& new_ = CAST(Str&, args[2]);
  482. int count = CAST(int, args[3]);
  483. return VAR(self.replace(old, new_, count));
  484. });
  485. _vm->bind(_vm->_t(VM::tp_str), "split(self, sep=' ')", [](VM* vm, ArgsView args) {
  486. const Str& self = _CAST(Str&, args[0]);
  487. const Str& sep = CAST(Str&, args[1]);
  488. if(sep.empty()) vm->ValueError("empty separator");
  489. std::vector<std::string_view> parts;
  490. if(sep.size == 1){
  491. parts = self.split(sep[0]);
  492. }else{
  493. parts = self.split(sep);
  494. }
  495. List ret(parts.size());
  496. for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i]));
  497. return VAR(std::move(ret));
  498. });
  499. _vm->bind(_vm->_t(VM::tp_str), "splitlines(self)", [](VM* vm, ArgsView args) {
  500. const Str& self = _CAST(Str&, args[0]);
  501. std::vector<std::string_view> parts;
  502. parts = self.split('\n');
  503. List ret(parts.size());
  504. for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i]));
  505. return VAR(std::move(ret));
  506. });
  507. _vm->bind(_vm->_t(VM::tp_str), "count(self, s: str)", [](VM* vm, ArgsView args) {
  508. const Str& self = _CAST(Str&, args[0]);
  509. const Str& s = CAST(Str&, args[1]);
  510. return VAR(self.count(s));
  511. });
  512. _vm->bind_method<1>(VM::tp_str, "index", [](VM* vm, ArgsView args) {
  513. const Str& self = _CAST(Str&, args[0]);
  514. const Str& sub = CAST(Str&, args[1]);
  515. int index = self.index(sub);
  516. if(index == -1) vm->ValueError("substring not found");
  517. return VAR(index);
  518. });
  519. _vm->bind_method<1>(VM::tp_str, "find", [](VM* vm, ArgsView args) {
  520. const Str& self = _CAST(Str&, args[0]);
  521. const Str& sub = CAST(Str&, args[1]);
  522. return VAR(self.index(sub));
  523. });
  524. _vm->bind_method<1>(VM::tp_str, "startswith", [](VM* vm, ArgsView args) {
  525. const Str& self = _CAST(Str&, args[0]);
  526. const Str& prefix = CAST(Str&, args[1]);
  527. return VAR(self.index(prefix) == 0);
  528. });
  529. _vm->bind_method<1>(VM::tp_str, "endswith", [](VM* vm, ArgsView args) {
  530. const Str& self = _CAST(Str&, args[0]);
  531. const Str& suffix = CAST(Str&, args[1]);
  532. int offset = self.length() - suffix.length();
  533. if(offset < 0) return vm->False;
  534. bool ok = memcmp(self.data+offset, suffix.data, suffix.length()) == 0;
  535. return VAR(ok);
  536. });
  537. _vm->bind_method<0>(VM::tp_str, "encode", [](VM* vm, ArgsView args) {
  538. const Str& self = _CAST(Str&, args[0]);
  539. unsigned char* buffer = new unsigned char[self.length()];
  540. memcpy(buffer, self.data, self.length());
  541. return VAR(Bytes(buffer, self.length()));
  542. });
  543. _vm->bind_method<1>(VM::tp_str, "join", [](VM* vm, ArgsView args) {
  544. auto _lock = vm->heap.gc_scope_lock();
  545. const Str& self = _CAST(Str&, args[0]);
  546. SStream ss;
  547. PyObject* it = vm->py_iter(args[1]); // strong ref
  548. PyObject* obj = vm->py_next(it);
  549. while(obj != vm->StopIteration){
  550. if(!ss.empty()) ss << self;
  551. ss << CAST(Str&, obj);
  552. obj = vm->py_next(it);
  553. }
  554. return VAR(ss.str());
  555. });
  556. _vm->bind_method<0>(VM::tp_str, "lower", [](VM* vm, ArgsView args) {
  557. const Str& self = _CAST(Str&, args[0]);
  558. return VAR(self.lower());
  559. });
  560. _vm->bind_method<0>(VM::tp_str, "upper", [](VM* vm, ArgsView args) {
  561. const Str& self = _CAST(Str&, args[0]);
  562. return VAR(self.upper());
  563. });
  564. // tp_list / tp_tuple
  565. _vm->bind(_vm->_t(VM::tp_list), "sort(self, key=None, reverse=False)", [](VM* vm, ArgsView args) {
  566. List& self = _CAST(List&, args[0]);
  567. PyObject* key = args[1];
  568. if(key == vm->None){
  569. std::stable_sort(self.begin(), self.end(), [vm](PyObject* a, PyObject* b){
  570. return vm->py_lt(a, b);
  571. });
  572. }else{
  573. std::stable_sort(self.begin(), self.end(), [vm, key](PyObject* a, PyObject* b){
  574. return vm->py_lt(vm->call(key, a), vm->call(key, b));
  575. });
  576. }
  577. bool reverse = CAST(bool, args[2]);
  578. if(reverse) self.reverse();
  579. return vm->None;
  580. });
  581. _vm->bind__repr__(VM::tp_list, [](VM* vm, PyObject* _0){
  582. List& iterable = _CAST(List&, _0);
  583. SStream ss;
  584. ss << '[';
  585. for(int i=0; i<iterable.size(); i++){
  586. ss << CAST(Str&, vm->py_repr(iterable[i]));
  587. if(i != iterable.size()-1) ss << ", ";
  588. }
  589. ss << ']';
  590. return VAR(ss.str());
  591. });
  592. _vm->bind__repr__(VM::tp_tuple, [](VM* vm, PyObject* _0){
  593. Tuple& iterable = _CAST(Tuple&, _0);
  594. SStream ss;
  595. ss << '(';
  596. if(iterable.size() == 1){
  597. ss << CAST(Str&, vm->py_repr(iterable[0]));
  598. ss << ',';
  599. }else{
  600. for(int i=0; i<iterable.size(); i++){
  601. ss << CAST(Str&, vm->py_repr(iterable[i]));
  602. if(i != iterable.size()-1) ss << ", ";
  603. }
  604. }
  605. ss << ')';
  606. return VAR(ss.str());
  607. });
  608. _vm->bind_constructor<-1>(_vm->_t(VM::tp_list), [](VM* vm, ArgsView args) {
  609. if(args.size() == 1+0) return VAR(List());
  610. if(args.size() == 1+1) return vm->py_list(args[1]);
  611. vm->TypeError("list() takes 0 or 1 arguments");
  612. return vm->None;
  613. });
  614. _vm->bind__contains__(VM::tp_list, [](VM* vm, PyObject* obj, PyObject* item) {
  615. List& self = _CAST(List&, obj);
  616. for(PyObject* i: self) if(vm->py_eq(i, item)) return vm->True;
  617. return vm->False;
  618. });
  619. _vm->bind_method<1>(VM::tp_list, "count", [](VM* vm, ArgsView args) {
  620. List& self = _CAST(List&, args[0]);
  621. int count = 0;
  622. for(PyObject* i: self) if(vm->py_eq(i, args[1])) count++;
  623. return VAR(count);
  624. });
  625. _vm->bind__eq__(VM::tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  626. List& a = _CAST(List&, lhs);
  627. if(!is_non_tagged_type(rhs, vm->tp_list)) return vm->NotImplemented;
  628. List& b = _CAST(List&, rhs);
  629. if(a.size() != b.size()) return vm->False;
  630. for(int i=0; i<a.size(); i++){
  631. if(!vm->py_eq(a[i], b[i])) return vm->False;
  632. }
  633. return vm->True;
  634. });
  635. _vm->bind_method<1>(VM::tp_list, "index", [](VM* vm, ArgsView args) {
  636. List& self = _CAST(List&, args[0]);
  637. PyObject* obj = args[1];
  638. for(int i=0; i<self.size(); i++){
  639. if(vm->py_eq(self[i], obj)) return VAR(i);
  640. }
  641. vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
  642. return vm->None;
  643. });
  644. _vm->bind_method<1>(VM::tp_list, "remove", [](VM* vm, ArgsView args) {
  645. List& self = _CAST(List&, args[0]);
  646. PyObject* obj = args[1];
  647. for(int i=0; i<self.size(); i++){
  648. if(vm->py_eq(self[i], obj)){
  649. self.erase(i);
  650. return vm->None;
  651. }
  652. }
  653. vm->ValueError(_CAST(Str&, vm->py_repr(obj)) + " is not in list");
  654. return vm->None;
  655. });
  656. _vm->bind_method<-1>(VM::tp_list, "pop", [](VM* vm, ArgsView args) {
  657. List& self = _CAST(List&, args[0]);
  658. if(args.size() == 1+0){
  659. if(self.empty()) vm->IndexError("pop from empty list");
  660. return self.popx_back();
  661. }
  662. if(args.size() == 1+1){
  663. int index = CAST(int, args[1]);
  664. index = vm->normalized_index(index, self.size());
  665. PyObject* ret = self[index];
  666. self.erase(index);
  667. return ret;
  668. }
  669. vm->TypeError("pop() takes at most 1 argument");
  670. return vm->None;
  671. });
  672. _vm->bind_method<1>(VM::tp_list, "append", [](VM* vm, ArgsView args) {
  673. List& self = _CAST(List&, args[0]);
  674. self.push_back(args[1]);
  675. return vm->None;
  676. });
  677. _vm->bind_method<1>(VM::tp_list, "extend", [](VM* vm, ArgsView args) {
  678. auto _lock = vm->heap.gc_scope_lock();
  679. List& self = _CAST(List&, args[0]);
  680. PyObject* it = vm->py_iter(args[1]); // strong ref
  681. PyObject* obj = vm->py_next(it);
  682. while(obj != vm->StopIteration){
  683. self.push_back(obj);
  684. obj = vm->py_next(it);
  685. }
  686. return vm->None;
  687. });
  688. _vm->bind_method<0>(VM::tp_list, "reverse", [](VM* vm, ArgsView args) {
  689. List& self = _CAST(List&, args[0]);
  690. std::reverse(self.begin(), self.end());
  691. return vm->None;
  692. });
  693. _vm->bind__mul__(VM::tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  694. const List& self = _CAST(List&, lhs);
  695. if(!is_int(rhs)) return vm->NotImplemented;
  696. int n = _CAST(int, rhs);
  697. List result;
  698. result.reserve(self.size() * n);
  699. for(int i = 0; i < n; i++) result.extend(self);
  700. return VAR(std::move(result));
  701. });
  702. _vm->bind_method<1>(VM::tp_list, "__rmul__", [](VM* vm, ArgsView args) {
  703. const List& self = _CAST(List&, args[0]);
  704. if(!is_int(args[1])) return vm->NotImplemented;
  705. int n = _CAST(int, args[1]);
  706. List result;
  707. result.reserve(self.size() * n);
  708. for(int i = 0; i < n; i++) result.extend(self);
  709. return VAR(std::move(result));
  710. });
  711. _vm->bind_method<2>(VM::tp_list, "insert", [](VM* vm, ArgsView args) {
  712. List& self = _CAST(List&, args[0]);
  713. int index = CAST(int, args[1]);
  714. if(index < 0) index += self.size();
  715. if(index < 0) index = 0;
  716. if(index > self.size()) index = self.size();
  717. self.insert(index, args[2]);
  718. return vm->None;
  719. });
  720. _vm->bind_method<0>(VM::tp_list, "clear", [](VM* vm, ArgsView args) {
  721. _CAST(List&, args[0]).clear();
  722. return vm->None;
  723. });
  724. _vm->bind_method<0>(VM::tp_list, "copy", PK_LAMBDA(VAR(_CAST(List, args[0]))));
  725. #define BIND_RICH_CMP(name, op, _t, _T) \
  726. _vm->bind__##name##__(_vm->_t, [](VM* vm, PyObject* lhs, PyObject* rhs){ \
  727. if(!is_non_tagged_type(rhs, vm->_t)) return vm->NotImplemented; \
  728. auto& a = _CAST(_T&, lhs); \
  729. auto& b = _CAST(_T&, rhs); \
  730. for(int i=0; i<a.size() && i<b.size(); i++){ \
  731. if(vm->py_eq(a[i], b[i])) continue; \
  732. return VAR(vm->py_##name(a[i], b[i])); \
  733. } \
  734. return VAR(a.size() op b.size()); \
  735. });
  736. BIND_RICH_CMP(lt, <, tp_list, List)
  737. BIND_RICH_CMP(le, <=, tp_list, List)
  738. BIND_RICH_CMP(gt, >, tp_list, List)
  739. BIND_RICH_CMP(ge, >=, tp_list, List)
  740. BIND_RICH_CMP(lt, <, tp_tuple, Tuple)
  741. BIND_RICH_CMP(le, <=, tp_tuple, Tuple)
  742. BIND_RICH_CMP(gt, >, tp_tuple, Tuple)
  743. BIND_RICH_CMP(ge, >=, tp_tuple, Tuple)
  744. #undef BIND_RICH_CMP
  745. _vm->bind__add__(VM::tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  746. const List& self = _CAST(List&, lhs);
  747. const List& other = CAST(List&, rhs);
  748. List new_list(self); // copy construct
  749. new_list.extend(other);
  750. return VAR(std::move(new_list));
  751. });
  752. _vm->bind__len__(VM::tp_list, [](VM* vm, PyObject* obj) {
  753. return (i64)_CAST(List&, obj).size();
  754. });
  755. _vm->bind__iter__(VM::tp_list, [](VM* vm, PyObject* obj) {
  756. List& self = _CAST(List&, obj);
  757. return VAR_T(ArrayIter, obj, self.begin(), self.end());
  758. });
  759. _vm->bind__getitem__(VM::tp_list, PyArrayGetItem<List>);
  760. _vm->bind__setitem__(VM::tp_list, [](VM* vm, PyObject* obj, PyObject* index, PyObject* value){
  761. List& self = _CAST(List&, obj);
  762. int i = CAST(int, index);
  763. i = vm->normalized_index(i, self.size());
  764. self[i] = value;
  765. });
  766. _vm->bind__delitem__(VM::tp_list, [](VM* vm, PyObject* obj, PyObject* index){
  767. List& self = _CAST(List&, obj);
  768. int i = CAST(int, index);
  769. i = vm->normalized_index(i, self.size());
  770. self.erase(i);
  771. });
  772. _vm->bind_constructor<-1>(_vm->_t(VM::tp_tuple), [](VM* vm, ArgsView args) {
  773. if(args.size() == 1+0) return VAR(Tuple(0));
  774. if(args.size() == 1+1){
  775. List list = CAST(List, vm->py_list(args[1]));
  776. return VAR(Tuple(std::move(list)));
  777. }
  778. vm->TypeError("tuple() takes at most 1 argument");
  779. return vm->None;
  780. });
  781. _vm->bind__contains__(VM::tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
  782. Tuple& self = _CAST(Tuple&, obj);
  783. for(PyObject* i: self) if(vm->py_eq(i, item)) return vm->True;
  784. return vm->False;
  785. });
  786. _vm->bind_method<1>(VM::tp_tuple, "count", [](VM* vm, ArgsView args) {
  787. Tuple& self = _CAST(Tuple&, args[0]);
  788. int count = 0;
  789. for(PyObject* i: self) if(vm->py_eq(i, args[1])) count++;
  790. return VAR(count);
  791. });
  792. _vm->bind__eq__(VM::tp_tuple, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  793. const Tuple& self = _CAST(Tuple&, lhs);
  794. if(!is_non_tagged_type(rhs, vm->tp_tuple)) return vm->NotImplemented;
  795. const Tuple& other = _CAST(Tuple&, rhs);
  796. if(self.size() != other.size()) return vm->False;
  797. for(int i = 0; i < self.size(); i++) {
  798. if(!vm->py_eq(self[i], other[i])) return vm->False;
  799. }
  800. return vm->True;
  801. });
  802. _vm->bind__hash__(VM::tp_tuple, [](VM* vm, PyObject* obj) {
  803. i64 x = 1000003;
  804. const Tuple& items = CAST(Tuple&, obj);
  805. for (int i=0; i<items.size(); i++) {
  806. i64 y = vm->py_hash(items[i]);
  807. // recommended by Github Copilot
  808. x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2));
  809. }
  810. return x;
  811. });
  812. _vm->bind__iter__(VM::tp_tuple, [](VM* vm, PyObject* obj) {
  813. Tuple& self = _CAST(Tuple&, obj);
  814. return VAR_T(ArrayIter, obj, self.begin(), self.end());
  815. });
  816. _vm->bind__getitem__(VM::tp_tuple, PyArrayGetItem<Tuple>);
  817. _vm->bind__len__(VM::tp_tuple, [](VM* vm, PyObject* obj) {
  818. return (i64)_CAST(Tuple&, obj).size();
  819. });
  820. // tp_bool
  821. _vm->bind_constructor<2>(_vm->_t(VM::tp_bool), PK_LAMBDA(VAR(vm->py_bool(args[1]))));
  822. _vm->bind__hash__(VM::tp_bool, [](VM* vm, PyObject* obj) {
  823. return (i64)_CAST(bool, obj);
  824. });
  825. _vm->bind__repr__(VM::tp_bool, [](VM* vm, PyObject* self) {
  826. bool val = _CAST(bool, self);
  827. return VAR(val ? "True" : "False");
  828. });
  829. _vm->bind__and__(VM::tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  830. return VAR(_CAST(bool, lhs) && CAST(bool, rhs));
  831. });
  832. _vm->bind__or__(VM::tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  833. return VAR(_CAST(bool, lhs) || CAST(bool, rhs));
  834. });
  835. _vm->bind__xor__(VM::tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  836. return VAR(_CAST(bool, lhs) != CAST(bool, rhs));
  837. });
  838. _vm->bind__eq__(VM::tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  839. if(is_non_tagged_type(rhs, vm->tp_bool)) return VAR(lhs == rhs);
  840. if(is_int(rhs)) return VAR(_CAST(bool, lhs) == (bool)CAST(i64, rhs));
  841. return vm->NotImplemented;
  842. });
  843. // tp_ellipsis / tp_NotImplementedType
  844. _vm->bind__repr__(_vm->_tp(_vm->Ellipsis), [](VM* vm, PyObject* self) {
  845. return VAR("...");
  846. });
  847. _vm->bind__repr__(_vm->_tp(_vm->NotImplemented), [](VM* vm, PyObject* self) {
  848. return VAR("NotImplemented");
  849. });
  850. // tp_bytes
  851. _vm->bind_constructor<2>(_vm->_t(VM::tp_bytes), [](VM* vm, ArgsView args){
  852. List& list = CAST(List&, args[1]);
  853. std::vector<unsigned char> buffer(list.size());
  854. for(int i=0; i<list.size(); i++){
  855. i64 b = CAST(i64, list[i]);
  856. if(b<0 || b>255) vm->ValueError("byte must be in range[0, 256)");
  857. buffer[i] = (char)b;
  858. }
  859. return VAR(Bytes(buffer));
  860. });
  861. _vm->bind__getitem__(VM::tp_bytes, [](VM* vm, PyObject* obj, PyObject* index) {
  862. const Bytes& self = _CAST(Bytes&, obj);
  863. int i = CAST(int, index);
  864. i = vm->normalized_index(i, self.size());
  865. return VAR(self[i]);
  866. });
  867. _vm->bind__hash__(VM::tp_bytes, [](VM* vm, PyObject* obj) {
  868. const Bytes& self = _CAST(Bytes&, obj);
  869. std::string_view view((char*)self.data(), self.size());
  870. return (i64)std::hash<std::string_view>()(view);
  871. });
  872. _vm->bind__repr__(VM::tp_bytes, [](VM* vm, PyObject* obj) {
  873. const Bytes& self = _CAST(Bytes&, obj);
  874. SStream ss;
  875. ss << "b'";
  876. for(int i=0; i<self.size(); i++){
  877. ss << "\\x";
  878. ss.write_hex((unsigned char)self[i]);
  879. }
  880. ss << "'";
  881. return VAR(ss.str());
  882. });
  883. _vm->bind__len__(VM::tp_bytes, [](VM* vm, PyObject* obj) {
  884. return (i64)_CAST(Bytes&, obj).size();
  885. });
  886. _vm->bind_method<0>(VM::tp_bytes, "decode", [](VM* vm, ArgsView args) {
  887. const Bytes& self = _CAST(Bytes&, args[0]);
  888. // TODO: check encoding is utf-8
  889. return VAR(Str(self.str()));
  890. });
  891. _vm->bind__eq__(VM::tp_bytes, [](VM* vm, PyObject* lhs, PyObject* rhs) {
  892. if(!is_non_tagged_type(rhs, vm->tp_bytes)) return vm->NotImplemented;
  893. return VAR(_CAST(Bytes&, lhs) == _CAST(Bytes&, rhs));
  894. });
  895. // tp_slice
  896. _vm->bind_constructor<4>(_vm->_t(VM::tp_slice), [](VM* vm, ArgsView args) {
  897. return VAR(Slice(args[1], args[2], args[3]));
  898. });
  899. _vm->bind__repr__(VM::tp_slice, [](VM* vm, PyObject* obj) {
  900. const Slice& self = _CAST(Slice&, obj);
  901. SStream ss;
  902. ss << "slice(";
  903. ss << CAST(Str, vm->py_repr(self.start)) << ", ";
  904. ss << CAST(Str, vm->py_repr(self.stop)) << ", ";
  905. ss << CAST(Str, vm->py_repr(self.step)) << ")";
  906. return VAR(ss.str());
  907. });
  908. // tp_mappingproxy
  909. _vm->bind_method<0>(VM::tp_mappingproxy, "keys", [](VM* vm, ArgsView args) {
  910. MappingProxy& self = _CAST(MappingProxy&, args[0]);
  911. List keys;
  912. for(StrName name : self.attr().keys()) keys.push_back(VAR(name.sv()));
  913. return VAR(std::move(keys));
  914. });
  915. _vm->bind_method<0>(VM::tp_mappingproxy, "values", [](VM* vm, ArgsView args) {
  916. MappingProxy& self = _CAST(MappingProxy&, args[0]);
  917. List values;
  918. for(auto& item : self.attr().items()) values.push_back(item.second);
  919. return VAR(std::move(values));
  920. });
  921. _vm->bind_method<0>(VM::tp_mappingproxy, "items", [](VM* vm, ArgsView args) {
  922. MappingProxy& self = _CAST(MappingProxy&, args[0]);
  923. List items;
  924. for(auto& item : self.attr().items()){
  925. PyObject* t = VAR(Tuple({VAR(item.first.sv()), item.second}));
  926. items.push_back(std::move(t));
  927. }
  928. return VAR(std::move(items));
  929. });
  930. _vm->bind__len__(VM::tp_mappingproxy, [](VM* vm, PyObject* obj) {
  931. return (i64)_CAST(MappingProxy&, obj).attr().size();
  932. });
  933. _vm->bind__eq__(VM::tp_mappingproxy, [](VM* vm, PyObject* obj, PyObject* other){
  934. const MappingProxy& a = _CAST(MappingProxy&, obj);
  935. if(!is_non_tagged_type(other, vm->tp_mappingproxy)) return vm->NotImplemented;
  936. const MappingProxy& b = _CAST(MappingProxy&, other);
  937. return VAR(a.obj == b.obj);
  938. });
  939. _vm->bind__getitem__(VM::tp_mappingproxy, [](VM* vm, PyObject* obj, PyObject* index) {
  940. MappingProxy& self = _CAST(MappingProxy&, obj);
  941. StrName key = CAST(Str&, index);
  942. PyObject* ret = self.attr().try_get_likely_found(key);
  943. if(ret == nullptr) vm->KeyError(index);
  944. return ret;
  945. });
  946. _vm->bind(_vm->_t(VM::tp_mappingproxy), "get(self, key, default=None)", [](VM* vm, ArgsView args) {
  947. MappingProxy& self = _CAST(MappingProxy&, args[0]);
  948. StrName key = CAST(Str&, args[1]);
  949. PyObject* ret = self.attr().try_get(key);
  950. if(ret == nullptr) return args[2];
  951. return ret;
  952. });
  953. _vm->bind__repr__(VM::tp_mappingproxy, [](VM* vm, PyObject* obj) {
  954. MappingProxy& self = _CAST(MappingProxy&, obj);
  955. SStream ss;
  956. ss << "mappingproxy({";
  957. bool first = true;
  958. for(auto& item : self.attr().items()){
  959. if(!first) ss << ", ";
  960. first = false;
  961. ss << item.first.escape() << ": " << CAST(Str, vm->py_repr(item.second));
  962. }
  963. ss << "})";
  964. return VAR(ss.str());
  965. });
  966. _vm->bind__contains__(VM::tp_mappingproxy, [](VM* vm, PyObject* obj, PyObject* key) {
  967. MappingProxy& self = _CAST(MappingProxy&, obj);
  968. return VAR(self.attr().contains(CAST(Str&, key)));
  969. });
  970. // tp_dict
  971. _vm->bind_constructor<-1>(_vm->_t(VM::tp_dict), [](VM* vm, ArgsView args){
  972. return VAR(Dict(vm));
  973. });
  974. _vm->bind_method<-1>(VM::tp_dict, "__init__", [](VM* vm, ArgsView args){
  975. if(args.size() == 1+0) return vm->None;
  976. if(args.size() == 1+1){
  977. auto _lock = vm->heap.gc_scope_lock();
  978. Dict& self = _CAST(Dict&, args[0]);
  979. List& list = CAST(List&, args[1]);
  980. for(PyObject* item : list){
  981. Tuple& t = CAST(Tuple&, item);
  982. if(t.size() != 2){
  983. vm->ValueError("dict() takes an iterable of tuples (key, value)");
  984. return vm->None;
  985. }
  986. self.set(t[0], t[1]);
  987. }
  988. return vm->None;
  989. }
  990. vm->TypeError("dict() takes at most 1 argument");
  991. return vm->None;
  992. });
  993. _vm->bind__len__(VM::tp_dict, [](VM* vm, PyObject* obj) {
  994. return (i64)_CAST(Dict&, obj).size();
  995. });
  996. _vm->bind__getitem__(VM::tp_dict, [](VM* vm, PyObject* obj, PyObject* index) {
  997. Dict& self = _CAST(Dict&, obj);
  998. PyObject* ret = self.try_get(index);
  999. if(ret == nullptr) vm->KeyError(index);
  1000. return ret;
  1001. });
  1002. _vm->bind__setitem__(VM::tp_dict, [](VM* vm, PyObject* obj, PyObject* key, PyObject* value) {
  1003. Dict& self = _CAST(Dict&, obj);
  1004. self.set(key, value);
  1005. });
  1006. _vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyObject* obj, PyObject* key) {
  1007. Dict& self = _CAST(Dict&, obj);
  1008. bool ok = self.erase(key);
  1009. if(!ok) vm->KeyError(key);
  1010. });
  1011. _vm->bind_method<-1>(VM::tp_dict, "pop", [](VM* vm, ArgsView args) {
  1012. if(args.size() != 2 && args.size() != 3){
  1013. vm->TypeError("pop() expected 1 or 2 arguments");
  1014. return vm->None;
  1015. }
  1016. Dict& self = _CAST(Dict&, args[0]);
  1017. PyObject* value = self.try_get(args[1]);
  1018. if(value == nullptr){
  1019. if(args.size() == 2) vm->KeyError(args[1]);
  1020. if(args.size() == 3){
  1021. return args[2];
  1022. }
  1023. }
  1024. self.erase(args[1]);
  1025. return value;
  1026. });
  1027. _vm->bind__contains__(VM::tp_dict, [](VM* vm, PyObject* obj, PyObject* key) {
  1028. Dict& self = _CAST(Dict&, obj);
  1029. return VAR(self.contains(key));
  1030. });
  1031. _vm->bind__iter__(VM::tp_dict, [](VM* vm, PyObject* obj) {
  1032. const Dict& self = _CAST(Dict&, obj);
  1033. return vm->py_iter(VAR(self.keys()));
  1034. });
  1035. _vm->bind_method<-1>(VM::tp_dict, "get", [](VM* vm, ArgsView args) {
  1036. Dict& self = _CAST(Dict&, args[0]);
  1037. if(args.size() == 1+1){
  1038. PyObject* ret = self.try_get(args[1]);
  1039. if(ret != nullptr) return ret;
  1040. return vm->None;
  1041. }else if(args.size() == 1+2){
  1042. PyObject* ret = self.try_get(args[1]);
  1043. if(ret != nullptr) return ret;
  1044. return args[2];
  1045. }
  1046. vm->TypeError("get() takes at most 2 arguments");
  1047. return vm->None;
  1048. });
  1049. _vm->bind_method<0>(VM::tp_dict, "keys", [](VM* vm, ArgsView args) {
  1050. const Dict& self = _CAST(Dict&, args[0]);
  1051. return VAR(self.keys());
  1052. });
  1053. _vm->bind_method<0>(VM::tp_dict, "values", [](VM* vm, ArgsView args) {
  1054. const Dict& self = _CAST(Dict&, args[0]);
  1055. return VAR(self.values());
  1056. });
  1057. _vm->bind_method<0>(VM::tp_dict, "items", [](VM* vm, ArgsView args) {
  1058. const Dict& self = _CAST(Dict&, args[0]);
  1059. Tuple items(self.size());
  1060. int j = 0;
  1061. self.apply([&](PyObject* k, PyObject* v){
  1062. items[j++] = VAR(Tuple({k, v}));
  1063. });
  1064. return VAR(std::move(items));
  1065. });
  1066. _vm->bind_method<1>(VM::tp_dict, "update", [](VM* vm, ArgsView args) {
  1067. Dict& self = _CAST(Dict&, args[0]);
  1068. const Dict& other = CAST(Dict&, args[1]);
  1069. self.update(other);
  1070. return vm->None;
  1071. });
  1072. _vm->bind_method<0>(VM::tp_dict, "copy", [](VM* vm, ArgsView args) {
  1073. const Dict& self = _CAST(Dict&, args[0]);
  1074. return VAR(self);
  1075. });
  1076. _vm->bind_method<0>(VM::tp_dict, "clear", [](VM* vm, ArgsView args) {
  1077. Dict& self = _CAST(Dict&, args[0]);
  1078. self.clear();
  1079. return vm->None;
  1080. });
  1081. _vm->bind__repr__(VM::tp_dict, [](VM* vm, PyObject* obj) {
  1082. Dict& self = _CAST(Dict&, obj);
  1083. SStream ss;
  1084. ss << "{";
  1085. bool first = true;
  1086. self.apply([&](PyObject* k, PyObject* v){
  1087. if(!first) ss << ", ";
  1088. first = false;
  1089. Str key = CAST(Str&, vm->py_repr(k));
  1090. Str value = CAST(Str&, vm->py_repr(v));
  1091. ss << key << ": " << value;
  1092. });
  1093. ss << "}";
  1094. return VAR(ss.str());
  1095. });
  1096. _vm->bind__eq__(VM::tp_dict, [](VM* vm, PyObject* a, PyObject* b) {
  1097. Dict& self = _CAST(Dict&, a);
  1098. if(!is_non_tagged_type(b, vm->tp_dict)) return vm->NotImplemented;
  1099. Dict& other = _CAST(Dict&, b);
  1100. if(self.size() != other.size()) return vm->False;
  1101. for(int i=0; i<self._capacity; i++){
  1102. auto item = self._items[i];
  1103. if(item.first == nullptr) continue;
  1104. PyObject* value = other.try_get(item.first);
  1105. if(value == nullptr) return vm->False;
  1106. if(!vm->py_eq(item.second, value)) return vm->False;
  1107. }
  1108. return vm->True;
  1109. });
  1110. _vm->bind__repr__(VM::tp_module, [](VM* vm, PyObject* obj) {
  1111. const Str& path = CAST(Str&, obj->attr(__path__));
  1112. return VAR(fmt("<module ", path.escape(), ">"));
  1113. });
  1114. // tp_property
  1115. _vm->bind_constructor<-1>(_vm->_t(VM::tp_property), [](VM* vm, ArgsView args) {
  1116. if(args.size() == 1+1){
  1117. return VAR(Property(args[1], vm->None, ""));
  1118. }else if(args.size() == 1+2){
  1119. return VAR(Property(args[1], args[2], ""));
  1120. }else if(args.size() == 1+3){
  1121. return VAR(Property(args[1], args[2], CAST(Str, args[3])));
  1122. }
  1123. vm->TypeError("property() takes at most 3 arguments");
  1124. return vm->None;
  1125. });
  1126. // properties
  1127. _vm->bind_property(_vm->_t(VM::tp_property), "__signature__", [](VM* vm, ArgsView args){
  1128. Property& self = _CAST(Property&, args[0]);
  1129. return VAR(self.signature);
  1130. });
  1131. _vm->bind_property(_vm->_t(VM::tp_function), "__doc__", [](VM* vm, ArgsView args) {
  1132. Function& func = _CAST(Function&, args[0]);
  1133. return VAR(func.decl->docstring);
  1134. });
  1135. _vm->bind_property(_vm->_t(VM::tp_native_func), "__doc__", [](VM* vm, ArgsView args) {
  1136. NativeFunc& func = _CAST(NativeFunc&, args[0]);
  1137. if(func.decl != nullptr) return VAR(func.decl->docstring);
  1138. return VAR("");
  1139. });
  1140. _vm->bind_property(_vm->_t(VM::tp_function), "__signature__", [](VM* vm, ArgsView args) {
  1141. Function& func = _CAST(Function&, args[0]);
  1142. return VAR(func.decl->signature);
  1143. });
  1144. _vm->bind_property(_vm->_t(VM::tp_native_func), "__signature__", [](VM* vm, ArgsView args) {
  1145. NativeFunc& func = _CAST(NativeFunc&, args[0]);
  1146. if(func.decl != nullptr) return VAR(func.decl->signature);
  1147. return VAR("");
  1148. });
  1149. // tp_exception
  1150. _vm->bind_constructor<-1>(_vm->_t(VM::tp_exception), [](VM* vm, ArgsView args){
  1151. Type cls = PK_OBJ_GET(Type, args[0]);
  1152. StrName cls_name = _type_name(vm, cls);
  1153. PyObject* e_obj = vm->heap.gcnew<Exception>(cls, cls_name);
  1154. e_obj->_enable_instance_dict();
  1155. PK_OBJ_GET(Exception, e_obj)._self = e_obj;
  1156. return e_obj;
  1157. });
  1158. _vm->bind(_vm->_t(VM::tp_exception), "__init__(self, msg=...)", [](VM* vm, ArgsView args){
  1159. Exception& self = _CAST(Exception&, args[0]);
  1160. if(args[1] == vm->Ellipsis){
  1161. self.msg = "";
  1162. }else{
  1163. self.msg = CAST(Str, args[1]);
  1164. }
  1165. return vm->None;
  1166. });
  1167. _vm->bind__repr__(VM::tp_exception, [](VM* vm, PyObject* obj) {
  1168. Exception& self = _CAST(Exception&, obj);
  1169. return VAR(fmt(_type_name(vm, obj->type), '(', self.msg.escape(), ')'));
  1170. });
  1171. _vm->bind__str__(VM::tp_exception, [](VM* vm, PyObject* obj) {
  1172. Exception& self = _CAST(Exception&, obj);
  1173. return VAR(self.msg);
  1174. });
  1175. RangeIter::register_class(_vm, _vm->builtins);
  1176. ArrayIter::register_class(_vm, _vm->builtins);
  1177. StringIter::register_class(_vm, _vm->builtins);
  1178. Generator::register_class(_vm, _vm->builtins);
  1179. }
  1180. void add_module_timeit(VM* vm){
  1181. PyObject* mod = vm->new_module("timeit");
  1182. vm->bind_func<2>(mod, "timeit", [](VM* vm, ArgsView args) {
  1183. PyObject* f = args[0];
  1184. i64 iters = CAST(i64, args[1]);
  1185. auto now = std::chrono::system_clock::now();
  1186. for(i64 i=0; i<iters; i++) vm->call(f);
  1187. auto end = std::chrono::system_clock::now();
  1188. f64 elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - now).count() / 1000.0;
  1189. return VAR(elapsed);
  1190. });
  1191. }
  1192. void add_module_operator(VM* vm){
  1193. PyObject* mod = vm->new_module("operator");
  1194. vm->bind_func<2>(mod, "lt", [](VM* vm, ArgsView args) { return VAR(vm->py_lt(args[0], args[1]));});
  1195. vm->bind_func<2>(mod, "le", [](VM* vm, ArgsView args) { return VAR(vm->py_le(args[0], args[1]));});
  1196. vm->bind_func<2>(mod, "eq", [](VM* vm, ArgsView args) { return VAR(vm->py_eq(args[0], args[1]));});
  1197. vm->bind_func<2>(mod, "ne", [](VM* vm, ArgsView args) { return VAR(vm->py_ne(args[0], args[1]));});
  1198. vm->bind_func<2>(mod, "ge", [](VM* vm, ArgsView args) { return VAR(vm->py_ge(args[0], args[1]));});
  1199. vm->bind_func<2>(mod, "gt", [](VM* vm, ArgsView args) { return VAR(vm->py_gt(args[0], args[1]));});
  1200. }
  1201. struct PyStructTime{
  1202. PY_CLASS(PyStructTime, time, struct_time)
  1203. int tm_year;
  1204. int tm_mon;
  1205. int tm_mday;
  1206. int tm_hour;
  1207. int tm_min;
  1208. int tm_sec;
  1209. int tm_wday;
  1210. int tm_yday;
  1211. int tm_isdst;
  1212. PyStructTime(std::time_t t){
  1213. std::tm* tm = std::localtime(&t);
  1214. tm_year = tm->tm_year + 1900;
  1215. tm_mon = tm->tm_mon + 1;
  1216. tm_mday = tm->tm_mday;
  1217. tm_hour = tm->tm_hour;
  1218. tm_min = tm->tm_min;
  1219. tm_sec = tm->tm_sec;
  1220. tm_wday = (tm->tm_wday + 6) % 7;
  1221. tm_yday = tm->tm_yday + 1;
  1222. tm_isdst = tm->tm_isdst;
  1223. }
  1224. PyStructTime* _() { return this; }
  1225. static void _register(VM* vm, PyObject* mod, PyObject* type){
  1226. vm->bind_notimplemented_constructor<PyStructTime>(type);
  1227. PY_READONLY_FIELD(PyStructTime, "tm_year", _, tm_year);
  1228. PY_READONLY_FIELD(PyStructTime, "tm_mon", _, tm_mon);
  1229. PY_READONLY_FIELD(PyStructTime, "tm_mday", _, tm_mday);
  1230. PY_READONLY_FIELD(PyStructTime, "tm_hour", _, tm_hour);
  1231. PY_READONLY_FIELD(PyStructTime, "tm_min", _, tm_min);
  1232. PY_READONLY_FIELD(PyStructTime, "tm_sec", _, tm_sec);
  1233. PY_READONLY_FIELD(PyStructTime, "tm_wday", _, tm_wday);
  1234. PY_READONLY_FIELD(PyStructTime, "tm_yday", _, tm_yday);
  1235. PY_READONLY_FIELD(PyStructTime, "tm_isdst", _, tm_isdst);
  1236. }
  1237. };
  1238. void add_module_time(VM* vm){
  1239. PyObject* mod = vm->new_module("time");
  1240. PyStructTime::register_class(vm, mod);
  1241. vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) {
  1242. auto now = std::chrono::system_clock::now();
  1243. return VAR(std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() / 1000.0);
  1244. });
  1245. vm->bind_func<1>(mod, "sleep", [](VM* vm, ArgsView args) {
  1246. f64 seconds = CAST_F(args[0]);
  1247. auto begin = std::chrono::system_clock::now();
  1248. while(true){
  1249. auto now = std::chrono::system_clock::now();
  1250. f64 elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - begin).count() / 1000.0;
  1251. if(elapsed >= seconds) break;
  1252. }
  1253. return vm->None;
  1254. });
  1255. vm->bind_func<0>(mod, "localtime", [](VM* vm, ArgsView args) {
  1256. auto now = std::chrono::system_clock::now();
  1257. std::time_t t = std::chrono::system_clock::to_time_t(now);
  1258. return VAR_T(PyStructTime, t);
  1259. });
  1260. }
  1261. void add_module_sys(VM* vm){
  1262. PyObject* mod = vm->new_module("sys");
  1263. vm->setattr(mod, "version", VAR(PK_VERSION));
  1264. vm->setattr(mod, "platform", VAR(kPlatformStrings[PK_SYS_PLATFORM]));
  1265. PyObject* stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
  1266. PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
  1267. vm->setattr(mod, "stdout", stdout_);
  1268. vm->setattr(mod, "stderr", stderr_);
  1269. vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
  1270. Str& s = CAST(Str&, args[0]);
  1271. vm->stdout_write(s);
  1272. return vm->None;
  1273. });
  1274. vm->bind_func<1>(stderr_, "write", [](VM* vm, ArgsView args) {
  1275. Str& s = CAST(Str&, args[0]);
  1276. vm->_stderr(s.data, s.size);
  1277. return vm->None;
  1278. });
  1279. }
  1280. void add_module_json(VM* vm){
  1281. PyObject* mod = vm->new_module("json");
  1282. vm->bind_func<1>(mod, "loads", [](VM* vm, ArgsView args) {
  1283. std::string_view sv;
  1284. if(is_non_tagged_type(args[0], vm->tp_bytes)){
  1285. sv = PK_OBJ_GET(Bytes, args[0]).sv();
  1286. }else{
  1287. sv = CAST(Str&, args[0]).sv();
  1288. }
  1289. CodeObject_ code = vm->compile(sv, "<json>", JSON_MODE);
  1290. return vm->_exec(code, vm->top_frame()->_module);
  1291. });
  1292. vm->bind_func<1>(mod, "dumps", [](VM* vm, ArgsView args) {
  1293. return vm->py_json(args[0]);
  1294. });
  1295. }
  1296. // https://docs.python.org/3.5/library/math.html
  1297. void add_module_math(VM* vm){
  1298. PyObject* mod = vm->new_module("math");
  1299. mod->attr().set("pi", VAR(3.1415926535897932384));
  1300. mod->attr().set("e" , VAR(2.7182818284590452354));
  1301. mod->attr().set("inf", VAR(std::numeric_limits<double>::infinity()));
  1302. mod->attr().set("nan", VAR(std::numeric_limits<double>::quiet_NaN()));
  1303. vm->bind_func<1>(mod, "ceil", PK_LAMBDA(VAR((i64)std::ceil(CAST_F(args[0])))));
  1304. vm->bind_func<1>(mod, "fabs", PK_LAMBDA(VAR(std::fabs(CAST_F(args[0])))));
  1305. vm->bind_func<1>(mod, "floor", PK_LAMBDA(VAR((i64)std::floor(CAST_F(args[0])))));
  1306. vm->bind_func<1>(mod, "fsum", [](VM* vm, ArgsView args) {
  1307. List& list = CAST(List&, args[0]);
  1308. double sum = 0;
  1309. double c = 0;
  1310. for(PyObject* arg : list){
  1311. double x = CAST_F(arg);
  1312. double y = x - c;
  1313. double t = sum + y;
  1314. c = (t - sum) - y;
  1315. sum = t;
  1316. }
  1317. return VAR(sum);
  1318. });
  1319. vm->bind_func<2>(mod, "gcd", [](VM* vm, ArgsView args) {
  1320. i64 a = CAST(i64, args[0]);
  1321. i64 b = CAST(i64, args[1]);
  1322. if(a < 0) a = -a;
  1323. if(b < 0) b = -b;
  1324. while(b != 0){
  1325. i64 t = b;
  1326. b = a % b;
  1327. a = t;
  1328. }
  1329. return VAR(a);
  1330. });
  1331. vm->bind_func<1>(mod, "isfinite", PK_LAMBDA(VAR(std::isfinite(CAST_F(args[0])))));
  1332. vm->bind_func<1>(mod, "isinf", PK_LAMBDA(VAR(std::isinf(CAST_F(args[0])))));
  1333. vm->bind_func<1>(mod, "isnan", PK_LAMBDA(VAR(std::isnan(CAST_F(args[0])))));
  1334. vm->bind_func<2>(mod, "isclose", [](VM* vm, ArgsView args) {
  1335. f64 a = CAST_F(args[0]);
  1336. f64 b = CAST_F(args[1]);
  1337. return VAR(std::fabs(a - b) <= Number::kEpsilon);
  1338. });
  1339. vm->bind_func<1>(mod, "exp", PK_LAMBDA(VAR(std::exp(CAST_F(args[0])))));
  1340. vm->bind_func<1>(mod, "log", PK_LAMBDA(VAR(std::log(CAST_F(args[0])))));
  1341. vm->bind_func<1>(mod, "log2", PK_LAMBDA(VAR(std::log2(CAST_F(args[0])))));
  1342. vm->bind_func<1>(mod, "log10", PK_LAMBDA(VAR(std::log10(CAST_F(args[0])))));
  1343. vm->bind_func<2>(mod, "pow", PK_LAMBDA(VAR(std::pow(CAST_F(args[0]), CAST_F(args[1])))));
  1344. vm->bind_func<1>(mod, "sqrt", PK_LAMBDA(VAR(std::sqrt(CAST_F(args[0])))));
  1345. vm->bind_func<1>(mod, "acos", PK_LAMBDA(VAR(std::acos(CAST_F(args[0])))));
  1346. vm->bind_func<1>(mod, "asin", PK_LAMBDA(VAR(std::asin(CAST_F(args[0])))));
  1347. vm->bind_func<1>(mod, "atan", PK_LAMBDA(VAR(std::atan(CAST_F(args[0])))));
  1348. vm->bind_func<2>(mod, "atan2", PK_LAMBDA(VAR(std::atan2(CAST_F(args[0]), CAST_F(args[1])))));
  1349. vm->bind_func<1>(mod, "cos", PK_LAMBDA(VAR(std::cos(CAST_F(args[0])))));
  1350. vm->bind_func<1>(mod, "sin", PK_LAMBDA(VAR(std::sin(CAST_F(args[0])))));
  1351. vm->bind_func<1>(mod, "tan", PK_LAMBDA(VAR(std::tan(CAST_F(args[0])))));
  1352. vm->bind_func<1>(mod, "degrees", PK_LAMBDA(VAR(CAST_F(args[0]) * 180 / 3.1415926535897932384)));
  1353. vm->bind_func<1>(mod, "radians", PK_LAMBDA(VAR(CAST_F(args[0]) * 3.1415926535897932384 / 180)));
  1354. vm->bind_func<1>(mod, "modf", [](VM* vm, ArgsView args) {
  1355. f64 i;
  1356. f64 f = std::modf(CAST_F(args[0]), &i);
  1357. return VAR(Tuple({VAR(f), VAR(i)}));
  1358. });
  1359. vm->bind_func<1>(mod, "factorial", [](VM* vm, ArgsView args) {
  1360. i64 n = CAST(i64, args[0]);
  1361. if(n < 0) vm->ValueError("factorial() not defined for negative values");
  1362. i64 r = 1;
  1363. for(i64 i=2; i<=n; i++) r *= i;
  1364. return VAR(r);
  1365. });
  1366. }
  1367. void add_module_traceback(VM* vm){
  1368. PyObject* mod = vm->new_module("traceback");
  1369. vm->bind_func<0>(mod, "print_exc", [](VM* vm, ArgsView args) {
  1370. if(vm->_last_exception==nullptr) vm->ValueError("no exception");
  1371. Exception& e = _CAST(Exception&, vm->_last_exception);
  1372. vm->stdout_write(e.summary());
  1373. return vm->None;
  1374. });
  1375. vm->bind_func<0>(mod, "format_exc", [](VM* vm, ArgsView args) {
  1376. if(vm->_last_exception==nullptr) vm->ValueError("no exception");
  1377. Exception& e = _CAST(Exception&, vm->_last_exception);
  1378. return VAR(e.summary());
  1379. });
  1380. }
  1381. void add_module_dis(VM* vm){
  1382. PyObject* mod = vm->new_module("dis");
  1383. static const auto get_code = [](VM* vm, PyObject* obj)->CodeObject_{
  1384. if(is_type(obj, vm->tp_str)){
  1385. const Str& source = CAST(Str, obj);
  1386. return vm->compile(source, "<dis>", EXEC_MODE);
  1387. }
  1388. PyObject* f = obj;
  1389. if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, obj).func;
  1390. return CAST(Function&, f).decl->code;
  1391. };
  1392. vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) {
  1393. CodeObject_ code = get_code(vm, args[0]);
  1394. vm->stdout_write(vm->disassemble(code));
  1395. return vm->None;
  1396. });
  1397. }
  1398. void add_module_gc(VM* vm){
  1399. PyObject* mod = vm->new_module("gc");
  1400. vm->bind_func<0>(mod, "collect", PK_LAMBDA(VAR(vm->heap.collect())));
  1401. }
  1402. void VM::post_init(){
  1403. init_builtins(this);
  1404. bind_method<-1>(tp_module, "__init__", [](VM* vm, ArgsView args) {
  1405. vm->NotImplementedError();
  1406. return vm->None;
  1407. });
  1408. _all_types[tp_module].m__getattr__ = [](VM* vm, PyObject* obj, StrName name) -> PyObject*{
  1409. const Str& path = CAST(Str&, obj->attr(__path__));
  1410. return vm->py_import(fmt(path, ".", name.sv()), false);
  1411. };
  1412. bind_method<1>(tp_property, "setter", [](VM* vm, ArgsView args) {
  1413. Property& self = _CAST(Property&, args[0]);
  1414. // The setter's name is not necessary to be the same as the property's name
  1415. // However, for cpython compatibility, we recommend to use the same name
  1416. self.setter = args[1];
  1417. return args[0];
  1418. });
  1419. // type
  1420. bind__getitem__(tp_type, [](VM* vm, PyObject* self, PyObject* _){
  1421. PK_UNUSED(_);
  1422. return self; // for generics
  1423. });
  1424. bind_property(_t(tp_type), "__annotations__", [](VM* vm, ArgsView args){
  1425. const PyTypeInfo* ti = &vm->_all_types[(PK_OBJ_GET(Type, args[0]))];
  1426. Tuple t(ti->annotated_fields.size());
  1427. for(int i=0; i<ti->annotated_fields.size(); i++){
  1428. t[i] = VAR(ti->annotated_fields[i].sv());
  1429. }
  1430. return VAR(std::move(t));
  1431. });
  1432. bind__repr__(tp_type, [](VM* vm, PyObject* self){
  1433. SStream ss;
  1434. const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, self)];
  1435. ss << "<class '" << info.name << "'>";
  1436. return VAR(ss.str());
  1437. });
  1438. bind_property(_t(tp_object), "__class__", PK_LAMBDA(vm->_t(args[0])));
  1439. bind_property(_t(tp_type), "__base__", [](VM* vm, ArgsView args){
  1440. const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
  1441. return info.base.index == -1 ? vm->None : vm->_all_types[info.base].obj;
  1442. });
  1443. bind_property(_t(tp_type), "__name__", [](VM* vm, ArgsView args){
  1444. const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
  1445. return VAR(info.name.sv());
  1446. });
  1447. bind_property(_t(tp_type), "__module__", [](VM* vm, ArgsView args){
  1448. const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, args[0])];
  1449. if(info.mod == nullptr) return vm->None;
  1450. return info.mod;
  1451. });
  1452. bind_property(_t(tp_bound_method), "__self__", [](VM* vm, ArgsView args){
  1453. return CAST(BoundMethod&, args[0]).self;
  1454. });
  1455. bind_property(_t(tp_bound_method), "__func__", [](VM* vm, ArgsView args){
  1456. return CAST(BoundMethod&, args[0]).func;
  1457. });
  1458. bind__eq__(tp_bound_method, [](VM* vm, PyObject* lhs, PyObject* rhs){
  1459. if(!is_non_tagged_type(rhs, vm->tp_bound_method)) return vm->NotImplemented;
  1460. const BoundMethod& _0 = PK_OBJ_GET(BoundMethod, lhs);
  1461. const BoundMethod& _1 = PK_OBJ_GET(BoundMethod, rhs);
  1462. return VAR(_0.self == _1.self && _0.func == _1.func);
  1463. });
  1464. bind_property(_t(tp_slice), "start", [](VM* vm, ArgsView args){
  1465. return CAST(Slice&, args[0]).start;
  1466. });
  1467. bind_property(_t(tp_slice), "stop", [](VM* vm, ArgsView args){
  1468. return CAST(Slice&, args[0]).stop;
  1469. });
  1470. bind_property(_t(tp_slice), "step", [](VM* vm, ArgsView args){
  1471. return CAST(Slice&, args[0]).step;
  1472. });
  1473. bind_property(_t(tp_object), "__dict__", [](VM* vm, ArgsView args){
  1474. if(is_tagged(args[0]) || !args[0]->is_attr_valid()) return vm->None;
  1475. return VAR(MappingProxy(args[0]));
  1476. });
  1477. add_module_sys(this);
  1478. add_module_traceback(this);
  1479. add_module_time(this);
  1480. add_module_json(this);
  1481. add_module_math(this);
  1482. add_module_re(this);
  1483. add_module_dis(this);
  1484. add_module_c(this);
  1485. add_module_gc(this);
  1486. add_module_random(this);
  1487. add_module_base64(this);
  1488. add_module_timeit(this);
  1489. add_module_operator(this);
  1490. add_module_csv(this);
  1491. for(const char* name: {"this", "functools", "heapq", "bisect", "pickle", "_long", "colorsys", "typing", "datetime", "dataclasses", "cmath"}){
  1492. _lazy_modules[name] = kPythonLibs[name];
  1493. }
  1494. try{
  1495. CodeObject_ code = compile(kPythonLibs["builtins"], "<builtins>", EXEC_MODE);
  1496. this->_exec(code, this->builtins);
  1497. code = compile(kPythonLibs["_set"], "<set>", EXEC_MODE);
  1498. this->_exec(code, this->builtins);
  1499. }catch(const Exception& e){
  1500. std::cerr << e.summary() << std::endl;
  1501. std::cerr << "failed to load builtins module!!" << std::endl;
  1502. exit(1);
  1503. }
  1504. if(enable_os){
  1505. add_module_io(this);
  1506. add_module_os(this);
  1507. _import_handler = _default_import_handler;
  1508. }
  1509. add_module_linalg(this);
  1510. add_module_easing(this);
  1511. add_module_collections(this);
  1512. #ifdef PK_USE_CJSON
  1513. add_module_cjson(this);
  1514. #endif
  1515. }
  1516. CodeObject_ VM::compile(const Str& source, const Str& filename, CompileMode mode, bool unknown_global_scope) {
  1517. Compiler compiler(this, source, filename, mode, unknown_global_scope);
  1518. try{
  1519. return compiler.compile();
  1520. }catch(const Exception& e){
  1521. #if PK_DEBUG_FULL_EXCEPTION
  1522. std::cerr << e.summary() << std::endl;
  1523. #endif
  1524. _error(e.self());
  1525. return nullptr;
  1526. }
  1527. }
  1528. } // namespace pkpy