(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;
}
}