大师兄的Python源码学习笔记(八): Tuple对象
大师兄的Python源码学习笔记(十): Python的编译过程
- 参考Python3源码,在陈儒大神文章的基础上,用c++实现对象的创建和基础运算功能。
1. 对象类型
PyObject.h
#pragma once
#ifndef __PYOBJECT_H__
#define __PYOBJECT_H__
#include <iostream>
#include <stdio.h>
#define PyObject_HEAD int refCount;struct tagPyTypeObject *type
#define PyObject_HEAD_INIT(typePtr) 0,typePtr
typedef struct tagPyObject
{
PyObject_HEAD;
}PyObject;
#endif
- 定义对象结构,只包含一个计数器和类型对象。
2. 类型对象
PyTypeObject.h
#pragma once
#ifndef __PYTYPEOBJECT_H__
#define __PYTYPEOBJECT_H__
#include "PyObject.h"
typedef void(*PrintFun)(PyObject* object);
typedef PyObject* (*AddFun)(PyObject* left, PyObject* right);
typedef long (*HashFun)(PyObject* object);
typedef struct tagPyTypeObject
{
PyObject_HEAD;
const char* name;
PrintFun print;
AddFun add;
HashFun hash;
}PyTypeObject;
extern PyTypeObject PyType_Type;
#endif
PyTypeObject.cpp
#include "pyTypeObject.h"
PyTypeObject PyType_Type =
{
PyObject_HEAD_INIT(&PyType_Type),
"type",
0,
0,
0
};
- 定义类型对象结构,类型对象本身也是一个对象。
- 类型对象还定义了名称属性和一些基础方法。
3. 整数对象
PyIntObject.h
#pragma once
#ifndef __PYINTOBJECT_H__
#define __PYINTOBJECT_H__
#include "pyTypeObject.h"
void int_print(PyObject* object);
PyObject* PyInt_Create(int value);
PyObject* int_add(PyObject* left, PyObject* right);
long int_hash(PyObject* object);
typedef struct tagPyIntObject
{
PyObject_HEAD;
int value;
}PyIntObject;
#endif
PyIntObject.cpp
#include "PyIntObject.h"
PyTypeObject PyInt_Type =
{
PyObject_HEAD_INIT(&PyType_Type),
"int",
int_print,
int_add,
int_hash
};
void int_print(PyObject* object)
{
PyIntObject* intObject = (PyIntObject*)object;
printf_s("%i\n", intObject->value);
}
PyObject* PyInt_Create(int value)
{
PyIntObject* object = new PyIntObject;
object->refCount = 1;
object->type = &PyInt_Type;
object->value = value;
return (PyObject*)object;
}
PyObject* int_add(PyObject* left, PyObject* right)
{
PyIntObject* leftInt = (PyIntObject*)left;
PyIntObject* rightInt = (PyIntObject*)right;
PyIntObject* res = (PyIntObject*)PyInt_Create(0);
if (!res)
{
std::cout << "infficient memory!" << std::endl;
exit(1);
}
else
{
res->value = leftInt->value + rightInt->value;
}
return (PyObject*)res;
}
long int_hash(PyObject* object)
{
return (long)((PyIntObject*)object)->value;
}
- 定义了整数对象和整数类型对象。
4. 字符串对象
PyStringObject.h
#pragma once
#ifndef __PYSTROBJECT_H__
#define __PYSTROBJECT_H__
#include "pyTypeObject.h"
PyObject* PyStr_Create(const char* value);
void string_print(PyObject* object);
long string_hash(PyObject* object);
PyObject* string_add(PyObject* left, PyObject* right);
typedef struct tagPyStrObject
{
PyObject_HEAD;
int length;
long hashValue;
char value[50];
}PyStringObject;
#endif
PyStringObject.cpp
#include "PyStrObject.h"
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) ? 0 : strlen(value);
object->hashValue = -1;
memset(object->value, 0, 50);
if (value)
{
strcpy_s(object->value, value);
}
return (PyObject*)object;
};
void string_print(PyObject* object)
{
PyStringObject* strObject = (PyStringObject*)object;
printf_s("%s\n", strObject->value);
};
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 = (100003 * x) ^ *p++;
}
x ^= strObject->length;
if (x == -1)
x = -2;
strObject->hashValue = x;
return x;
};
PyObject* string_add(PyObject* left, PyObject* right)
{
PyStringObject* leftStr = (PyStringObject*)left;
PyStringObject* rightStr = (PyStringObject*)right;
PyStringObject* result = (PyStringObject*)PyStr_Create(nullptr);
if (!result)
{
printf_s("infficient memerory");
}
else
{
strcpy_s(result->value, leftStr->value);
strcat_s(result->value, rightStr->value);
}
return (PyObject*)result;
};
- 定义了字符串对象和字符串类型对象。
5. 字典对象
PyDictObject.h
#pragma once
#ifndef __PYDICTOBJECT_H__
#define __PYDICTOBJECT_H__
#include "pyTypeObject.h"
#include <map>
using namespace std;
PyObject* PyDict_Create();
PyObject* PyDict_GetItem(PyObject* target, PyObject* key);
int PyDict_SetItem(PyObject* target, PyObject* key, PyObject* value);
void dict_print(PyObject* object);
typedef struct tagPyDictObject
{
PyObject_HEAD;
map<long, PyObject*> dict;
}PyDictObject;
#endif
PyDictObject.cpp
#include "PyDictObject.h"
using namespace std;
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);
map<long, PyObject*>& dict = ((PyDictObject*)target)->dict;
map<long, PyObject*>::iterator it = dict.find(keyHashValue);
map<long, PyObject*>::iterator end = dict.end();
if (it == end)
{
return nullptr;
}
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;
}
void dict_print(PyObject* object)
{
PyDictObject* dictobject = (PyDictObject*)object;
cout << ("{");
map<long, PyObject*>::iterator it = (dictobject->dict).begin();
map<long, PyObject*>::iterator end = (dictobject->dict).end();
for (; it != end; ++it)
{
cout << it->first << ":" << it->second << ","<<endl;
}
cout << "}" << endl;
}
- 定义了字典对象机构和字典类型对象。
6. 简单交互环境
main.cpp
#include "PyIntObject.h"
#include "PyStrObject.h"
#include "PyDictObject.h"
#include <String>
#include <regex>
using namespace std;
PyDictObject* m_LocalEnvironment = new PyDictObject;
bool IsSourceAllDigit(std::string& source)
{
for (std::string::size_type pos = 0; pos < source.size(); ++pos)
{
int res = isdigit(source[pos]);
if (!res)return res;
}
return true;
}
PyObject* GetObjectBySymbol(std::string& source)
{
PyObject* key = (PyObject*)PyStr_Create(source.c_str());
PyObject* value = PyDict_GetItem((PyObject*)m_LocalEnvironment, key);
if (!value)
{
std::cout << "[Error] : " << source << " is not defined!!" << std::endl;
return nullptr;
}
return value;
}
void ExcutePrint(std::string symbol)
{
PyObject* object = GetObjectBySymbol(symbol);
if (object)
{
PyTypeObject* type = object->type;
type->print(object);
}
}
void ExcuteAdd(string& target, string& source)
{
std::string::size_type pos;
PyObject* strValue = nullptr;
PyObject* resultValue = nullptr;
if (IsSourceAllDigit(source))
{
PyObject* intValue = (PyObject*)PyInt_Create(atoi(source.c_str()));
PyObject* key = (PyObject*)PyStr_Create(target.c_str());
PyDict_SetItem((PyObject*)m_LocalEnvironment, key, intValue);
}
else if (source.find("\"") != std::string::npos)
{
strValue = (PyObject*)PyStr_Create(source.substr(1, source.size() - 2).c_str());
PyObject* key = (PyObject*)PyStr_Create(target.c_str());
PyDict_SetItem((PyObject*)m_LocalEnvironment, key, strValue);
}
else if ((pos = source.find("+")) != std::string::npos)
{
string ls = source.substr(0, pos);
string rs = source.substr(pos + 1);
PyObject* leftObject = GetObjectBySymbol(ls);
PyObject* rightObject = GetObjectBySymbol(rs);
if (leftObject && rightObject && leftObject->type == rightObject->type)
{
resultValue = (leftObject->type)->add(leftObject, rightObject);
PyObject* key = (PyObject*)PyStr_Create(target.c_str());
PyDict_SetItem((PyObject*)m_LocalEnvironment, key, resultValue);
}
}
}
void ExcuteCommand(std::string& command)
{
std::regex print_reg("^print[(](.*)[)]");
std::regex equal_reg("(.*)=(.*)");
std::smatch m;
if (std::regex_match(command,m,print_reg))
{
ExcutePrint(m[1].str());
}
else if (std::regex_match(command,m,equal_reg))
{
std::string target = m[1].str();
std::string source = m[2].str();
ExcuteAdd(target, source);
}
}
const char* info = "********* myPython ********\n";
const char* prompt = ">>> ";
void Excute()
{
std::string m_Command;
std::cout << info;
std::cout << prompt;
while (getline(cin, m_Command))
{
if (m_Command.size() == 0)
{
std::cout << prompt;
continue;
}
else if (m_Command == "exit")
{
return;
}
else
{
ExcuteCommand(m_Command);
}
std::cout << prompt;
}
}
int main()
{
Excute();
return 0;
}
- 一个简单的指令交互环境。
********* myPython ********
>>> a=1
>>> b=2
>>> c=a+b
>>> print(c)
3
>>> a="hello "
>>> b="world!"
>>> c=a+b
>>> print(c)
hello world!
>>>
网友评论