use new vector impl

This commit is contained in:
blueloveTH 2024-06-01 18:18:38 +08:00
parent ac82f6f33f
commit a59592b799
25 changed files with 282 additions and 201 deletions

View File

@ -1,5 +1,5 @@
SRC=$(find src/ -name "*.cpp")
FLAGS="-std=c++17 -O2 -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g"
FLAGS="-std=c++17 -Og -stdlib=libc++ -Iinclude -frtti -Wfatal-errors -g"
clang++ $FLAGS -o main src2/main.cpp $SRC

View File

@ -70,17 +70,17 @@ struct CodeObject {
std::shared_ptr<SourceData> src;
Str name;
std::vector<Bytecode> codes;
std::vector<LineInfo> lines;
vector<Bytecode> codes;
vector<LineInfo> lines;
small_vector_2<PyVar, 8> consts; // constants
small_vector_2<StrName, 8> varnames; // local variables
int nlocals; // varnames.size()
NameDictInt varnames_inv;
std::vector<CodeBlock> blocks;
vector<CodeBlock> blocks;
NameDictInt labels;
std::vector<FuncDecl_> func_decls;
vector<FuncDecl_> func_decls;
int start_line;
int end_line;

View File

@ -5,7 +5,6 @@
#include <ctime>
#include <stdexcept>
#include <vector>
#include <string>
#include <chrono>
#include <string_view>

View File

@ -27,11 +27,11 @@ class Compiler {
bool unknown_global_scope; // for eval/exec() call
// for parsing token stream
int i = 0;
std::vector<Token> tokens;
vector<Token> tokens;
const Token& prev() const{ return tokens.at(i-1); }
const Token& curr() const{ return tokens.at(i); }
const Token& next() const{ return tokens.at(i+1); }
const Token& prev() const{ return tokens[i-1]; }
const Token& curr() const{ return tokens[i]; }
const Token& next() const{ return tokens[i+1]; }
const Token& err() const{
if(i >= tokens.size()) return prev();
return curr();

View File

@ -37,10 +37,10 @@ struct SourceData {
CompileMode mode;
Str source;
pod_vector<const char*> line_starts;
vector<const char*> line_starts;
bool is_precompiled;
std::vector<Str> _precompiled_tokens;
vector<Str> _precompiled_tokens;
SourceData(std::string_view source, const Str& filename, CompileMode mode);
SourceData(const Str& filename, CompileMode mode);

View File

@ -352,7 +352,7 @@ struct CallExpr: Expr{
Expr_ callable;
Expr_vector args;
// **a will be interpreted as a special keyword argument: {"**": a}
std::vector<std::pair<Str, Expr_>> kwargs;
vector<std::pair<Str, Expr_>> kwargs;
void emit_(CodeEmitContext* ctx) override;
};

View File

@ -8,8 +8,8 @@
namespace pkpy {
struct ManagedHeap{
std::vector<PyObject*> _no_gc;
std::vector<PyObject*> gen;
vector<PyObject*> _no_gc;
vector<PyObject*> gen;
VM* vm;
void (*_gc_on_delete)(VM*, PyObject*) = nullptr;
void (*_gc_marker_ex)(VM*) = nullptr;

View File

@ -30,7 +30,7 @@ constexpr const char* kTokens[] = {
};
using TokenValue = std::variant<std::monostate, i64, f64, Str>;
const TokenIndex kTokenCount = sizeof(kTokens) / sizeof(kTokens[0]);
const int kTokenCount = sizeof(kTokens) / sizeof(kTokens[0]);
constexpr TokenIndex TK(const char token[]) {
for(int k=0; k<kTokenCount; k++){
@ -99,7 +99,7 @@ struct Lexer {
const char* token_start;
const char* curr_char;
int current_line = 1;
std::vector<Token> nexts;
vector<Token> nexts;
stack_no_copy<int, small_vector_2<int, 8>> indents;
int brackets_level = 0;
@ -129,7 +129,7 @@ struct Lexer {
void SyntaxError(){ throw_err("SyntaxError", "invalid syntax"); }
void IndentationError(Str msg){ throw_err("IndentationError", msg); }
Lexer(VM* vm, std::shared_ptr<SourceData> src);
std::vector<Token> run();
vector<Token> run();
};

View File

@ -13,17 +13,11 @@ constexpr T default_invalid_value(){
else return Discarded();
}
template<typename T>
struct NameDictItem{
StrName first;
T second;
};
template<typename T>
struct NameDictImpl {
PK_ALWAYS_PASS_BY_POINTER(NameDictImpl)
using Item = NameDictItem<T>;
using Item = std::pair<StrName, T>;
static constexpr uint16_t kInitialCapacity = 16;
static_assert(is_pod_v<T>);
@ -166,19 +160,21 @@ while(!_items[i].first.empty()) { \
return val;
}
pod_vector<StrName> keys() const {
pod_vector<StrName> v;
array<StrName> keys() const {
array<StrName> v(_size);
int j = 0;
for(uint16_t i=0; i<_capacity; i++){
if(_items[i].first.empty()) continue;
v.push_back(_items[i].first);
new (&v[j++]) StrName(_items[i].first);
}
return v;
}
pod_vector<NameDictItem<T>> items() const{
pod_vector<NameDictItem<T>> v;
array<Item> items() const{
array<Item> v(_size);
int j = 0;
apply([&](StrName key, T val){
v.push_back(NameDictItem<T>{key, val});
new(&v[j++]) Item(key, val);
});
return v;
}

View File

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

View File

@ -77,8 +77,8 @@ struct Str{
int index(const Str& sub, int start=0) const;
Str replace(char old, char new_) const;
Str replace(const Str& old, const Str& new_, int count=-1) const;
pod_vector<std::string_view> split(const Str& sep) const;
pod_vector<std::string_view> split(char sep) const;
vector<std::string_view> split(const Str& sep) const;
vector<std::string_view> split(char sep) const;
int count(const Str& sub) const;
/*************unicode*************/
@ -127,8 +127,8 @@ struct StrName {
struct SStream{
PK_ALWAYS_PASS_BY_POINTER(SStream)
// pod_vector<T> is allocated by pool128 so the buffer can be moved into Str without a copy
pod_vector<char> buffer;
vector<char> buffer;
int _precision = -1;
bool empty() const { return buffer.empty(); }

View File

@ -35,8 +35,8 @@ struct Tuple {
void _gc_mark(VM*) const;
};
struct List: pod_vector<PyVar>{
using pod_vector<PyVar>::pod_vector;
struct List: public vector<PyVar>{
using vector<PyVar>::vector;
void _gc_mark(VM*) const;
Tuple to_tuple() const{

View File

@ -5,147 +5,216 @@
namespace pkpy{
struct explicit_copy_t {
explicit explicit_copy_t() = default;
};
template<typename T>
struct pod_vector{
static constexpr int SizeT = sizeof(T);
static constexpr int N = 128 / SizeT;
static constexpr int Growth = 2;
// static_assert(128 % SizeT == 0);
static_assert(is_pod_v<T>);
static_assert(N >= 4);
int _size;
int _capacity;
struct array{
T* _data;
int _size;
using size_type = int;
pod_vector(): _size(0), _capacity(N) {
_data = (T*)pool128_alloc(_capacity * SizeT);
}
// support initializer list
pod_vector(std::initializer_list<T> il): _size(il.size()), _capacity(std::max(N, _size)) {
_data = (T*)pool128_alloc(_capacity * SizeT);
for(int i=0; i<_size; i++) _data[i] = *(il.begin() + i);
}
pod_vector(int size): _size(size), _capacity(std::max(N, size)) {
_data = (T*)pool128_alloc(_capacity * SizeT);
}
pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) {
_data = (T*)pool128_alloc(_capacity * SizeT);
memcpy(_data, other._data, SizeT * _size);
}
pod_vector(pod_vector&& other) noexcept {
_size = other._size;
_capacity = other._capacity;
_data = other._data;
array(): _data(nullptr), _size(0) {}
array(int size): _data((T*)malloc(sizeof(T) * size)), _size(size) {}
array(array&& other) noexcept: _data(other._data), _size(other._size) {
other._data = nullptr;
other._size = 0;
}
array(const array& other) = delete;
array(explicit_copy_t, const array& other) {
_data = (T*)malloc(sizeof(T) * other._size);
_size = other._size;
for(int i=0; i<_size; i++) _data[i] = other._data[i];
}
pod_vector& operator=(pod_vector&& other) noexcept {
if(_data!=nullptr) pool128_dealloc(_data);
_size = other._size;
_capacity = other._capacity;
array& operator=(array&& other) noexcept{
if(_data){
std::destroy(begin(), end());
free(_data);
}
_data = other._data;
_size = other._size;
other._data = nullptr;
other._size = 0;
return *this;
}
// remove copy assignment
pod_vector& operator=(const pod_vector& other) = delete;
array& operator=(const array& other) = delete;
template<typename __ValueT>
void push_back(__ValueT&& t) {
if (_size == _capacity) reserve(_capacity*Growth);
_data[_size++] = std::forward<__ValueT>(t);
T& operator[](int i) {
PK_DEBUG_ASSERT(i>=0 && i<_size);
return _data[i];
}
template<typename... Args>
void emplace_back(Args&&... args) {
if (_size == _capacity) reserve(_capacity*Growth);
new (&_data[_size++]) T(std::forward<Args>(args)...);
const T& operator[](int i) const {
PK_DEBUG_ASSERT(i>=0 && i<_size);
return _data[i];
}
void reserve(int cap){
if(cap <= _capacity) return;
_capacity = cap;
T* old_data = _data;
_data = (T*)pool128_alloc(_capacity * SizeT);
if(old_data != nullptr){
memcpy(_data, old_data, SizeT * _size);
pool128_dealloc(old_data);
}
}
void pop_back() { _size--; }
T popx_back() { T t = std::move(_data[_size-1]); _size--; return t; }
void extend(const pod_vector& other){
for(int i=0; i<other.size(); i++) push_back(other[i]);
}
void extend(const T* begin, const T* end){
for(auto it=begin; it!=end; it++) push_back(*it);
}
T& operator[](int index) { return _data[index]; }
const T& operator[](int index) const { return _data[index]; }
T* begin() { return _data; }
T* end() { return _data + _size; }
const T* begin() const { return _data; }
const T* end() const { return _data + _size; }
T& back() { return _data[_size - 1]; }
const T& back() const { return _data[_size - 1]; }
bool empty() const { return _size == 0; }
int size() const { return _size; }
T* data() { return _data; }
const T* data() const { return _data; }
void clear() { _size=0; }
template<typename __ValueT>
void insert(int i, __ValueT&& val){
if (_size == _capacity) reserve(_capacity*Growth);
for(int j=_size; j>i; j--) _data[j] = _data[j-1];
_data[i] = std::forward<__ValueT>(val);
_size++;
}
void erase(int i){
for(int j=i; j<_size-1; j++) _data[j] = _data[j+1];
_size--;
}
void reverse(){
std::reverse(_data, _data+_size);
}
void resize(int size){
if(size > _capacity) reserve(size);
_size = size;
}
T* begin() const{ return _data; }
T* end() const{ return _data + _size; }
std::pair<T*, int> detach() noexcept {
T* p = _data;
int size = _size;
std::pair<T*, int> retval(_data, _size);
_data = nullptr;
_size = 0;
return {p, size};
return retval;
}
~pod_vector() {
if(_data != nullptr) pool128_dealloc(_data);
~array() {
if(_data){
std::destroy(begin(), end());
free(_data);
}
}
};
template <typename T, typename Container=std::vector<T>>
template<typename T>
struct vector{
T* _data;
int _capacity;
int _size;
using size_type = int;
vector(): _data(nullptr), _capacity(0), _size(0) {}
vector(int size):
_data((T*)malloc(sizeof(T) * size)),
_capacity(size), _size(size) {}
vector(vector&& other) noexcept:
_data(other._data), _capacity(other._capacity), _size(other._size) {
other._data = nullptr;
other._capacity = 0;
other._size = 0;
}
vector(const vector& other) = delete;
vector(explicit_copy_t, const vector& other):
_data((T*)malloc(sizeof(T) * other._size)),
_capacity(other._size), _size(other._size) {
for(int i=0; i<_size; i++) _data[i] = other._data[i];
}
// allow move
vector& operator=(vector&& other) noexcept{
if(_data){
std::destroy(begin(), end());
free(_data);
}
new (this) vector(std::move(other));
return *this;
}
// disallow copy
vector& operator=(const vector& other) = delete;
bool empty() const { return _size == 0; }
int size() const { return _size; }
int capacity() const { return _capacity; }
T& back() { return _data[_size-1]; }
T* begin() const { return _data; }
T* end() const { return _data + _size; }
T* data() const { return _data; }
void reserve(int cap){
if(cap < 4) cap = 4; // minimum capacity
if(cap <= capacity()) return;
T* new_data = (T*)malloc(sizeof(T) * cap);
if constexpr(std::is_trivially_copyable_v<T>){
memcpy(new_data, _data, sizeof(T) * _size);
}else{
for(int i=0; i<_size; i++){
new(&new_data[i]) T(std::move(_data[i]));
_data[i].~T();
}
}
if(_data) free(_data);
_data = new_data;
_capacity = cap;
}
void resize(int size){
reserve(size);
_size = size;
}
void push_back(const T& t){
if(_size == _capacity) reserve(_capacity * 2);
new (&_data[_size++]) T(t);
}
void push_back(T&& t){
if(_size == _capacity) reserve(_capacity * 2);
new(&_data[_size++]) T(std::move(t));
}
template<typename... Args>
void emplace_back(Args&&... args){
if(_size == _capacity) reserve(_capacity * 2);
new(&_data[_size++]) T(std::forward<Args>(args)...);
}
T& operator[](int i) { return _data[i]; }
const T& operator[](int i) const { return _data[i]; }
void extend(T* begin, T* end){
int n = end - begin;
reserve(_size + n);
for(int i=0; i<n; i++) new(&_data[_size++]) T(begin[i]);
}
void insert(int index, const T& t){
if(_size == _capacity) reserve(_capacity * 2);
for(int i=_size; i>index; i--) _data[i] = std::move(_data[i-1]);
_data[index] = t;
_size++;
}
void erase(int index){
for(int i=index; i<_size-1; i++) _data[i] = std::move(_data[i+1]);
_size--;
}
void pop_back(){
PK_DEBUG_ASSERT(_size > 0);
_size--;
if constexpr(!std::is_trivially_destructible_v<T>){
_data[_size].~T();
}
}
void clear(){
std::destroy(begin(), end());
_size = 0;
}
std::pair<T*, int> detach() noexcept {
std::pair<T*, int> retval(_data, _size);
_data = nullptr;
_capacity = 0;
_size = 0;
return retval;
}
void swap(vector& other){
std::swap(_data, other._data);
std::swap(_capacity, other._capacity);
std::swap(_size, other._size);
}
~vector(){
if(_data){
std::destroy(begin(), end());
free(_data);
}
}
};
template <typename T, typename Container=vector<T>>
class stack{
Container vec;
public:
@ -167,7 +236,7 @@ public:
const Container& container() const { return vec; }
};
template <typename T, typename Container=std::vector<T>>
template <typename T, typename Container=vector<T>>
class stack_no_copy: public stack<T, Container>{
public:
stack_no_copy() = default;

View File

@ -74,7 +74,7 @@ struct PyTypeInfo{
PyTypeInfo(PyObject* obj, Type base, PyObject* mod, StrName name, bool subclass_enabled, Vt vt={}):
obj(obj), base(base), mod(mod), name(name), subclass_enabled(subclass_enabled), vt(vt) {}
std::vector<StrName> annotated_fields = {};
vector<StrName> annotated_fields = {};
// unary operators
Str (*m__repr__)(VM* vm, PyVar) = nullptr;
@ -127,8 +127,8 @@ struct PyTypeInfo{
struct ImportContext{
PK_ALWAYS_PASS_BY_POINTER(ImportContext)
std::vector<Str> pending;
std::vector<bool> pending_is_init; // a.k.a __init__.py
vector<Str> pending;
vector<bool> pending_is_init; // a.k.a __init__.py
ImportContext() {}
@ -159,7 +159,7 @@ public:
ManagedHeap heap;
ValueStack s_data;
CallStack callstack;
std::vector<PyTypeInfo> _all_types;
vector<PyTypeInfo> _all_types;
NameDict _modules; // loaded modules
std::map<StrName, Str> _lazy_modules; // lazy loaded modules

View File

@ -931,7 +931,7 @@ __NEXT_STEP:
if(_1 == StopIteration) break;
extras.push_back(_1);
}
PUSH(VAR(extras));
PUSH(VAR(std::move(extras)));
} DISPATCH()
/*****************************************/
case OP_BEGIN_CLASS:{
@ -1056,7 +1056,9 @@ __NEXT_STEP:
Exception& _e = PK_OBJ_GET(Exception, e_obj);
bool is_base_frame_to_be_popped = frame == base_frame;
__pop_frame();
if(callstack.empty()) throw _e; // propagate to the top level
if(callstack.empty()){
throw std::move(_e); // propagate to the top level
}
frame = &callstack.top();
PUSH(e_obj);
if(is_base_frame_to_be_popped){

View File

@ -1292,7 +1292,7 @@ __EAT_DOTS_END:
}
int count = deserializer.read_count();
std::vector<Str>& precompiled_tokens = lexer.src->_precompiled_tokens;
vector<Str>& precompiled_tokens = lexer.src->_precompiled_tokens;
for(int i=0; i<count; i++){
precompiled_tokens.push_back(deserializer.read_string('\n'));
}
@ -1379,7 +1379,7 @@ __EAT_DOTS_END:
PyVar e_obj = vm->call(vm->builtins->attr(type), VAR(msg));
Exception& e = PK_OBJ_GET(Exception, e_obj);
e.st_push(src, lineno, cursor, "");
throw e;
throw std::move(e);
}
std::string_view TokenDeserializer::read_string(char c){

View File

@ -73,7 +73,7 @@ __NEXT_LINE:
if(ret.size() == 0){
vm->ValueError("empty csvfile");
}
List header = CAST(List&, ret[0]);
const List& header = CAST(List&, ret[0]);
List new_ret;
for(int i=1; i<ret.size(); i++){
const List& row = CAST(List&, ret[i]);

View File

@ -66,14 +66,16 @@ namespace pkpy{
}
Str Exception::summary() const {
stack<ExceptionLine> st(stacktrace);
SStream ss;
if(is_re) ss << "Traceback (most recent call last):\n";
while(!st.empty()) {
ss << st.top().snapshot() << '\n';
st.pop();
// while(!st.empty()) {
// ss << st.top().snapshot() << '\n';
// st.pop();
// }
const auto& container = stacktrace.container();
for(int i=container.size()-1; i>=0; i--){
ss << container[i].snapshot() << '\n';
}
// TODO: allow users to override the behavior
if (!msg.empty()) ss << type.sv() << ": " << msg;
else ss << type.sv();
return ss.str();

View File

@ -3,7 +3,8 @@
namespace pkpy{
int ManagedHeap::sweep(){
std::vector<PyObject*> alive;
vector<PyObject*> alive;
alive.reserve(gen.size() / 2);
for(PyObject* obj: gen){
if(obj->gc_marked){
obj->gc_marked = false;

View File

@ -485,7 +485,7 @@ static bool is_unicode_Lo_char(uint32_t c) {
this->indents.push(0);
}
std::vector<Token> Lexer::run() {
vector<Token> Lexer::run() {
PK_ASSERT(curr_char == src->source.c_str());
while (lex_one_token());
return std::move(nexts);

View File

@ -622,7 +622,7 @@ void __init_builtins(VM* _vm) {
const Str& self = _CAST(Str&, args[0]);
const Str& sep = CAST(Str&, args[1]);
if(sep.empty()) vm->ValueError("empty separator");
pod_vector<std::string_view> parts;
vector<std::string_view> parts;
if(sep.size == 1){
parts = self.split(sep[0]);
}else{
@ -635,8 +635,7 @@ void __init_builtins(VM* _vm) {
_vm->bind(_vm->_t(VM::tp_str), "splitlines(self)", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]);
pod_vector<std::string_view> parts;
parts = self.split('\n');
vector<std::string_view> parts = self.split('\n');
List ret(parts.size());
for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i]));
return VAR(std::move(ret));
@ -797,7 +796,9 @@ void __init_builtins(VM* _vm) {
});
}
bool reverse = CAST(bool, args[2]);
if(reverse) self.reverse();
if(reverse){
std::reverse(self.begin(), self.end());
}
return vm->None;
});
@ -892,7 +893,9 @@ void __init_builtins(VM* _vm) {
List& self = _CAST(List&, args[0]);
if(args.size() == 1+0){
if(self.empty()) vm->IndexError("pop from empty list");
return self.popx_back();
PyVar retval = self.back();
self.pop_back();
return retval;
}
if(args.size() == 1+1){
i64 index = CAST(i64, args[1]);
@ -936,7 +939,7 @@ void __init_builtins(VM* _vm) {
int n = _CAST(int, _1);
List result;
result.reserve(self.size() * n);
for(int i = 0; i < n; i++) result.extend(self);
for(int i = 0; i < n; i++) result.extend(self.begin(), self.end());
return VAR(std::move(result));
});
_vm->bind_func(VM::tp_list, "__rmul__", 2, [](VM* vm, ArgsView args) {
@ -945,7 +948,7 @@ void __init_builtins(VM* _vm) {
int n = _CAST(int, args[1]);
List result;
result.reserve(self.size() * n);
for(int i = 0; i < n; i++) result.extend(self);
for(int i = 0; i < n; i++) result.extend(self.begin(), self.end());
return VAR(std::move(result));
});
@ -964,7 +967,10 @@ void __init_builtins(VM* _vm) {
return vm->None;
});
_vm->bind_func(VM::tp_list, "copy", 1, PK_LAMBDA(VAR(_CAST(List, args[0]))));
_vm->bind_func(VM::tp_list, "copy", 1, [](VM* vm, ArgsView args){
const List& self = _CAST(List&, args[0]);
return VAR(List(explicit_copy_t(), self));
});
#define BIND_RICH_CMP(name, op, _t, _T) \
_vm->bind__##name##__(_vm->_t, [](VM* vm, PyVar lhs, PyVar rhs){ \
@ -993,8 +999,8 @@ void __init_builtins(VM* _vm) {
_vm->bind__add__(VM::tp_list, [](VM* vm, PyVar _0, PyVar _1) {
const List& self = _CAST(List&, _0);
const List& other = CAST(List&, _1);
List new_list(self); // copy construct
new_list.extend(other);
List new_list(explicit_copy_t(), self);
new_list.extend(other.begin(), other.end());
return VAR(std::move(new_list));
});
@ -1637,7 +1643,7 @@ void VM::__post_init_builtin_types(){
try{
// initialize dummy func_decl for exec/eval
CodeObject_ dynamic_co = compile("def _(): pass", "<dynamic>", EXEC_MODE);
__dynamic_func_decl = dynamic_co->func_decls.at(0);
__dynamic_func_decl = dynamic_co->func_decls[0];
// initialize builtins
CodeObject_ code = compile(kPythonLibs_builtins, "<builtins>", EXEC_MODE);
this->_exec(code, this->builtins);

View File

@ -40,7 +40,7 @@ void LineProfiler::_step(int callstack_size, Frame* frame){
}
}
frames.top().prev_record = &file_records.at(line);
frames.top().prev_record = &file_records[line];
}
void LineProfiler::_step_end(int callstack_size, Frame* frame, int line){
@ -87,11 +87,11 @@ Str LineProfiler::stats(){
int end_line = decl->code->end_line;
if(start_line == -1 || end_line == -1) continue;
std::string_view filename = decl->code->src->filename.sv();
std::vector<_LineRecord>& file_records = records[filename];
vector<_LineRecord>& file_records = records[filename];
if(file_records.empty()) continue;
clock_t total_time = 0;
for(int line = start_line; line <= end_line; line++){
total_time += file_records.at(line).time;
total_time += file_records[line].time;
}
ss << "Total time: " << (f64)total_time / CLOCKS_PER_SEC << "s\n";
ss << "File: " << filename << "\n";
@ -99,7 +99,7 @@ Str LineProfiler::stats(){
ss << "Line # Hits Time Per Hit % Time Line Contents\n";
ss << "==============================================================\n";
for(int line = start_line; line <= end_line; line++){
const _LineRecord& record = file_records.at(line);
const _LineRecord& record = file_records[line];
if(!record.is_valid()) continue;
ss << left_pad(std::to_string(line), 6);
if(record.hits == 0){

View File

@ -190,7 +190,7 @@ struct Random{
PyVar* data = view.begin();
int size = view.size();
if(size == 0) vm->IndexError("cannot choose from an empty sequence");
pod_vector<f64> cum_weights(size);
array<f64> cum_weights(size);
if(args[2] == vm->None){
for(int i = 0; i < size; i++) cum_weights[i] = i + 1;
}else{

View File

@ -333,8 +333,8 @@ int utf8len(unsigned char c, bool suppress){
return _byte_index_to_unicode(size);
}
pod_vector<std::string_view> Str::split(const Str& sep) const{
pod_vector<std::string_view> result;
vector<std::string_view> Str::split(const Str& sep) const{
vector<std::string_view> result;
std::string_view tmp;
int start = 0;
while(true){
@ -349,8 +349,8 @@ int utf8len(unsigned char c, bool suppress){
return result;
}
pod_vector<std::string_view> Str::split(char sep) const{
pod_vector<std::string_view> result;
vector<std::string_view> Str::split(char sep) const{
vector<std::string_view> result;
int i = 0;
for(int j = 0; j < size; j++){
if(data[j] == sep){
@ -404,29 +404,35 @@ int utf8len(unsigned char c, bool suppress){
}
Str SStream::str(){
#if 0
// after this call, the buffer is no longer valid
buffer.reserve(buffer.size() + 1); // allocate one more byte for '\0'
buffer[buffer.size()] = '\0'; // set '\0'
return Str(buffer.detach());
#else
#warning "SStream::str() needs to be optimized"
buffer.push_back('\0');
return Str(buffer.data(), buffer.size()-1);
#endif
}
SStream& SStream::operator<<(const Str& s){
buffer.extend(s.begin(), s.end());
for(char c: s) buffer.push_back(c);
return *this;
}
SStream& SStream::operator<<(const char* s){
buffer.extend(s, s + strlen(s));
while(*s) buffer.push_back(*s++);
return *this;
}
SStream& SStream::operator<<(const std::string& s){
buffer.extend(s.data(), s.data() + s.size());
for(char c: s) buffer.push_back(c);
return *this;
}
SStream& SStream::operator<<(std::string_view s){
buffer.extend(s.data(), s.data() + s.size());
for(char c: s) buffer.push_back(c);
return *this;
}
@ -459,7 +465,7 @@ int utf8len(unsigned char c, bool suppress){
buffer.push_back('-');
val = -val;
}
char* begin = buffer.end();
auto begin = buffer.end();
while(val){
buffer.push_back('0' + val % 10);
val /= 10;

View File

@ -330,7 +330,7 @@ namespace pkpy{
PyVar VM::py_import(Str path, bool throw_err){
if(path.empty()) vm->ValueError("empty module name");
static auto f_join = [](const pod_vector<std::string_view>& cpnts){
static auto f_join = [](const vector<std::string_view>& cpnts){
SStream ss;
for(int i=0; i<cpnts.size(); i++){
if(i != 0) ss << ".";
@ -346,7 +346,7 @@ namespace pkpy{
Str curr_path = __import_context.pending.back();
bool curr_is_init = __import_context.pending_is_init.back();
// convert relative path to absolute path
pod_vector<std::string_view> cpnts = curr_path.split('.');
vector<std::string_view> cpnts = curr_path.split('.');
int prefix = 0; // how many dots in the prefix
for(int i=0; i<path.length(); i++){
if(path[i] == '.') prefix++;
@ -366,7 +366,7 @@ namespace pkpy{
PyVar ext_mod = _modules.try_get(name);
if(ext_mod != nullptr) return ext_mod;
pod_vector<std::string_view> path_cpnts = path.split('.');
vector<std::string_view> path_cpnts = path.split('.');
// check circular import
if(__import_context.pending.size() > 128){
ImportError("maximum recursion depth exceeded while importing");
@ -769,7 +769,7 @@ Str VM::disassemble(CodeObject_ co){
return s + std::string(n - s.length(), ' ');
};
std::vector<int> jumpTargets;
vector<int> jumpTargets;
for(int i=0; i<co->codes.size(); i++){
Bytecode byte = co->codes[i];
if(byte.is_forward_jump()){
@ -1442,7 +1442,7 @@ void VM::_error(PyVar e_obj){
Exception& e = PK_OBJ_GET(Exception, e_obj);
if(callstack.empty()){
e.is_re = false;
throw e;
throw std::move(e);
}
PUSH(e_obj);
__raise_exc();
@ -1665,7 +1665,7 @@ void VM::__breakpoint(){
bool show_headers = true;
while(true){
std::vector<LinkedFrame*> frames;
vector<LinkedFrame*> frames;
LinkedFrame* lf = callstack._tail;
while(lf != nullptr){
frames.push_back(lf);