python源码剖析的samllpython

SmallPython

SmallPython介绍

只建立了python的int和string的构造以及相加和打印。虽然很
small,但是还是可以看到C基于对象的编程手法和python的内部对象构造的过程

PyObject、PyTypeObject、PyIntObject、PyStrObject、PyDictObject

PyObject

#ifndef _PYOBJECT_H_
#define _PYOBJECT_H_

#define PyObject_HEAD \
    int refCount; \
    struct tagPyTypeObject *type


#define PyObject_HEAD_INIT(typePtr)\
    0, typePtr


typedef struct tagPyObject
{
    PyObject_HEAD;
}PyObject;

#endif

PyTypeObject

#ifndef _PYTYPEOBJECT_H_
#define _PYTYPEOBJECT_H_

#include "PyObject.h"

//definition of PyTypeObject
typedef void(*PrintFun)(PyObject* object);
typedef PyObject* (*AddFun)(PyObject* left, PyObject* right);
typedef long(*HashFun)(PyObject* object);


typedef struct tagPyTypeObject
{
    PyObject_HEAD;
    char* name;
    PrintFun print;
    AddFun add;
    HashFun hash;
}PyTypeObject;


PyTypeObject PyType_Type = { PyObject_HEAD_INIT(0), "type", 0, 0, 0 };

#endif

PyIntObject

#ifndef _PYINTOBJECT_H_
#define _PYINTOBJECT_H_

#include "PyObject.h"
#include "PyTypeObject.h"
#include <stdio.h>

typedef struct tagPyIntObject
{
    PyObject_HEAD;
    int value;
}PyIntObject;

PyObject* PyInt_Create(int value);



static void int_print(PyObject* object)
{
    PyIntObject* intObject = (PyIntObject*)object;
    printf("%d\n", intObject->value);
}


static PyObject* int_add(PyObject* left, PyObject* right)
{
    PyIntObject* leftInt = (PyIntObject*)left;
    PyIntObject* rightInt = (PyIntObject*)right;
    PyIntObject* result = (PyIntObject*)PyInt_Create(0);
    if (result == NULL)
    {
        printf("We have no enough memory!!\n");
    }
    else
    {
        result->value = leftInt->value + rightInt->value;
    }
    return (PyObject*)result;
}


static long int_hash(PyObject* object)
{
    return (long)((PyIntObject*)object)->value;
}

PyTypeObject PyInt_Type =
{
    PyObject_HEAD_INIT(&PyType_Type),
    "int",
    int_print,
    int_add,
    int_hash
};


PyObject* PyInt_Create(int value)
{
    PyIntObject* object = new PyIntObject;
    object->refCount = 1;
    object->type = &PyInt_Type;
    object->value = value;
    return (PyObject*)object;
}

#endif

PyStrObject



#ifndef _PYSTROBJECT_H_
#define _PYSTROBJECT_H_

#include "PyObject.h"
#include "PyTypeObject.h"
#include <stdio.h>
#include <string.h>


typedef struct tagPyStrObject
{
    PyObject_HEAD;
    int length;
    long hashValue;
    char value[50];
}PyStringObject;



PyObject* PyStr_Create(const char* value);

static void string_print(PyObject* object)
{
    PyStringObject* strObject = (PyStringObject*)object;
    printf("%s\n", strObject->value);
}


static 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 = (1000003 * x) ^ *p++;
    x ^= strObject->length;
    if (x == -1)
        x = -2;
    strObject->hashValue = x;
    return x;
}

#define _CRT_SECURE_NO_WARNINGS
static PyObject* string_add(PyObject* left, PyObject* right)
{
    PyStringObject* leftStr = (PyStringObject*)left;
    PyStringObject* rightStr = (PyStringObject*)right;
    PyStringObject* result = (PyStringObject*)PyStr_Create(nullptr);
    if (result == NULL)
    {
        printf("We have no enough memory!!\n");
    }
    else
    {
        strcpy_s(result->value, leftStr->value);
        strcat_s(result->value, rightStr->value);
    }
    return (PyObject*)result;
}


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 == NULL) ? 0 : strlen(value);
    object->hashValue = -1;
    memset(object->value, 0, 50);
    if (value != NULL)
    {
        strcpy_s(object->value, value);
    }
    return (PyObject*)object;
}

#endif

PyDictObject

#ifndef _PYDICTOBJECT_H_
#define _PYDICTOBJECT_H_

#include "PyObject.h"
#include "PyTypeObject.h"
#include<stdio.h>
#include <map>
using std::map;

typedef struct tagPyDictObject
{
    PyObject_HEAD;
    map<long, PyObject*> dict;
}PyDictObject;


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


//function for PyDict_Type
static void dict_print(PyObject* object)
{
    PyDictObject* dictObject = (PyDictObject*)object;
    printf("{\n");
    map<long, PyObject*>::iterator it = (dictObject->dict).begin();
    map<long, PyObject*>::iterator end = (dictObject->dict).end();
    for (; it != end; ++it)
    {
        //print key
        printf("%d : ", it->first);
        //print value
        PyObject* value = it->second;
        (value->type)->print(value);
        printf(",\n");
    }
    printf("}\n");
}


PyTypeObject PyDict_Type =
{
    PyObject_HEAD_INIT(&PyType_Type),
    "dict",
    dict_print,
    0,
    0
};

PyObject* PyDict_Create()
{
    //create object
    PyDictObject* object = new PyDictObject;
    object->refCount = 1;
    object->type = &PyDict_Type;
    return (PyObject*)object;
}

#endif

EXC

#ifndef _EXC_H_
#define _EXC_H_

#include "PyObject.h"
#include "PyIntObject.h"
#include "PyDictObject.h"
#include "PyStrObject.h"
#include <string>
#include <iostream>

using std::cout;
using std::endl;
using std::string;

PyDictObject LocalEnvironment = { 1, &PyDict_Type, map<long, PyObject*>() };
PyDictObject* m_LocalEnvironment = &LocalEnvironment;

void ExcutePrint(string symbol);
PyObject* GetObjectBySymbol(string& symbol);
void ExcuteAdd(string& target, string& source);

void ExcuteCommand(string& command)
{
    string::size_type pos = 0;
    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);
    }
}

int IsSourceAllDigit(string& str){
    int len = str.size();
    for (int i = 0; i < len; ++i){
        if (!isdigit(str[i])){
            return 0;
        }
    }
    return 1;
}


void ExcuteAdd(string& target, string& source)
{
    string::size_type pos;
    if (IsSourceAllDigit(source))
    {
        PyObject* intValue = PyInt_Create(atoi(source.c_str()));
        PyObject* key = PyStr_Create(target.c_str());
        PyDict_SetItem((PyObject*)m_LocalEnvironment, key, intValue);
    }
    else if (source.find("\"") != string::npos)
    {
        PyObject* strValue = PyStr_Create(source.substr(1, source.size() - 2).c_str());
        PyObject* key = PyStr_Create(target.c_str());
        PyDict_SetItem((PyObject*)m_LocalEnvironment, key, strValue);
    }
    else if ((pos = source.find("+")) != string::npos)
    {
        PyObject* leftObject = GetObjectBySymbol(source.substr(0, pos));
        PyObject* rightObject = GetObjectBySymbol(source.substr(pos + 1));
        if (leftObject != NULL && rightObject != NULL && leftObject->type == rightObject->type)
        {
            PyObject* resultValue = (leftObject->type)->add(leftObject, rightObject);
            PyObject* key = PyStr_Create(target.c_str());
            PyDict_SetItem((PyObject*)m_LocalEnvironment, key, resultValue);
        }
        (m_LocalEnvironment->type)->print((PyObject*)m_LocalEnvironment);
    }
}

PyObject* GetObjectBySymbol(string& symbol)
{
    PyObject* key = PyStr_Create(symbol.c_str());
    PyObject* value = PyDict_GetItem((PyObject*)m_LocalEnvironment, key);
    //是不是应该加上delete
    delete key;
    if (value == NULL)
    {
        cout << "[Error] : " << symbol << " is not defined!!" << endl;
        return nullptr;
    }
    return value;
}




void ExcutePrint(string symbol)
{
    PyObject* object = GetObjectBySymbol(symbol);
    if (object != NULL)
    {
        PyTypeObject* type = object->type;
        type->print(object);
    }
}
#endif

main

#include "exc.h"
#include <string>
#include <iostream>
using namespace std;

char* info = "********** Python Research **********\n";
char* prompt = ">>> ";

string m_Command;

int main()
{

    cout << info;
    cout << prompt;
    while (getline(cin, m_Command)){
        if (m_Command.size() == 0){
            cout << prompt;
            continue;
        }
        else if (m_Command == "exit"){
            return 0;
        }
        else{
            ExcuteCommand(m_Command);
        }
        cout << prompt;
    }
    //资源是不是应该回收
    return 0;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/xiaolixi199311/article/details/79205558