Bootstrap

【python源码剖析】——最小的python模拟器smallpython

code

#include<iostream>
#include<string.h>
#include<iterator>
#include<stdlib.h>
#include<stdio.h>
#include<memory>
#include<map>
#include<ctype.h>
using namespace std;
#define PyObject_HEAD							\
	int refCount; \
	struct tagPyTypeObject *type

#define PyObject_HEAD_INIT(typePtr) \
	0,typePtr

typedef struct tagPyObject
{
	PyObject_HEAD;
}PyObject;

typedef void (*PrintFun)(PyObject*object);
typedef PyObject* (*AddFun)(PyObject* left,PyObject*right);
typedef long (*HashFun)(PyObject* object);

typedef struct tagPyTypeObject
{
	PyObject_HEAD;
	char* name;
	PrintFun print;
	AddFun add;
	HashFun hash;
}PyTypeObject;

PyTypeObject PyType_Type =
	{
		PyObject_HEAD_INIT(&PyType_Type),
		"type",
		0,
		0,
		0
	};

typedef struct tagIntObject
{
	PyObject_HEAD;
	int value;
}PyIntObject;

static  void int_print(PyObject*object);
static PyObject* int_add(PyObject*left,PyObject* right);
static long int_hash(PyObject* object);

PyTypeObject PyInt_Type =
	{
		PyObject_HEAD_INIT(&PyType_Type),
		"int",
		int_print,
		int_add,
		int_hash
	};


PyObject* PyInt_Create(int value)
{
	PyIntObject *object = new PyIntObject;
	object->refCount = 1;
	object->type = &PyInt_Type;
	object->value = value;
	return (PyObject*)object;
}

static  void int_print(PyObject*object)
{
	PyIntObject* intObject = (PyIntObject*)object;
	printf("%d\n",intObject->value);
}

static PyObject* int_add(PyObject*left,PyObject* right)
{
	PyIntObject* leftInt = (PyIntObject*)left;
	PyIntObject* rightInt = (PyIntObject*)right;
	PyIntObject* result = (PyIntObject*)PyInt_Create(0);
	if(result == NULL)
		{
			printf("we have no enough memory");
			exit(1);
		}
	else
		{
			result->value = leftInt->value+rightInt->value;
		}
	return (PyObject*)result;
}

static long int_hash(PyObject* object)
{
	return (long)((PyIntObject*)object)->value;
}


typedef struct tagPyStrObject
{
	PyObject_HEAD;
	int length;
	long hashValue;
	char value[50];
}PyStringObject;
static void string_print(PyObject*object);
static long string_hash(PyObject*object);
static PyObject* string_add(PyObject*left, PyObject*right);
PyTypeObject PyString_Type =
	{
		PyObject_HEAD_INIT(&PyType_Type),
		"str",
		string_print,
		string_add,
		string_hash
	};
PyObject* PyStr_Create(const char*value)
{
	PyStringObject* object = new PyStringObject;
	object->refCount = 1;
	object->type = &PyString_Type;
	object->length = (value ==NULL? 0: strlen(value));
	object->hashValue = -1;
	memset(object->value,0,50);
	if(value!=NULL)
		{
			strcpy(object->value,value);
		}
	return (PyObject*)object;
}

static void string_print(PyObject*object)
{
	PyStringObject*strObject = (PyStringObject*)object;
	printf("%s\n",strObject->value);
}

static long string_hash(PyObject*object)
{
	PyStringObject* strObject = (PyStringObject*)object;
	register int len;
	register unsigned char* p;
	register long x;

	if(strObject->hashValue!=-1)
		return strObject->hashValue;
	len = strObject->length;
	p = (unsigned char*)strObject->value;
	x = *p<<7;
	while(--len>0)
		x = (1000003*x)^*p++;
	x^=strObject->length;
	if(x==-1)
		x=-2;
	strObject->hashValue = x;
	return x;
}

static PyObject* string_add(PyObject*left, PyObject*right)
{
	PyStringObject*leftStr = (PyStringObject*)left;
	PyStringObject*rightStr = (PyStringObject*)right;
	PyStringObject*result = (PyStringObject*)PyStr_Create(NULL);
	if(result == NULL)
		{
			printf("we have no enough memory");
			exit(1);
		}
	else
		{
			strcpy(result->value,leftStr->value);
			strcat(result->value,rightStr->value);//something in book wrong
		}
	return (PyObject*)result;
}




typedef struct tagPyDictObject
{
	PyObject_HEAD;
	map<long,PyObject*>dict;
}PyDictObject;
PyDictObject *m_LocalEnvironment= new PyDictObject;
static void dict_print(PyObject*object);
PyTypeObject PyDict_Type =
	{
		PyObject_HEAD_INIT(&PyType_Type),
		"dict",
		dict_print,
		0,
		0
	};
PyObject*PyDict_Create()
{
	PyDictObject*object = new PyDictObject;
	object->refCount = 1;
	object->type = &PyDict_Type;
	return (PyObject*)object;
}

PyObject* PyDict_GetItem(PyObject*target,PyObject*key)
{
	long keyHashValue = (key->type)->hash(key);				// pyobject的hash值
	map<long,PyObject*>&dict = ((PyDictObject*)target)->dict;	// 遍历pydictobject获得对象
	map<long,PyObject*>::iterator it= dict.find(keyHashValue);
	map<long,PyObject*>::iterator end= dict.end();
	if(it==end)
		return NULL;
	return it->second;
	
}

int PyDict_SetItem(PyObject*target,PyObject*key,PyObject*value)
{
	long keyHashValue = (key->type)->hash(key);
	PyDictObject* dictObject = (PyDictObject*)target;
	(dictObject->dict)[keyHashValue]=value;
	return 0;
}

static void dict_print(PyObject*object)
{
	PyDictObject*dictObject = (PyDictObject*)object;
	printf("(");
	map<long,PyObject*>::iterator it =(dictObject->dict).begin();
	map<long,PyObject*>::iterator end =(dictObject->dict).end();
	for(;it!=end;++it)
		{
			printf("%ld: ",it->first);
			PyObject*value=it->second;
			(value->type)->print(value);
			printf(", ");
		}
	printf(")\n");
}


PyObject* GetObjectBySymbol(string &symbol)
{
	PyObject* key = PyStr_Create(symbol.c_str());		// 新创建一个对象
	PyObject *value = PyDict_GetItem((PyObject*)m_LocalEnvironment,key);		// 在字典中搜索对象
	if(value == NULL)
		{
			cout<<"[Error]: "<<symbol<<" is not defined!"<<endl;
			return NULL;
		}
	return value;
}
bool IsSourceAllDigit(string source)
{
	bool result =true;
	for(int i=0;i<source.size();i++)
		{
			result = isdigit(source[i]);
			if(result == false)
				break;
		}
	return result;
	
}
void ExcuteAdd(string&target,string&source)
{
	string::size_type pos;
	PyObject* strValue = NULL;
	PyObject* resultValue = NULL;
	if(IsSourceAllDigit(source))
		{
			PyObject* intValue = PyInt_Create(atoi(source.c_str()));
			PyObject* key = PyStr_Create(target.c_str());
			PyDict_SetItem((PyObject*)m_LocalEnvironment,key,intValue);
		}
	else if(source.find("\"") !=string::npos)
		{
			strValue = PyStr_Create(source.substr(1,source.size()-2).c_str());
			PyObject* key = PyStr_Create(target.c_str());
			PyDict_SetItem((PyObject*)m_LocalEnvironment,key,strValue);
		}
	else if((pos = source.find("+"))!=string::npos)
		{
			string left = source.substr(0,pos);
			string right = source.substr(pos+1);
			PyObject*leftObject = GetObjectBySymbol(left);
			PyObject*rightObject = GetObjectBySymbol(right);
			if(leftObject!=NULL&&rightObject!=NULL&&leftObject->type==rightObject->type)
				{
					resultValue = (leftObject->type)->add(leftObject,rightObject);		// 返回结果对象指针
					PyObject*key = PyStr_Create(target.c_str());						// 创建结果对象指针
					PyDict_SetItem((PyObject*)m_LocalEnvironment,key,resultValue);
				}
			//(m_LocalEnvironment->type)->print((PyObject*)m_LocalEnvironment);
		}
}
void ExcutePrint(string symbol)
{
	PyObject* object = GetObjectBySymbol(symbol);
	if(object!=NULL)
		{
			PyTypeObject* type = object->type;
			type->print(object);
		}
}
void ExcuteCommand(string&command)
{
	string::size_type pos = 0;
	if((pos = command.find("print "))!=string::npos)
		{
			ExcutePrint(command.substr(6));
		}
	else if((pos=command.find(" = "))!=string::npos)
		{
			string target = command.substr(0,pos);
			string source = command.substr(pos+3);
			ExcuteAdd(target,source);
		}
}





const char* info = "*********Python Research*********\n";
const char* prompt = ">>>";
string m_Command;
void Excute()
{
	cout<<info;
	cout<<prompt;
	while(getline(cin,m_Command))
		{
			if(m_Command.size()==0)
				{
					cout<<prompt;
					continue;
				}
			else if(m_Command == "exit")
				{
					return;
				}
			else
				{
					ExcuteCommand(m_Command);
				}
			cout<<prompt;
		}
}
int main()
{
	Excute();
	return 0;
}

编译:
g++ main.cpp

测试
./a.out

>>>s1 = "robert"
>>>t1 = "python"
>>>r = s1+t1
>>>print r
robertpython

注意:
后面的字符串相加和书上的原始例子变量名有区别,因为stringobject的hash函数有问题。s1,s2的命令hash值是一样的。

;