大师兄的Python源码学习笔记(九): 自制Python

时间:2021-6-6 作者:qvyue

大师兄的Python源码学习笔记(八): Tuple对象
大师兄的Python源码学习笔记(十): Python的编译过程

  • 参考Python3源码,在陈儒大神文章的基础上,用c++实现对象的创建和基础运算功能。
1. 对象类型
PyObject.h

#pragma once  
#ifndef __PYOBJECT_H__
#define __PYOBJECT_H__
#include 
#include 

#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("%in", 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 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("%sn", 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 = 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 
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 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& dict = ((PyDictObject*)target)->dict;
    map::iterator it = dict.find(keyHashValue);
    map::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 ::iterator it = (dictobject->dict).begin();
    map::iterator end = (dictobject->dict).end();
    for (; it != end; ++it)
    {
        cout first second 
  • 定义了字典对象机构和字典类型对象。
6. 简单交互环境
main.cpp

#include "PyIntObject.h"
#include "PyStrObject.h"
#include "PyDictObject.h"
#include 
#include 

using namespace std;

PyDictObject* m_LocalEnvironment = new PyDictObject;

bool IsSourceAllDigit(std::string& source)
{

    for (std::string::size_type pos = 0; pos 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 
  • 一个简单的指令交互环境。
********* myPython ********
>>> a=1
>>> b=2
>>> c=a+b
>>> print(c)
3
>>> a="hello "
>>> b="world!"
>>> c=a+b
>>> print(c)
hello world!
>>>
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。