luapy (3) lua state

1)lua 数据类型

from enum import Enum, unique


@unique
class LuaType(Enum):
    NONE = -1
    NIL = 0
    BOOLEAN = 1
    LIGHT_USER_DATA = 2
    NUMBER = 3
    STRING = 4
    TABLE = 5
    FUNCTION = 6
    USER_DATA = 7
    THREAD = 8

2)lua stack

class LuaStack:
    MAX_STACK_SIZE = 1000

    def __init__(self):
        self.slots = []

    def top(self):
        return len(self.slots)

    def check(self, n):
        return len(self.slots) + n <= LuaStack.MAX_STACK_SIZE

    def push(self, val):
        if len(self.slots) > LuaStack.MAX_STACK_SIZE:
            raise Exception('Stack Over Flow')
        self.slots.append(val)

    def pop(self):
        ret = self.slots[-1]
        self.slots.pop()
        return ret

    def abs_index(self, idx):
        if idx >= 0:
            return idx
        return idx + len(self.slots) + 1

    def is_valid(self, idx):
        idx = self.abs_index(idx)
        return (idx > 0) and (idx <= len(self.slots))

    def get(self, idx):
        if not self.is_valid(idx):
            return None
        return self.slots[self.abs_index(idx)-1]

    def set(self, idx, val):
        if not self.is_valid(idx):
            raise Exception('Invalid Index')
        self.slots[self.abs_index(idx)-1] = val

    def reverse(self, begin, end):
        while begin < end:
            self.slots[begin], self.slots[end] = self.slots[end], self.slots[begin]
            begin += 1
            end -= 1

3)lua state

from lua_stack import LuaStack
from lua_type import LuaType
from lua_value import LuaValue
from arith_op import ArithOp
from arithmetic import Arithmetic
from cmp_op import CmpOp
from compare import Compare


class LuaState:
    def __init__(self):
        self.stack = LuaStack()

    def get_top(self):
        return self.stack.top()

    def abs_index(self, idx):
        return self.stack.abs_index(idx)

    def check_stack(self, n):
        return self.stack.check(n)

    def pop(self, n):
        for i in range(n):
            self.stack.pop()

    def copy(self, src, dst):
        self.stack.set(dst, self.stack.get(src))

    def push_value(self, idx):
        self.stack.push(self.stack.get(idx))

    def replace(self, idx):
        self.stack.set(idx, self.stack.pop())

    def insert(self, idx):
        self.rotate(idx, 1)

    def remove(self, idx):
        self.rotate(idx, -1)
        self.pop(1)

    def rotate(self, idx, n):
        t = self.stack.top() - 1
        p = self.stack.abs_index(idx) - 1
        m = t - n if n >= 0 else p - n - 1
        self.stack.reverse(p, m)
        self.stack.reverse(m+1, t)
        self.stack.reverse(p, t)

    def set_top(self, idx):
        new_top = self.stack.abs_index(idx)
        assert(new_top >= 0)

        n = self.stack.top() - new_top
        if n > 0:
            for i in range(n):
                self.stack.pop()
        elif n < 0:
            for i in range(-n):
                self.stack.push(None)

    @staticmethod
    def type_name(tp):
        if tp == LuaType.NONE:
            return 'no value'
        elif tp == LuaType.NIL:
            return 'nil'
        elif tp == LuaType.BOOLEAN:
            return 'boolean'
        elif tp == LuaType.NUMBER:
            return 'number'
        elif tp == LuaType.STRING:
            return 'string'
        elif tp == LuaType.TABLE:
            return 'table'
        elif tp == LuaType.FUNCTION:
            return 'function'
        elif tp == LuaType.THREAD:
            return 'thread'
        elif tp == LuaType.USER_DATA:
            return 'userdata'

    def type(self, idx):
        if self.stack.is_valid(idx):
            return LuaValue.type_of(self.stack.get(idx))
        return LuaType.NONE

    def is_none(self, idx):
        return self.type(idx) == LuaType.NONE

    def is_nil(self, idx):
        return self.type(idx) == LuaType.NIL

    def is_none_or_nil(self, idx):
        return self.is_none(idx) or self.is_nil(idx)

    def is_boolean(self, idx):
        return self.type(idx) == LuaType.BOOLEAN

    def is_integer(self, idx):
        return isinstance(self.stack.get(idx), int)

    def is_number(self, idx):
        return self.to_number(idx) is not None

    def is_string(self, idx):
        tp = self.type(idx)
        return tp == LuaType.STRING or tp == LuaType.NUMBER

    def is_table(self, idx):
        return self.type(idx) == LuaType.TABLE

    def is_thread(self, idx):
        return self.type(idx) == LuaType.THREAD

    def is_function(self, idx):
        return self.type(idx) == LuaType.FUNCTION

    def to_boolean(self, idx):
        return LuaValue.to_boolean(self.stack.get(idx))

    def to_integer(self, idx):
        i = self.to_integerx(idx)
        return 0 if i is None else i

    def to_integerx(self, idx):
        val = self.stack.get(idx)
        return val if isinstance(val, int) else None

    def to_number(self, idx):
        val = self.stack.get(idx)
        if isinstance(val, float):
            return val
        elif isinstance(val, int):
            return float(val)
        return 0

    def to_string(self, idx):
        val = self.stack.get(idx)
        if isinstance(val, str):
            return val
        elif isinstance(val, int) or isinstance(val, float):
            s = str(val)
            self.stack.set(idx, s)
            return s
        return ''

    def push_nil(self):
        self.stack.push(None)

    def push_boolean(self, b):
        self.stack.push(b)

    def push_integer(self, n):
        self.stack.push(n)

    def push_number(self, n):
        self.stack.push(n)

    def push_string(self, s):
        self.stack.push(s)

    def dump(self):
        top = self.stack.top()
        for i in range(1, top+1):
            t = self.type(i)
            if t == LuaType.BOOLEAN:
                print('[%s]' % ('true' if self.to_boolean(i) else 'false'), end='')
            elif t == LuaType.NUMBER:
                if self.is_integer(i):
                    print('[%d]' % self.to_integer(i), end='')
                else:
                    print('[%g]' % self.to_number(i), end='')
            elif t == LuaType.STRING:
                print('["%s"]' % self.to_string(i), end='')
            else:
                print('[%s]' % LuaState.type_name(t), end='')

        print()

4)lua value

from lua_type import LuaType


class LuaValue:
    @staticmethod
    def type_of(val):
        if val is None:
            return LuaType.NIL
        elif isinstance(val, bool):
            return LuaType.BOOLEAN
        elif isinstance(val, int) or isinstance(val, float):
            return LuaType.NUMBER
        elif isinstance(val, str):
            return LuaType.STRING
        raise Exception('Type not support')

    @staticmethod
    def to_boolean(val):
        if val is None:
            return False
        elif isinstance(val, bool):
            return val
        else:
            return True

5)test

from lua_state import LuaState


def main():
    ls = LuaState()

    ls.push_boolean(True)
    ls.dump()
    ls.push_integer(10)
    ls.dump()
    ls.push_nil()
    ls.dump()
    ls.push_string('hello')
    ls.dump()
    ls.push_value(-4)
    ls.dump()
    ls.replace(3)
    ls.dump()
    ls.set_top(6)
    ls.dump()
    ls.remove(-3)
    ls.dump()
    ls.set_top(-5)
    ls.dump()


if __name__ == '__main__':
    main()

6)test result

[true]
[true][10]
[true][10][nil]
[true][10][nil]["hello"]
[true][10][nil]["hello"][true]
[true][10][true]["hello"]
[true][10][true]["hello"][nil][nil]
[true][10][true][nil][nil]
[true]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值