From 7e28c8a1dac6f9db218cfe42d94bef5315533d16 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Mon, 8 Apr 2024 18:19:34 +0900 Subject: [PATCH] =?UTF-8?q?array=20storage=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aheui/_compat.py | 5 ++ aheui/aheui.py | 140 +--------------------------------- aheui/int/bigint.py | 5 +- aheui/int/smallint.py | 5 +- aheui/storage/__init__.py | 0 aheui/storage/array.py | 82 ++++++++++++++++++++ aheui/storage/linkedlist.py | 148 ++++++++++++++++++++++++++++++++++++ 7 files changed, 244 insertions(+), 141 deletions(-) create mode 100644 aheui/storage/__init__.py create mode 100644 aheui/storage/array.py create mode 100644 aheui/storage/linkedlist.py diff --git a/aheui/_compat.py b/aheui/_compat.py index b2d94ad..16875d5 100644 --- a/aheui/_compat.py +++ b/aheui/_compat.py @@ -100,3 +100,8 @@ def _bytestr(i): from aheui.int import bigint # Enable bigint in rpython build else: from aheui.int import smallint as bigint # noqa: F401 smallint or python support + +try: + from aheui.storage.linkedlist import Stack, Queue, Port +except ImportError: + from aheui.storage.array import Stack, Queue, Port # noqa: F401 smallint or python support diff --git a/aheui/aheui.py b/aheui/aheui.py index 67695a1..8320e5a 100644 --- a/aheui/aheui.py +++ b/aheui/aheui.py @@ -7,7 +7,7 @@ from aheui import const as c from aheui._argparse import InformationException, get_prog -from aheui._compat import jit, unichr, ord, _unicode, bigint, PYR +from aheui._compat import jit, unichr, ord, _unicode, bigint, PYR, Stack, Queue, Port from aheui import compile from aheui.option import process_options, OptionError from aheui.warning import NoRpythonWarning, WriteUtf8RangeWarning, warnings @@ -32,144 +32,6 @@ def get_location(pc, stackok, is_queue, program): DEBUG = False # debug flag for `rpaheui` -MINUS1 = bigint.fromlong(-1) - - -class Node(object): - """Element unit for stack and queue.""" - - def __init__(self, next, value=MINUS1): - self.value = value - self.next = next - - -class LinkedList(object): - """Common linked list for storages""" - - def __len__(self): - return self.size - - def pop(self): - node = self.head - self.head = node.next - value = node.value - del node - self.size -= 1 - return value - - def swap(self): - node1 = self.head - node2 = node1.next - node1.value, node2.value = node2.value, node1.value - - def add(self): - r1, r2 = self._get_2_values() - r = bigint.add(r2, r1) - self._put_value(r) - - def sub(self): - r1, r2 = self._get_2_values() - r = bigint.sub(r2, r1) - self._put_value(r) - - def mul(self): - r1, r2 = self._get_2_values() - r = bigint.mul(r2, r1) - self._put_value(r) - - def div(self): - r1, r2 = self._get_2_values() - r = bigint.div(r2, r1) - self._put_value(r) - - def mod(self): - r1, r2 = self._get_2_values() - r = bigint.mod(r2, r1) - self._put_value(r) - - def cmp(self): - r1, r2 = self._get_2_values() - r = int(bigint.ge(r2, r1)) - big_r = bigint.fromint(r) - self._put_value(big_r) - - -class Stack(LinkedList): - """Base data storage for Aheui, except for ieung and hieuh.""" - - def __init__(self): - self.head = None - self.size = 0 - - def push(self, value): - # assert(isinstance(value, bigint.Int)) - node = Node(self.head, value) - self.head = node - self.size += 1 - - def dup(self): - self.push(self.head.value) - - # Tools for common methods. inline? - - def _get_2_values(self): - return self.pop(), self.head.value - - def _put_value(self, value): - self.head.value = value - - -class Queue(LinkedList): - - def __init__(self): - self.tail = Node(None) - self.head = self.tail - self.size = 0 - - def push(self, value): - # assert(isinstance(value, bigint.Int)) - tail = self.tail - tail.value = value - new = Node(None) - tail.next = new - self.tail = new - self.size += 1 - - def dup(self): - head = self.head - node = Node(head, head.value) - self.head = node - self.size += 1 - - def _get_2_values(self): - return self.pop(), self.pop() - - def _put_value(self, value): - self.push(value) - - -class Port(LinkedList): - - def __init__(self): - self.head = None - self.size = 0 - self.last_push = bigint.fromint(0) - - def push(self, value): - # assert(isinstance(value, bigint.Int)) - node = Node(self.head, value) - self.head = node - self.size += 1 - self.last_push = value - - def dup(self): - self.push(self.last_push) - - def _get_2_values(self): - return self.pop(), self.head.value - - def _put_value(self, value): - self.head.value = value class Storage(object): diff --git a/aheui/int/bigint.py b/aheui/int/bigint.py index fb4ddc5..faee73e 100644 --- a/aheui/int/bigint.py +++ b/aheui/int/bigint.py @@ -1,5 +1,5 @@ -from aheui._compat import jit +from rpython.rlib import jit from rpython.rlib.rbigint import rbigint @@ -72,3 +72,6 @@ def is_zero(r): @jit.elidable def is_unicodepoint(r): return 0 <= r._size and r.int_le(0x110000) + + +MINUS1 = fromlong(-1) diff --git a/aheui/int/smallint.py b/aheui/int/smallint.py index c61086d..d1d1e6c 100644 --- a/aheui/int/smallint.py +++ b/aheui/int/smallint.py @@ -14,7 +14,7 @@ def fromstr(s): - return int(s) + return Int(s) def fromint(v): @@ -71,3 +71,6 @@ def is_zero(r): def is_unicodepoint(r): return 0 < r <= 0x110000 + + +MINUS1 = Int(-1) diff --git a/aheui/storage/__init__.py b/aheui/storage/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/aheui/storage/array.py b/aheui/storage/array.py new file mode 100644 index 0000000..b3d8bc3 --- /dev/null +++ b/aheui/storage/array.py @@ -0,0 +1,82 @@ +from collections import deque +from aheui._compat import PYR + + +assert not PYR, 'RPython must use linkedlist' + + +class Stack(list): + __slots__ = () + + def push(self, value): + self.append(value) + + def dup(self): + self.append(self[-1]) + + def swap(self): + self[-1], self[-2] = self[-2], self[-1] + + def add(self): + top = self.pop() + self[-1] += top + + def sub(self): + top = self.pop() + self[-1] -= top + + def mul(self): + top = self.pop() + self[-1] *= top + + def div(self): + top = self.pop() + self[-1] /= top + + def mod(self): + top = self.pop() + self[-1] %= top + + def cmp(self): + top = self.pop() + self[-1] = self[-1] >= top + + +class Queue(deque): + __slots__ = () + + def push(self, value): + self.appendleft(value) + + def dup(self): + self.appendleft(self[0]) + + def swap(self): + self[-1], self[-2] = self[-2], self[-1] + + def add(self): + top = self.pop() + self.appendleft(self.pop() + top) + + def sub(self): + top = self.pop() + self.appendleft(self.pop() - top) + + def mul(self): + top = self.pop() + self.appendleft(self.pop() * top) + + def div(self): + top = self.pop() + self.appendleft(self.pop() / top) + + def mod(self): + top = self.pop() + self.appendleft(self.pop() % top) + + def cmp(self): + top = self.pop() + self.appendleft(self.pop() >= top) + + +Port = Stack diff --git a/aheui/storage/linkedlist.py b/aheui/storage/linkedlist.py new file mode 100644 index 0000000..c71fd36 --- /dev/null +++ b/aheui/storage/linkedlist.py @@ -0,0 +1,148 @@ +from aheui._compat import bigint + + +class Node(object): + """Element unit for stack and queue.""" + + __slots__ = ('value', 'next') + + def __init__(self, next, value=bigint.MINUS1): + self.value = value + self.next = next + + +class LinkedList(object): + """Common linked list for storages""" + + __slots__ = ('head', 'size') + + def __len__(self): + return self.size + + def pop(self): + node = self.head + self.head = node.next + value = node.value + del node + self.size -= 1 + return value + + def swap(self): + node1 = self.head + node2 = node1.next + node1.value, node2.value = node2.value, node1.value + + def add(self): + r1, r2 = self._get_2_values() + r = bigint.add(r2, r1) + self._put_value(r) + + def sub(self): + r1, r2 = self._get_2_values() + r = bigint.sub(r2, r1) + self._put_value(r) + + def mul(self): + r1, r2 = self._get_2_values() + r = bigint.mul(r2, r1) + self._put_value(r) + + def div(self): + r1, r2 = self._get_2_values() + r = bigint.div(r2, r1) + self._put_value(r) + + def mod(self): + r1, r2 = self._get_2_values() + r = bigint.mod(r2, r1) + self._put_value(r) + + def cmp(self): + r1, r2 = self._get_2_values() + r = int(bigint.ge(r2, r1)) + big_r = bigint.fromint(r) + self._put_value(big_r) + + +class Stack(LinkedList): + """Base data storage for Aheui, except for ieung and hieuh.""" + + __slots__ = ('head', 'size') + + def __init__(self): + self.head = None + self.size = 0 + + def push(self, value): + # assert(isinstance(value, bigint.Int)) + node = Node(self.head, value) + self.head = node + self.size += 1 + + def dup(self): + self.push(self.head.value) + + # Tools for common methods. inline? + + def _get_2_values(self): + return self.pop(), self.head.value + + def _put_value(self, value): + self.head.value = value + + +class Queue(LinkedList): + + __slots__ = ('head', 'tail', 'size') + + def __init__(self): + self.tail = Node(None) + self.head = self.tail + self.size = 0 + + def push(self, value): + # assert(isinstance(value, bigint.Int)) + tail = self.tail + tail.value = value + new = Node(None) + tail.next = new + self.tail = new + self.size += 1 + + def dup(self): + head = self.head + node = Node(head, head.value) + self.head = node + self.size += 1 + + def _get_2_values(self): + return self.pop(), self.pop() + + def _put_value(self, value): + self.push(value) + + +class Port(LinkedList): + + __slots__ = ('head', 'size', 'last_push') + + def __init__(self): + self.head = None + self.size = 0 + self.last_push = bigint.fromint(0) + + def push(self, value): + # assert(isinstance(value, bigint.Int)) + node = Node(self.head, value) + self.head = node + self.size += 1 + self.last_push = value + + def dup(self): + self.push(self.last_push) + + def _get_2_values(self): + return self.pop(), self.head.value + + def _put_value(self, value): + self.head.value = value