Skip to content

Commit

Permalink
Merge pull request #32 from aheui/bigint
Browse files Browse the repository at this point in the history
bigint 빌드를 기본 활성화하고 bigint 출력 허용
  • Loading branch information
youknowone authored Apr 5, 2024
2 parents 07088ed + 6e23e2c commit 198dcac
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 50 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ jobs:
run: |
export RPYTHON="pypy $GITHUB_WORKSPACE/pypy/rpython/bin/rpython"
cd $GITHUB_WORKSPACE
make
make -j 3
- name: Test with snippets
run: |
cd "$GITHUB_WORKSPACE/snippets"
AHEUI="$GITHUB_WORKSPACE/rpaheui-c" ./test.sh --disable logo integer
AHEUI="$GITHUB_WORKSPACE/rpaheui-c" ./test.sh --disable integer
AHEUI="$GITHUB_WORKSPACE/rpaheui-bigint-c" ./test.sh
36 changes: 25 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,44 @@ RPYTHON?=../pypy/rpython/bin/rpython
RPYTHONFLAGS?=--opt=jit --translation-jit_opencoder_model=big


all: aheui-c aheui-py
.PHONY: all rpaheui-c rpaheui-bigint-c test-bigint test-smallint test-py clean install


all: aheui-bigint-c aheui-c aheui-py

version:
echo "VERSION = '`git describe --tags`'" > aheui/version.py

aheui-py:
aheui-py: version
cp rpaheui.py bin/aheui-py
cp rpaheui.py bin/aheui

aheui-c: version
rpaheui-bigint-c:
RPAHEUI_BIGINT=1 $(RPYTHON) $(RPYTHONFLAGS) --output rpaheui-bigint-c rpaheui.py

rpaheui-c:
$(RPYTHON) $(RPYTHONFLAGS) rpaheui.py

aheui-bigint-c: rpaheui-bigint-c
cp rpaheui-bigint-c bin/aheui-bigint-c

aheui-c: rpaheui-c
cp rpaheui-c bin/aheui-c

clean:
rm rpaheui-c
rm rpaheui-smallint rpaheui-bigint

install: aheui-c
install: rpaheui-c rpaheui-bigint-c
cp rpaheui-bigint-c /usr/local/bin/rpaheui-bigint
cp rpaheui-c /usr/local/bin/rpaheui
ln -s /usr/local/bin/rpaheui /usr/local/bin/aheui

test:
if [ -e snippets ]; then cd snippets && git pull; else git clone https://github.com/aheui/snippets; fi
cd snippets && AHEUI="../rpaheui-c" bash test.sh
test-bigint:
cd snippets && AHEUI="../rpaheui-bigint-c" bash test.sh

test-smallint:
cd snippets && AHEUI="../rpaheui-c" bash test.sh --disable integer

testpy:
test-py:
pytest
if [ -e snippets ]; then cd snippets && git pull; else git clone https://github.com/aheui/snippets; fi
cd snippets && AHEUI=../rpaheui.py bash test.sh
cd snippets && AHEUI=../bin/aheui bash test.sh --disable logo
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
```
git clone https://github.com/aheui/rpaheui
make # RPYTHON 환경변수 설정 필요. rpython은 pypy 소스코드를 내려받으면 포함되어 있습니다. 버전은 github actions 설정을 참고해 주세요.
./aheui-c <your-aheui-code>
./bin/aheui-c <아희 코드 파일>
./bin/aheui-bigint-c <큰 정수가 필요한 아희 코드 파일>
```

JIT로 속도 올리기
Expand Down
48 changes: 45 additions & 3 deletions aheui/_compat.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@

# coding: utf-8
from __future__ import absolute_import
import os


try:
from rpython.rlib import jit
from rpython.rlib.listsort import TimSort
TRACE_LIMIT = jit.PARAMETERS['trace_limit']

PYR = True
PY2 = False
PY3 = False
PY = -1

try:
USE_BIGINT = os.environ["RPAHEUI_BIGINT"]
except (KeyError, ValueError):
USE_BIGINT = ''

except ImportError:
"""Python compatibility."""
# Python compatibility

import sys

PY = sys.version_info.major
PYR = False
PY2 = PY == 2
PY3 = PY == 3

USE_BIGINT = False

def omnipotent(*args, **kw):
return args and args[0]

Expand Down Expand Up @@ -53,11 +75,31 @@ def ord(n):

try:
# rpython, python2
@jit.elidable
def _unicode(i):
return (b'%d' % i).decode('utf-8')
_unicode(0)

@jit.elidable
def _bytestr(i):
return b'%d' % i
except TypeError:
# python3
def _unicode(i):
return u'%d' % i
_unicode(0)

def _bytestr(i):
return b'%d' % i


try:
USE_BIGINT = os.environ["RPAHEUI_BIGINT"]
except (KeyError, ValueError):
USE_BIGINT = ''


if USE_BIGINT:
from aheui.int import bigint # Enable bigint in rpython build
else:
from aheui.int import smallint as bigint # noqa: F401 smallint or python support
46 changes: 24 additions & 22 deletions aheui/aheui.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
import os

from aheui import const as c
from aheui._compat import jit, unichr, ord, _unicode
from aheui._compat import jit, unichr, ord, _unicode, bigint
from aheui import compile
from aheui.int import smallint as bigint # import `bigint` to enable bigint
from aheui.option import process_options
from aheui.warning import WarningPool

Expand Down Expand Up @@ -62,11 +61,6 @@ def swap(self):
node2 = node1.next
node1.value, node2.value = node2.value, node1.value

def pop_longlong(self):
big_r = self.pop()
r = bigint.tolonglong(big_r)
return r

def add(self):
r1, r2 = self._get_2_values()
r = bigint.add(r2, r1)
Expand Down Expand Up @@ -284,19 +278,27 @@ def read_number(input_buffer=input_buffer):
return num


@jit.dont_look_inside
def write_number(value):
os.write(outfp, _unicode(value).encode('utf-8'))
def write_number(value_str):
os.write(outfp, value_str)


@jit.dont_look_inside
def write_utf8(warnings, value):
if not (0 <= value < 0x110000):
warnings.warn(b'write-utf8-range', value)
value = 0xfffd
os.write(outfp, unichr(value).encode('utf-8'))
REPLACE_CHAR = unichr(0xfffd).encode('utf-8')

if bigint.is_unicodepoint(value):
codepoint = bigint.toint(value)
unicode_char = unichr(codepoint)
bytes = unicode_char.encode('utf-8')
else:
bytes = REPLACE_CHAR

os.write(outfp, bytes)


def warn_utf8_range(warnings, value):
warnings.warn(b'write-utf8-range', value)
os.write(outfp, unichr(0xfffd).encode('utf-8'))

class Program(object):
_immutable_fields_ = ['labels[**]', 'opcodes[*]', 'values[*]', 'size']

Expand Down Expand Up @@ -402,7 +404,8 @@ def mainloop(program, debug):
elif op == c.OP_JMP:
jump = True
elif op == c.OP_BRZ:
jump = 0 == selected.pop_longlong()
top = selected.pop()
jump = bigint.is_zero(top)
else:
assert False
if jump:
Expand All @@ -414,10 +417,10 @@ def mainloop(program, debug):
stacksize=stacksize, storage=storage, selected=selected)
continue
elif op == c.OP_POPNUM:
r = selected.pop_longlong()
write_number(r)
r = selected.pop()
write_number(bigint.str(r))
elif op == c.OP_POPCHAR:
r = selected.pop_longlong()
r = selected.pop()
write_utf8(warnings, r)
elif op == c.OP_PUSHNUM:
num = read_number()
Expand All @@ -435,12 +438,11 @@ def mainloop(program, debug):
pc += 1

if len(selected) > 0:
return int(selected.pop_longlong())
return bigint.toint(selected.pop())
else:
return 0



def open_w(filename):
return os.open(filename, os.O_WRONLY | os.O_CREAT, 0o644)

Expand Down Expand Up @@ -482,7 +484,7 @@ def entry_point(argv):
cmd, source, contents, str_opt_level, target, aheuic_output, comment_aheuis, output, warning_limit, trace_limit = process_options(argv, os.environ)
except SystemExit:
return 1

warnings.limit = warning_limit
if trace_limit >= 0:
jit.set_param(driver, 'trace_limit', trace_limit)
Expand Down
32 changes: 25 additions & 7 deletions aheui/int/bigint.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@

from rpython.rlib.jit import elidable
from aheui._compat import jit
from rpython.rlib.rbigint import rbigint


NAME = 'bigint'


Int = rbigint


Expand All @@ -26,31 +29,46 @@ def tolonglong(big):
return big.tolonglong()


@elidable
def str(big):
return big.str()


@jit.elidable
def add(r1, r2):
return r1.add(r2)


@elidable
@jit.elidable
def sub(r1, r2):
return r1.sub(r2)


@elidable
@jit.elidable
def mul(r1, r2):
return r1.mul(r2)


@elidable
@jit.elidable
def div(r1, r2):
return r1.div(r2)


@elidable
@jit.elidable
def mod(r1, r2):
return r1.mod(r2)


@elidable
@jit.elidable
def ge(r1, r2):
return r1.ge(r2)


@jit.elidable
def is_zero(r):
# return r.sign == 0
return r._size == 0 # pypy 7.3.15


@jit.elidable
def is_unicodepoint(r):
return 0 <= r._size and r.int_le(0x110000)
28 changes: 28 additions & 0 deletions aheui/int/smallint.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
from __future__ import absolute_import

try:
import builtins
except ImportError:
builtins = __builtins__
from aheui._compat import _bytestr


NAME = 'smallint'


Int = int


Expand All @@ -21,6 +33,14 @@ def tolonglong(v):
return v


def str(r):
return _bytestr(r)


def hex(r):
return hex(r)


def add(r1, r2):
return r1 + r2

Expand All @@ -43,3 +63,11 @@ def mod(r1, r2):

def ge(r1, r2):
return r1 >= r2


def is_zero(r):
return r == 0


def is_unicodepoint(r):
return 0 < r <= 0x110000
4 changes: 2 additions & 2 deletions aheui/option.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import os
from aheui._argparse import ArgumentParser
from aheui._compat import bigint
from aheui.version import VERSION
from aheui import compile

Expand Down Expand Up @@ -32,11 +33,10 @@
parser.add_argument('--no-c', '--no-c', narg='0', default='no', description='Do not generate `.aheuic` file automatically.', full_description='\tWhat is .aheuic? https://github.com/aheui/snippets/commit/cbb5a12e7cd2db771538ab28dfbc9ad1ada86f35\n')
parser.add_argument('--warning-limit', '--warning-limit', default='', description='Set repetitive warning limit. '' fallbacks to environment variable `RPAHEUI_WARNING_LIMIT`. 0 means no warning. -1 means no limit. Default is 3.')
parser.add_argument('--trace-limit', '--trace-limit', default='', description='Set JIT trace limit. '' fallbacks to environment variable `RPAHEUI_TRACE_LIMIT`.')
parser.add_argument('--version', '-v', narg='-1', default='no', description='Show program version', message=VERSION)
parser.add_argument('--version', '-v', narg='-1', default='no', description='Show program version', message=('%s %s' % (VERSION, bigint.NAME)).encode('utf-8'))
parser.add_argument('--help', '-h', narg='-1', default='no', description='Show this help text')



def kwarg_or_environ(kwargs, environ, arg_key, env_key):
if arg_key in kwargs and kwargs[arg_key] != '':
return (1, kwargs[arg_key])
Expand Down
2 changes: 1 addition & 1 deletion aheui/warning.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def __init__(self, name, message):

def format(self, *args):
return self.message % args


WARNING_LIST = [
Warning(b'write-utf8-range', b'[Warning:UndefinedBehavior:write-utf8-range] value %x is out of unicode codepoint range.'),
Expand Down

0 comments on commit 198dcac

Please sign in to comment.