(Python学習6)Small Python

8005 ワード

実は『Pythonソース剖析中の』です
少しの変更と補足
#include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <iostream>


using namespace std;


#define PyObject_Head	\
	int ob_refcnt;	\
struct _typeobject * ob_type;


#define PyObject_Head_Init(typePtr)	\
	0, typePtr,


// ----    ---------------------------------------
typedef struct _object{
	PyObject_Head
}PyObject;


// ----    ---------------------------------------
typedef PyObject* (*FunAdd)(PyObject*, PyObject*);
typedef void (*FunPrint)(PyObject*);
typedef long (*FunHash)(PyObject*);


typedef struct _typeobject{
	PyObject_Head
	char * name;
	FunAdd pyAdd;
	FunPrint pyPrint;
	FunHash pyHash;
}PyTypeObject;


PyTypeObject PyType_Tpye =
{
	PyObject_Head_Init(&PyType_Tpye)
	"Type",
	0,
	0,
	0
};


// ----    --------------------------------------
typedef struct _intobject{
	PyObject_Head
	int val;
}PyIntObject;


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


PyTypeObject PyInt_Type =
{
	PyObject_Head_Init(&PyType_Tpye)
	"int",
	int_add,
	int_print,
	int_hash,
};


PyObject* PyInt_Create(int val){
	PyIntObject * int_object = new PyIntObject;
	int_object->ob_refcnt = 1;
	int_object->ob_type = &PyInt_Type;
	int_object->val = val;
	return (PyObject*)int_object;
}


PyObject* int_add(PyObject* left, PyObject* right){
	PyIntObject * int_result = (PyIntObject*)PyInt_Create(0);
	PyIntObject * int_left = (PyIntObject*)left;
	PyIntObject * int_right = (PyIntObject*)right;
	int_result->val = int_left->val + int_right->val;
	return (PyObject*)int_result;
}


void int_print(PyObject * object){
	PyIntObject * int_object = (PyIntObject*)object;
	printf("%d
", int_object->val); } long int_hash(PyObject * object){ PyIntObject * int_object = (PyIntObject*)object; long x = int_object->val; if (x == -1) x = -2; return x; } //---- ----------------------------------------------- typedef struct _strobject{ PyObject_Head int length; long hash; char val[50]; }PyStrObject; PyObject* str_add(PyObject* left, PyObject* right); void str_print(PyObject * object); long str_hash(PyObject * object); PyTypeObject PyStr_Type = { PyObject_Head_Init(&PyType_Tpye) "string", str_add, str_print, str_hash, }; PyObject * PyStr_Create(const char * val){ PyStrObject* str_object = new PyStrObject; str_object->ob_refcnt = 1; str_object->ob_type = &PyStr_Type; str_object->length = (val == NULL ? 0 : strlen(val)); str_object->hash = -1; memset(str_object->val, 0, 50); if (val != NULL) strcpy(str_object->val, val); return (PyObject*)str_object; } PyObject * str_add(PyObject* left, PyObject* right){ PyStrObject * str_result = (PyStrObject*)PyStr_Create(NULL); PyStrObject * str_left = (PyStrObject*)left; PyStrObject * str_right = (PyStrObject*)right; strcpy(str_result->val, str_left->val); strcat(str_result->val, str_right->val); return (PyObject*)str_result; } void str_print(PyObject* object){ PyStrObject* str_object = (PyStrObject*)object; printf("%s
", str_object->val); } long str_hash(PyObject * object){ PyStrObject *str_object = (PyStrObject*)object; if (str_object->hash != -1) { return str_object->hash; } int len; unsigned char * p; long x; len = str_object->length; p = (unsigned char *)str_object->val; x = *p << 7; while (--len >= 0) { x = (1000003*x) ^ *p++; } x ^= str_object->length; if (x == -1) x = -2; str_object->hash = x; return x; } //---- ---------------------------------- typedef struct _dictobject { PyObject_Head map<long, PyObject*> dict; }PyDictObject; void dict_print(PyObject*); PyTypeObject PyDict_Type = { PyObject_Head_Init(&PyType_Tpye) "dict", 0, dict_print, 0 }; PyObject * PyDict_Create(){ PyDictObject * dict_object = new PyDictObject; dict_object->ob_refcnt = 1; dict_object->ob_type = &PyDict_Type; return (PyObject*)dict_object; } void PyDict_SetItem(PyObject* target, PyObject* key, PyObject* val){ PyDictObject* dict_object = (PyDictObject*)target; long hash_key = key->ob_type->pyHash(key); dict_object->dict[hash_key] = val; } PyObject* PyDict_GetItem(PyObject* target, PyObject* key){ long hash_key = key->ob_type->pyHash(key); map<long, PyObject*>& dict = ((PyDictObject*)target)->dict; map<long, PyObject*>::iterator it = dict.find(hash_key); map<long, PyObject*>::iterator end = dict.end(); if (it == end) return NULL; else return it->second; } void dict_print(PyObject* object){ PyDictObject * dict_object = (PyDictObject*)object; map<long, PyObject*>& dict = dict_object->dict; map<long, PyObject*>::iterator it = dict.begin(); map<long, PyObject*>::iterator end = dict.end(); printf("{
"); for ( ; it != end; ++it) { printf("\t%ld : ", it->first); it->second->ob_type->pyPrint(it->second); } printf("}
"); } //---- ---------------------------------------------------- PyObject* m_LocalEnv = PyDict_Create(); PyObject* GetObjectBySymbol(string& symbol); void ExcutePrint(string& symbol); void ExcuteAdd(string& target, string& source); bool isSourceAllDigit(string& source); void ExcuteCommand(string& command){ string::size_type pos; 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); } } PyObject* GetObjectBySymbol(string& symbol){ PyObject* key = PyStr_Create(symbol.c_str()); PyObject* val = PyDict_GetItem(m_LocalEnv, key); if (val == NULL) { printf("[Error]: \"%s\" is not defined !
", symbol.c_str()); return NULL; } return val; } void ExcutePrint(string& symbol){ PyObject* object = GetObjectBySymbol(symbol); if (object != NULL) object->ob_type->pyPrint(object); } void ExcuteAdd(string& target, string& source){ if (target == "" || source == "") return; string::size_type pos; if (isSourceAllDigit(source)) { PyObject* key = PyStr_Create(target.c_str()); PyObject* val = PyInt_Create(atoi(source.c_str())); PyDict_SetItem(m_LocalEnv, key, val); }else if ((pos = source.find("\"")) != string::npos) { PyObject* key = PyStr_Create(target.c_str()); PyObject* val = PyStr_Create((source.substr(1, source.size()-2)).c_str()); PyDict_SetItem(m_LocalEnv, key, val); }else if ((pos = source.find(" + ")) != string::npos) { PyObject* source_left = GetObjectBySymbol(source.substr(0, pos)); PyObject* source_right = GetObjectBySymbol(source.substr(pos + 3)); if (source_left != NULL && source_right != NULL && source_left->ob_type == source_right->ob_type) { PyObject* val = source_left->ob_type->pyAdd(source_left, source_right); PyObject* key = PyStr_Create(target.c_str()); PyDict_SetItem(m_LocalEnv, key, val); } } // m_LocalEnv->ob_type->pyPrint(m_LocalEnv); } bool isSourceAllDigit(string& source){ int len = source.size(); for (int i=0; i<len; ++i) if (!isdigit(source[i])) return false; return true; } //---- ----------------------------------------------- string info = " ****** Small Python ***********"; string prompt = ">>> "; int main(){ string m_Command; cout << info << endl; cout << prompt; while (getline(cin, m_Command)) { if (m_Command == "") ; else if (m_Command == "exit") return 0; else ExcuteCommand(m_Command); cout << prompt; } }