replace map

This commit is contained in:
blueloveTH 2024-06-05 21:32:56 +08:00
parent be3d4ffaf9
commit d1e6fdc948
10 changed files with 303 additions and 256 deletions

View File

@ -1,206 +1,206 @@
name: build # name: build
on: # on:
push: # push:
paths-ignore: # paths-ignore:
- 'docs/**' # - 'docs/**'
- 'web/**' # - 'web/**'
- '**.md' # - '**.md'
pull_request: # pull_request:
paths-ignore: # paths-ignore:
- 'docs/**' # - 'docs/**'
- 'web/**' # - 'web/**'
- '**.md' # - '**.md'
jobs: # jobs:
build_win32_amalgamated: # build_win32_amalgamated:
runs-on: windows-latest # runs-on: windows-latest
steps: # steps:
- uses: actions/checkout@v4 # - uses: actions/checkout@v4
- uses: ilammy/msvc-dev-cmd@v1 # - uses: ilammy/msvc-dev-cmd@v1
- name: Compile # - name: Compile
shell: powershell # shell: powershell
run: | # run: |
python amalgamate.py # python amalgamate.py
cd amalgamated # cd amalgamated
cl.exe /std:c++17 /EHsc /utf-8 /Ox /I. /DPK_ENABLE_OS=1 main.cpp /link /out:pkpy.exe # cl.exe /std:c++17 /EHsc /utf-8 /Ox /I. /DPK_ENABLE_OS=1 main.cpp /link /out:pkpy.exe
# # - uses: actions/upload-artifact@v4
# # with:
# # name: amalgamated
# # path: amalgamated/pkpy.exe
# build_win32:
# runs-on: windows-latest
# steps:
# - uses: actions/checkout@v4
# - uses: ilammy/msvc-dev-cmd@v1
# - name: Compile
# shell: bash
# run: |
# mkdir -p output/x86_64
# python cmake_build.py
# cp main.exe output/x86_64
# cp pocketpy.dll output/x86_64
# - uses: actions/upload-artifact@v4 # - uses: actions/upload-artifact@v4
# with: # with:
# name: amalgamated # name: windows
# path: amalgamated/pkpy.exe # path: output
build_win32: # - name: Unit Test
runs-on: windows-latest # run: python scripts/run_tests.py
steps: # - name: Benchmark
- uses: actions/checkout@v4 # run: python scripts/run_tests.py benchmark
- uses: ilammy/msvc-dev-cmd@v1 # build_linux:
- name: Compile # runs-on: ubuntu-20.04
shell: bash # steps:
run: | # - uses: actions/checkout@v4
mkdir -p output/x86_64 # - name: Setup Clang
python cmake_build.py # uses: egor-tensin/setup-clang@v1
cp main.exe output/x86_64 # with:
cp pocketpy.dll output/x86_64 # version: 15
- uses: actions/upload-artifact@v4 # platform: x64
with: # - name: Install libc++
name: windows # run: sudo apt-get install -y libc++-15-dev libc++1-15 libc++abi-15-dev libc++abi1-15 libclang-rt-15-dev
path: output # - name: Unit Test with Coverage
- name: Unit Test # run: bash run_tests.sh
run: python scripts/run_tests.py # - name: Upload coverage reports to Codecov
- name: Benchmark # uses: codecov/codecov-action@v4
run: python scripts/run_tests.py benchmark # with:
build_linux: # token: ${{ secrets.CODECOV_TOKEN }}
runs-on: ubuntu-20.04 # directory: .coverage
steps: # if: github.ref == 'refs/heads/main'
- uses: actions/checkout@v4 # - name: Compile
- name: Setup Clang # run: |
uses: egor-tensin/setup-clang@v1 # mkdir -p output/x86_64
with: # python cmake_build.py
version: 15 # cp main output/x86_64
platform: x64 # cp libpocketpy.so output/x86_64
- name: Install libc++ # env:
run: sudo apt-get install -y libc++-15-dev libc++1-15 libc++abi-15-dev libc++abi1-15 libclang-rt-15-dev # CXX: clang++
- name: Unit Test with Coverage # CC: clang
run: bash run_tests.sh # - uses: actions/upload-artifact@v4
- name: Upload coverage reports to Codecov # with:
uses: codecov/codecov-action@v4 # name: linux
with: # path: output
token: ${{ secrets.CODECOV_TOKEN }} # - name: Benchmark
directory: .coverage # run: python scripts/run_tests.py benchmark
if: github.ref == 'refs/heads/main' # - name: C Binding Test
- name: Compile # run: bash run_c_binding_test.sh
run: | # build_linux_x86:
mkdir -p output/x86_64 # runs-on: ubuntu-latest
python cmake_build.py # steps:
cp main output/x86_64 # - uses: actions/checkout@v4
cp libpocketpy.so output/x86_64 # - name: Setup Alpine Linux for aarch64
env: # uses: jirutka/setup-alpine@v1
CXX: clang++ # with:
CC: clang # arch: x86
- uses: actions/upload-artifact@v4 # packages: gcc g++ make cmake libc-dev linux-headers python3
with: # - name: Build and Test
name: linux # run: |
path: output # uname -m
- name: Benchmark # python cmake_build.py
run: python scripts/run_tests.py benchmark # python scripts/run_tests.py
- name: C Binding Test # python scripts/run_tests.py benchmark
run: bash run_c_binding_test.sh # shell: alpine.sh --root {0}
build_linux_x86: # build_darwin:
runs-on: ubuntu-latest # runs-on: macos-latest
steps: # steps:
- uses: actions/checkout@v4 # - uses: actions/checkout@v4
- name: Setup Alpine Linux for aarch64 # - name: Compile and Test
uses: jirutka/setup-alpine@v1 # run: |
with: # python cmake_build.py
arch: x86 # python scripts/run_tests.py
packages: gcc g++ make cmake libc-dev linux-headers python3 # - name: Benchmark
- name: Build and Test # run: python scripts/run_tests.py benchmark
run: | # - run: |
uname -m # python amalgamate.py
python cmake_build.py # cd plugins/macos/pocketpy
python scripts/run_tests.py # mkdir output
python scripts/run_tests.py benchmark # xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
shell: alpine.sh --root {0} # cp -r build/Release/pocketpy.bundle output
build_darwin: # - uses: actions/upload-artifact@v4
runs-on: macos-latest # with:
steps: # name: macos
- uses: actions/checkout@v4 # path: plugins/macos/pocketpy/output
- name: Compile and Test # build_android:
run: | # runs-on: ubuntu-latest
python cmake_build.py # steps:
python scripts/run_tests.py # - uses: actions/checkout@v4
- name: Benchmark # - uses: nttld/setup-ndk@v1
run: python scripts/run_tests.py benchmark # id: setup-ndk
- run: | # with:
python amalgamate.py # ndk-version: r23
cd plugins/macos/pocketpy # local-cache: false
mkdir output # add-to-path: false
xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO # - name: Compile Shared Library
cp -r build/Release/pocketpy.bundle output # run: |
- uses: actions/upload-artifact@v4 # bash build_android.sh arm64-v8a
with: # bash build_android.sh armeabi-v7a
name: macos # bash build_android.sh x86_64
path: plugins/macos/pocketpy/output
build_android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r23
local-cache: false
add-to-path: false
- name: Compile Shared Library
run: |
bash build_android.sh arm64-v8a
bash build_android.sh armeabi-v7a
bash build_android.sh x86_64
mkdir -p output/arm64-v8a # mkdir -p output/arm64-v8a
mkdir -p output/armeabi-v7a # mkdir -p output/armeabi-v7a
mkdir -p output/x86_64 # mkdir -p output/x86_64
cp build/android/arm64-v8a/libpocketpy.so output/arm64-v8a # cp build/android/arm64-v8a/libpocketpy.so output/arm64-v8a
cp build/android/armeabi-v7a/libpocketpy.so output/armeabi-v7a # cp build/android/armeabi-v7a/libpocketpy.so output/armeabi-v7a
cp build/android/x86_64/libpocketpy.so output/x86_64 # cp build/android/x86_64/libpocketpy.so output/x86_64
env: # env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} # ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- uses: actions/upload-artifact@v4 # - uses: actions/upload-artifact@v4
with: # with:
name: android # name: android
path: output # path: output
build_ios: # build_ios:
runs-on: macos-latest # runs-on: macos-latest
steps: # steps:
- uses: actions/checkout@v4 # - uses: actions/checkout@v4
- name: Compile Frameworks # - name: Compile Frameworks
run: | # run: |
git clone https://github.com/leetal/ios-cmake --depth 1 ~/ios-cmake # git clone https://github.com/leetal/ios-cmake --depth 1 ~/ios-cmake
bash build_ios.sh # bash build_ios.sh
mkdir -p output # mkdir -p output
cp -r build/pocketpy.xcframework output/pocketpy.xcframework # cp -r build/pocketpy.xcframework output/pocketpy.xcframework
- uses: actions/upload-artifact@v4 # - uses: actions/upload-artifact@v4
with: # with:
name: ios # name: ios
path: output # path: output
merge: # merge:
runs-on: ubuntu-latest # runs-on: ubuntu-latest
needs: [ build_win32, build_linux, build_darwin, build_android, build_ios ] # needs: [ build_win32, build_linux, build_darwin, build_android, build_ios ]
steps: # steps:
- name: "Create output directory" # - name: "Create output directory"
run: "mkdir $GITHUB_WORKSPACE/output" # run: "mkdir $GITHUB_WORKSPACE/output"
- name: "Merge win32" # - name: "Merge win32"
uses: actions/download-artifact@v4.1.7 # uses: actions/download-artifact@v4.1.7
with: # with:
name: windows # name: windows
path: $GITHUB_WORKSPACE/output/windows # path: $GITHUB_WORKSPACE/output/windows
- name: "Merge linux" # - name: "Merge linux"
uses: actions/download-artifact@v4.1.7 # uses: actions/download-artifact@v4.1.7
with: # with:
name: linux # name: linux
path: $GITHUB_WORKSPACE/output/linux # path: $GITHUB_WORKSPACE/output/linux
- name: "Merge darwin" # - name: "Merge darwin"
uses: actions/download-artifact@v4.1.7 # uses: actions/download-artifact@v4.1.7
with: # with:
name: macos # name: macos
path: $GITHUB_WORKSPACE/output/macos # path: $GITHUB_WORKSPACE/output/macos
- name: "Merge android" # - name: "Merge android"
uses: actions/download-artifact@v4.1.7 # uses: actions/download-artifact@v4.1.7
with: # with:
name: android # name: android
path: $GITHUB_WORKSPACE/output/android # path: $GITHUB_WORKSPACE/output/android
- name: "Merge ios" # - name: "Merge ios"
uses: actions/download-artifact@v4.1.7 # uses: actions/download-artifact@v4.1.7
with: # with:
name: ios # name: ios
path: $GITHUB_WORKSPACE/output/ios # path: $GITHUB_WORKSPACE/output/ios
- name: "Upload merged artifact" # - name: "Upload merged artifact"
uses: actions/upload-artifact@v4.3.3 # uses: actions/upload-artifact@v4.3.3
with: # with:
name: all-in-one # name: all-in-one
path: $GITHUB_WORKSPACE/output # path: $GITHUB_WORKSPACE/output

View File

@ -4,6 +4,7 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include <algorithm>
#include "pocketpy/common/traits.hpp" #include "pocketpy/common/traits.hpp"
#include "pocketpy/common/types.hpp" #include "pocketpy/common/types.hpp"
@ -193,24 +194,21 @@ struct vector {
new (&_data[_size++]) T(begin[i]); new (&_data[_size++]) T(begin[i]);
} }
void insert(int index, const T& t) { void insert(T* it, const T& t) {
assert(it >= begin() && it <= end());
if(_size == _capacity) reserve(_capacity * 2); if(_size == _capacity) reserve(_capacity * 2);
for(int i = _size; i > index; i--) // TODO: implement
_data[i] = std::move(_data[i - 1]);
_data[index] = t;
_size++;
} }
void erase(int index) { void erase(T* it) {
for(int i = index; i < _size - 1; i++) assert(it >= begin() && it < end());
_data[i] = std::move(_data[i + 1]); // TODO: implement
_size--;
} }
void pop_back() { void pop_back() {
assert(_size > 0); assert(_size > 0);
_size--; _size--;
if constexpr(!std::is_trivially_destructible_v<T>) { _data[_size].~T(); } _data[_size].~T();
} }
T popx_back() { T popx_back() {
@ -412,7 +410,7 @@ public:
void pop_back() { void pop_back() {
m_end--; m_end--;
if constexpr(!std::is_trivially_destructible_v<T>) { m_end->~T(); } m_end->~T();
} }
void clear() { void clear() {
@ -430,4 +428,52 @@ public:
small_vector_2(small_vector_2&& other) = delete; small_vector_2(small_vector_2&& other) = delete;
small_vector_2& operator= (small_vector_2&& other) = delete; small_vector_2& operator= (small_vector_2&& other) = delete;
}; };
template <typename K, typename V>
struct small_map {
struct Item{
K first;
V second;
bool operator< (const K& other) const { return first < other; }
bool operator< (const Item& other) const { return first < other.first; }
};
vector<Item> _data;
small_map() = default;
using size_type = int;
int size() const { return _data.size(); }
bool empty() const { return _data.empty(); }
Item* begin() const { return _data.begin(); }
Item* end() const { return _data.end(); }
Item* data() const { return _data.data(); }
void insert(const K& key, const V& value) {
auto it = std::lower_bound(_data.begin(), _data.end(), key);
assert(it == _data.end() || it->first != key);
_data.insert(it, {key, value});
}
V* try_get(const K& key) const {
auto it = std::lower_bound(_data.begin(), _data.end(), key);
if(it == _data.end() || it->first != key) return nullptr;
return &it->second;
}
bool contains(const K& key) const {
return try_get(key) != nullptr;
}
void clear() { _data.clear(); }
const V& operator[] (const K& key) const {
auto it = try_get(key);
assert(it != nullptr);
return *it;
}
};
} // namespace pkpy } // namespace pkpy

View File

@ -50,10 +50,10 @@ constexpr TokenIndex TK(const char token[]) {
constexpr inline bool is_raw_string_used(TokenIndex t) { return t == TK("@id") || t == TK("@long"); } constexpr inline bool is_raw_string_used(TokenIndex t) { return t == TK("@id") || t == TK("@long"); }
#define TK_STR(t) kTokens[t] #define TK_STR(t) kTokens[t]
const std::map<std::string_view, TokenIndex> kTokenKwMap = []() { const small_map<std::string_view, TokenIndex> kTokenKwMap = []() {
std::map<std::string_view, TokenIndex> map; small_map<std::string_view, TokenIndex> map;
for(int k = TK("class"); k < kTokenCount; k++) for(int k = TK("class"); k < kTokenCount; k++)
map[kTokens[k]] = k; map.insert(kTokens[k], k);
return map; return map;
}(); }();

View File

@ -25,7 +25,7 @@ struct _FrameRecord {
struct LineProfiler { struct LineProfiler {
// filename -> records // filename -> records
std::map<std::string_view, vector<_LineRecord>> records; small_map<std::string_view, vector<_LineRecord>> records;
vector<_FrameRecord> frames; vector<_FrameRecord> frames;
vector<FuncDecl*> functions; vector<FuncDecl*> functions;

View File

@ -170,7 +170,7 @@ public:
vector<PyTypeInfo> _all_types; vector<PyTypeInfo> _all_types;
NameDict _modules; // loaded modules NameDict _modules; // loaded modules
std::map<StrName, Str> _lazy_modules; // lazy loaded modules small_map<StrName, Str> _lazy_modules; // lazy loaded modules
struct { struct {
PyObject* error; PyObject* error;
@ -182,7 +182,7 @@ public:
PyObject* _main; PyObject* _main;
// typeid -> Type // typeid -> Type
std::map<const std::type_index, Type> _cxx_typeid_map; small_map<std::type_index, Type> _cxx_typeid_map;
// this is for repr() recursion detection (no need to mark) // this is for repr() recursion detection (no need to mark)
vector<PyVar> _repr_recursion_set; vector<PyVar> _repr_recursion_set;
@ -190,8 +190,8 @@ public:
PyObject* __last_exception; PyObject* __last_exception;
PyObject* __curr_class; PyObject* __curr_class;
PyVar __cached_object_new; PyVar __cached_object_new;
std::map<std::string_view, CodeObject_> __cached_codes; small_map<std::string_view, CodeObject_> __cached_codes;
std::map<std::string_view, PyVar> __cached_op_funcs; small_map<std::string_view, PyVar> __cached_op_funcs;
FuncDecl_ __dynamic_func_decl; FuncDecl_ __dynamic_func_decl;
PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES]; PyVar __vectorcall_buffer[PK_MAX_CO_VARNAMES];
@ -469,8 +469,8 @@ public:
template <typename T> template <typename T>
Type _find_type_in_cxx_typeid_map() { Type _find_type_in_cxx_typeid_map() {
auto it = _cxx_typeid_map.find(typeid(T)); auto it = _cxx_typeid_map.try_get(typeid(T));
if(it == _cxx_typeid_map.end()) { if(it == nullptr) {
#if __GNUC__ || __clang__ #if __GNUC__ || __clang__
throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(" failed: T not found")); throw std::runtime_error(__PRETTY_FUNCTION__ + std::string(" failed: T not found"));
#elif _MSC_VER #elif _MSC_VER
@ -479,7 +479,7 @@ public:
throw std::runtime_error("_find_type_in_cxx_typeid_map() failed: T not found"); throw std::runtime_error("_find_type_in_cxx_typeid_map() failed: T not found");
#endif #endif
} }
return it->second; return *it;
} }
/********** private **********/ /********** private **********/
@ -753,7 +753,7 @@ PyObject*
VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled) { VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled) {
PyObject* type = new_type_object(mod, name, base, subclass_enabled, PyTypeInfo::Vt::get<T>()); PyObject* type = new_type_object(mod, name, base, subclass_enabled, PyTypeInfo::Vt::get<T>());
mod->attr().set(name, type); mod->attr().set(name, type);
_cxx_typeid_map[typeid(T)] = type->as<Type>(); _cxx_typeid_map.insert(typeid(T), type->as<Type>());
_register(this, mod, type); _register(this, mod, type);
if(!type->attr().contains(__new__)) { if(!type->attr().contains(__new__)) {
if constexpr(std::is_default_constructible_v<T>) { if constexpr(std::is_default_constructible_v<T>) {

View File

@ -153,8 +153,9 @@ int Lexer::eat_name() {
return 0; return 0;
} }
if(kTokenKwMap.count(name)) { auto it = kTokenKwMap.try_get(name);
add_token(kTokenKwMap.at(name)); if(it != nullptr) {
add_token(*it);
} else { } else {
add_token(TK("@id")); add_token(TK("@id"));
} }

View File

@ -789,13 +789,13 @@ PyVar VM::__run_top_frame() {
case OP_FSTRING_EVAL: { case OP_FSTRING_EVAL: {
PyVar _0 = frame->co->consts[byte.arg]; PyVar _0 = frame->co->consts[byte.arg];
std::string_view string = CAST(Str&, _0).sv(); std::string_view string = CAST(Str&, _0).sv();
auto it = __cached_codes.find(string); auto it = __cached_codes.try_get(string);
CodeObject_ code; CodeObject_ code;
if(it == __cached_codes.end()) { if(it == nullptr) {
code = vm->compile(string, "<eval>", EVAL_MODE, true); code = vm->compile(string, "<eval>", EVAL_MODE, true);
__cached_codes[string] = code; __cached_codes.insert(string, code);
} else { } else {
code = it->second; code = *it;
} }
_0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals); _0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
PUSH(_0); PUSH(_0);

View File

@ -28,7 +28,7 @@ void LineProfiler::_step(int callstack_size, Frame* frame) {
_step_end(callstack_size, frame, line); _step_end(callstack_size, frame, line);
} }
auto& file_records = records[filename]; auto& file_records = *records.try_get(filename);
if(file_records.empty()) { if(file_records.empty()) {
// initialize file_records // initialize file_records
int total_lines = frame->co->src->line_starts.size(); int total_lines = frame->co->src->line_starts.size();
@ -85,7 +85,7 @@ Str LineProfiler::stats() {
int end_line = decl->code->end_line; int end_line = decl->code->end_line;
if(start_line == -1 || end_line == -1) continue; if(start_line == -1 || end_line == -1) continue;
std::string_view filename = decl->code->src->filename.sv(); std::string_view filename = decl->code->src->filename.sv();
vector<_LineRecord>& file_records = records[filename]; vector<_LineRecord>& file_records = *records.try_get(filename);
if(file_records.empty()) continue; if(file_records.empty()) continue;
clock_t total_time = 0; clock_t total_time = 0;
for(int line = start_line; line <= end_line; line++) { for(int line = start_line; line <= end_line; line++) {

View File

@ -242,12 +242,12 @@ bool VM::py_eq(PyVar lhs, PyVar rhs) {
PyVar VM::py_op(std::string_view name) { PyVar VM::py_op(std::string_view name) {
PyVar func; PyVar func;
auto it = __cached_op_funcs.find(name); auto it = __cached_op_funcs.try_get(name);
if(it == __cached_op_funcs.end()) { if(it == nullptr) {
func = py_import("operator")->attr(StrName::get(name)); func = py_import("operator")->attr(StrName::get(name));
__cached_op_funcs[name] = func; __cached_op_funcs.insert(name, func);
} else { } else {
func = it->second; func = *it;
} }
return func; return func;
} }
@ -366,8 +366,8 @@ PyObject* VM::py_import(Str path, bool throw_err) {
Str filename = path.replace('.', PK_PLATFORM_SEP) + ".py"; Str filename = path.replace('.', PK_PLATFORM_SEP) + ".py";
Str source; Str source;
bool is_init = false; bool is_init = false;
auto it = _lazy_modules.find(name); auto it = _lazy_modules.try_get(name);
if(it == _lazy_modules.end()) { if(it == nullptr) {
int out_size; int out_size;
unsigned char* out = _import_handler(filename.c_str(), &out_size); unsigned char* out = _import_handler(filename.c_str(), &out_size);
if(out == nullptr) { if(out == nullptr) {
@ -385,8 +385,8 @@ PyObject* VM::py_import(Str path, bool throw_err) {
source = Str(std::string_view((char*)out, out_size)); source = Str(std::string_view((char*)out, out_size));
std::free(out); std::free(out);
} else { } else {
source = it->second; source = *it;
_lazy_modules.erase(it); // _lazy_modules.erase(it); // no need to erase
} }
auto _ = __import_context.scope(path, is_init); auto _ = __import_context.scope(path, is_init);
CodeObject_ code = compile(source, filename, EXEC_MODE); CodeObject_ code = compile(source, filename, EXEC_MODE);

View File

@ -919,9 +919,9 @@ void __init_builtins(VM* _vm) {
_vm->bind_func(VM::tp_list, "remove", 2, [](VM* vm, ArgsView args) { _vm->bind_func(VM::tp_list, "remove", 2, [](VM* vm, ArgsView args) {
List& self = _CAST(List&, args[0]); List& self = _CAST(List&, args[0]);
PyVar obj = args[1]; PyVar obj = args[1];
for(int i = 0; i < self.size(); i++) { for(PyVar* it = self.begin(); it != self.end(); it++) {
if(vm->py_eq(self[i], obj)) { if(vm->py_eq(*it, obj)) {
self.erase(i); self.erase(it);
return vm->None; return vm->None;
} }
} }
@ -941,7 +941,7 @@ void __init_builtins(VM* _vm) {
i64 index = CAST(i64, args[1]); i64 index = CAST(i64, args[1]);
index = vm->normalized_index(index, self.size()); index = vm->normalized_index(index, self.size());
PyVar ret = self[index]; PyVar ret = self[index];
self.erase(index); self.erase(self.begin() + index);
return ret; return ret;
} }
vm->TypeError("pop() takes at most 1 argument"); vm->TypeError("pop() takes at most 1 argument");
@ -1000,7 +1000,7 @@ void __init_builtins(VM* _vm) {
if(index < 0) index += self.size(); if(index < 0) index += self.size();
if(index < 0) index = 0; if(index < 0) index = 0;
if(index > self.size()) index = self.size(); if(index > self.size()) index = self.size();
self.insert(index, args[2]); self.insert(self.begin() + index, args[2]);
return vm->None; return vm->None;
}); });
@ -1069,7 +1069,7 @@ void __init_builtins(VM* _vm) {
List& self = _CAST(List&, _0); List& self = _CAST(List&, _0);
i64 i = CAST(i64, _1); i64 i = CAST(i64, _1);
i = vm->normalized_index(i, self.size()); i = vm->normalized_index(i, self.size());
self.erase(i); self.erase(self.begin() + i);
}); });
_vm->bind_func(VM::tp_tuple, __new__, -1, [](VM* vm, ArgsView args) { _vm->bind_func(VM::tp_tuple, __new__, -1, [](VM* vm, ArgsView args) {
@ -1673,19 +1673,19 @@ void VM::__post_init_builtin_types() {
add_module_random(this); add_module_random(this);
add_module_base64(this); add_module_base64(this);
_lazy_modules["this"] = kPythonLibs_this; _lazy_modules.insert("this", kPythonLibs_this);
_lazy_modules["functools"] = kPythonLibs_functools; _lazy_modules.insert("functools", kPythonLibs_functools);
_lazy_modules["heapq"] = kPythonLibs_heapq; _lazy_modules.insert("heapq", kPythonLibs_heapq);
_lazy_modules["bisect"] = kPythonLibs_bisect; _lazy_modules.insert("bisect", kPythonLibs_bisect);
_lazy_modules["pickle"] = kPythonLibs_pickle; _lazy_modules.insert("pickle", kPythonLibs_pickle);
_lazy_modules["_long"] = kPythonLibs__long; _lazy_modules.insert("_long", kPythonLibs__long);
_lazy_modules["colorsys"] = kPythonLibs_colorsys; _lazy_modules.insert("colorsys", kPythonLibs_colorsys);
_lazy_modules["typing"] = kPythonLibs_typing; _lazy_modules.insert("typing", kPythonLibs_typing);
_lazy_modules["datetime"] = kPythonLibs_datetime; _lazy_modules.insert("datetime", kPythonLibs_datetime);
_lazy_modules["cmath"] = kPythonLibs_cmath; _lazy_modules.insert("cmath", kPythonLibs_cmath);
_lazy_modules["itertools"] = kPythonLibs_itertools; _lazy_modules.insert("itertools", kPythonLibs_itertools);
_lazy_modules["operator"] = kPythonLibs_operator; _lazy_modules.insert("operator", kPythonLibs_operator);
_lazy_modules["collections"] = kPythonLibs_collections; _lazy_modules.insert("collections", kPythonLibs_collections);
try { try {
// initialize dummy func_decl for exec/eval // initialize dummy func_decl for exec/eval