0% found this document useful (0 votes)
41 views11 pages

Writing A Python Interpreter For Fun and Profit - Shy Shalom

Uploaded by

alan88w
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views11 pages

Writing A Python Interpreter For Fun and Profit - Shy Shalom

Uploaded by

alan88w
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Lightning Talk:

Writing a Python
Interpreter for Fun and
Profit

Shy Shalom
Intigua Inc., Israel
[email protected]
Dynamically typed
Interpreted
CPython (python.org)

Pops a,b
Byte-code Adds
Push result
PUSH a
Python text PUSH b
BINARY_ADD
def func(a, b): POP c
c = a + b CPython CPython
print c compiler PUSH c Interpreter
return c PRINT_ITEM
PRINT_NEWLINE
PUSH c
RETURN_VALUE
object

Everything
dict list bool int str
Is an Object
module class method func

a = "Hello!"
b = a

Everything
Is Reference a
object

Counted b
count=2
type=str
"Hello!"

shared_ptr<>
Python CPython byte My
text compiler code Interpreter

void test()
{
Interpreter vm
Ref module = vm.import(R"**(
def pyfunc(a,b):
return a+b
)**");
Ref resObj = module.call("pyfunc", 1, 2);
int result = extract<int>(resObj);
}
int cxxfunc(const string& msg) {
cout << msg;
return 42
}

void test()
{
Interpreter vm
vm.builtins.def("cxxfunc", cxxfunc);
Ref module = vm.import(R"**(
def pyfunc(a,b):
cxxfunc("Hello!")
return a+b
)**");
Ref resObj = module.call("pyfunc", 1, 2);
}
struct Thing {
void action(int a, int b);
};
void test()
{
Interpreter vm
Ref m = vm.builtins
Ref c = m.class_<Thing>("Thing")
.def("action", &Thing::action);
Thing t;
Ref wrap_t = c.wrapInstance(t)
wrap_t.call("action", 1, 2)
}
void unpack(vector<Ref>& v) {}

template<typename T, typename ...Args>


void unpack(vector<Ref>& v, const T&& a, const Args&&... args) {
v.push_back(objectFromT(std::forward<T>(a)));
unpack(v, args...);
}

Template<typename ...Args>
Ref call(const string& name, const Args&&... args) {
vector<Ref> argv;
unpack(argv, args...);
runCode(lookup(name), argv);
}
Ref runCode(ByteCode code, vector<Ref> args) {
Frame f(args)
int pc = 0
while(true) {
byte opcode = code[pc];
byte param = code[pc + 1]
switch(opcode) { runCode()
case PUSH:
f.stack.push(f.vars[param]);
break;
case POP:
f.vars[param] = f.stack.pop(); runCode()
break;
case JUMP_TO:
pc = param
continue;
case CALL_FUNCTION: runCode()
runCode(pop(), popArgs(param))
break;
case RETURN_VALUE:
return frame.pop();
}
pc += 2;
}
}
(boost::intrusive_ptr)
struct Object { struct Ref {
int m_refcount; Object *m_ptr;
}; };

struct Str : Object { struct List : Object {


std::string v; std::vector<Ref> v;
}; };

struct Int : Object { struct Dict : Object {


int v; std::map<int, Ref> v;
}; };

template<typename T>
T extract(Ref ref);

template<>
std::string extract(Ref ref) {
return dynamic_cast<Str>(ref.m_ptr)->v;
}
Why?
• Need scripting but don’t want to write a compiler?
• LUA is too strange, Everybody knows python.

CPython Your Interpreter


~350,000 loc ~2000 loc
Global State Multiple instance
Policy for real multi
GIL (global interpreter lock)
threading
- Dump all, start new
Garbage Collection
- Memory snapshot
C API, C code
C++11
+boost::python

You might also like