美文网首页
大师兄的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