美文网首页
大师兄的Python源码学习笔记(九): 自制Python

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

作者: superkmi | 来源:发表于2021-03-22 19:08 被阅读0次

    大师兄的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!
    >>>
    

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/zrwucltx.html