Let's play with more cores.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014, 2015, 2017 Simon Forman
|
||||
#
|
||||
# This file is part of Thun
|
||||
#
|
||||
# Thun is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Thun is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Thun. If not see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import argparse, io, pkg_resources
|
||||
from .library import initialize, inscribe, Def
|
||||
from .joy import repl, interp
|
||||
from .utils.pretty_print import trace
|
||||
|
||||
|
||||
inscribe(trace)
|
||||
|
||||
|
||||
argparser = argparse.ArgumentParser(
|
||||
prog='thun',
|
||||
description='Joy Interpreter',
|
||||
)
|
||||
argparser.add_argument(
|
||||
'-d', '--defs',
|
||||
action='append',
|
||||
default=[
|
||||
io.TextIOWrapper(
|
||||
pkg_resources.resource_stream(__name__, 'defs.txt'),
|
||||
encoding='UTF_8',
|
||||
)
|
||||
],
|
||||
type=argparse.FileType('r', encoding='UTF_8'),
|
||||
help=(
|
||||
'Add additional definition files.'
|
||||
' Can be used more than once.'
|
||||
),
|
||||
)
|
||||
argparser.add_argument(
|
||||
'-q', '--quiet',
|
||||
help='Don\'t show the prompt.',
|
||||
default=False,
|
||||
action='store_true',
|
||||
)
|
||||
|
||||
|
||||
args = argparser.parse_args()
|
||||
|
||||
|
||||
if args.quiet:
|
||||
j = interp
|
||||
else:
|
||||
j = repl
|
||||
print('''\
|
||||
Thun - Copyright © 2017 Simon Forman
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type "warranty".
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type "sharing" for details.
|
||||
Type "words" to see a list of all words, and "[<name>] help" to print the
|
||||
docs for a word.
|
||||
''')
|
||||
|
||||
dictionary=initialize()
|
||||
for def_stream in args.defs:
|
||||
Def.load_definitions(def_stream, dictionary)
|
||||
stack = j(dictionary=dictionary)
|
||||
@@ -0,0 +1,116 @@
|
||||
-- 1 -
|
||||
? dup bool
|
||||
&& nulco [nullary [false]] dip branch
|
||||
++ 1 +
|
||||
|| nulco [nullary] dip [true] branch
|
||||
!- 0 >=
|
||||
<{} [] swap
|
||||
<<{} [] rollup
|
||||
abs dup 0 < [] [neg] branch
|
||||
anamorphism [pop []] swap [dip swons] genrec
|
||||
app1 grba infrst
|
||||
app2 [grba swap grba swap] dip [infrst] cons ii
|
||||
app3 3 appN
|
||||
appN [grabN] codi map disenstacken
|
||||
at drop first
|
||||
average [sum] [size] cleave /
|
||||
b [i] dip i
|
||||
binary unary popd
|
||||
ccccons ccons ccons
|
||||
ccons cons cons
|
||||
clear stack bool [pop stack bool] loop
|
||||
cleave fork popdd
|
||||
clop cleave popdd
|
||||
codi cons dip
|
||||
codireco codi reco
|
||||
dinfrirst dip infrst
|
||||
dipd [dip] codi
|
||||
disenstacken ? [uncons ?] loop pop
|
||||
down_to_zero [0 >] [dup --] while
|
||||
drop [rest] times
|
||||
dupd [dup] dip
|
||||
dupdd [dup] dipd
|
||||
dupdip dupd dip
|
||||
dupdipd dup dipd
|
||||
enstacken stack [clear] dip
|
||||
flatten <{} [concat] step
|
||||
fork [i] app2
|
||||
fourth rest third
|
||||
gcd true [tuck mod dup 0 >] loop pop
|
||||
genrec [[genrec] ccccons] nullary swons concat ifte
|
||||
grabN <{} [cons] times
|
||||
grba [stack popd] dip
|
||||
hypot [sqr] ii + sqrt
|
||||
ifte [nullary] dipd swap branch
|
||||
ii [dip] dupdip i
|
||||
infra swons swaack [i] dip swaack
|
||||
infrst infra first
|
||||
make_generator [codireco] ccons
|
||||
mod %
|
||||
neg 0 swap -
|
||||
not [true] [false] branch
|
||||
nulco [nullary] cons
|
||||
nullary [stack] dinfrirst
|
||||
of swap at
|
||||
pam [i] map
|
||||
pm [+] [-] clop
|
||||
popd [pop] dip
|
||||
popdd [pop] dipd
|
||||
popop pop pop
|
||||
popopop pop popop
|
||||
popopd [popop] dip
|
||||
popopdd [popop] dipd
|
||||
product 1 swap [*] step
|
||||
quoted [unit] dip
|
||||
range [0 <=] [1 - dup] anamorphism
|
||||
range_to_zero unit [down_to_zero] infra
|
||||
reco rest cons
|
||||
rest [pop] infra
|
||||
reverse <{} shunt
|
||||
roll> swap swapd
|
||||
roll< swapd swap
|
||||
rollup roll>
|
||||
rolldown roll<
|
||||
rrest rest rest
|
||||
run <{} infra
|
||||
second rest first
|
||||
shift uncons [swons] dip
|
||||
shunt [swons] step
|
||||
size [pop ++] step_zero
|
||||
spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte
|
||||
split_at [drop] [take] clop
|
||||
split_list [take reverse] [drop] clop
|
||||
sqr dup *
|
||||
stackd [stack] dip
|
||||
step_zero 0 roll> step
|
||||
sum [+] step_zero
|
||||
swapd [swap] dip
|
||||
swons swap cons
|
||||
swoncat swap concat
|
||||
sqr dup mul
|
||||
tailrec [i] genrec
|
||||
take [] roll> [shift] times pop
|
||||
ternary binary popd
|
||||
third rest second
|
||||
tuck dup swapd
|
||||
unary nullary popd
|
||||
uncons [first] [rest] cleave
|
||||
unit [] cons
|
||||
unquoted [i] dip
|
||||
unswons uncons swap
|
||||
while swap nulco dupdipd concat loop
|
||||
x dup i
|
||||
step [_step0] x
|
||||
_step0 _step1 [popopop] [_stept] branch
|
||||
_step1 [?] dipd roll<
|
||||
_stept [uncons] dipd [dupdipd] dip x
|
||||
times [_times0] x
|
||||
_times0 _times1 [popopop] [_timest] branch
|
||||
_times1 [dup 0 >] dipd roll<
|
||||
_timest [[--] dip dupdipd] dip x
|
||||
map [_map0] cons [[] [_map?] [_mape]] dip tailrec
|
||||
_map? pop bool not
|
||||
_mape popd reverse
|
||||
_map0 [_map1] dipd _map2
|
||||
_map1 stackd shift
|
||||
_map2 [infrst] cons dipd roll< swons
|
||||
@@ -0,0 +1,126 @@
|
||||
ALIASES = (
|
||||
('bool', ['truthy']),
|
||||
('mod', ['%', 'rem', 'remainder', 'modulus']),
|
||||
('getitem', ['pick', 'at']),
|
||||
('xor', ['^']),
|
||||
)
|
||||
|
||||
#
|
||||
# § Combinators
|
||||
#
|
||||
|
||||
|
||||
# Several combinators depend on other words in their definitions,
|
||||
# we use symbols to prevent hard-coding these, so in theory, you
|
||||
# could change the word in the dictionary to use different semantics.
|
||||
S_choice = Symbol('choice')
|
||||
S_first = Symbol('first')
|
||||
S_genrec = Symbol('genrec')
|
||||
S_getitem = Symbol('getitem')
|
||||
S_i = Symbol('i')
|
||||
S_ifte = Symbol('ifte')
|
||||
S_infra = Symbol('infra')
|
||||
S_loop = Symbol('loop')
|
||||
S_pop = Symbol('pop')
|
||||
S_primrec = Symbol('primrec')
|
||||
S_step = Symbol('step')
|
||||
S_swaack = Symbol('swaack')
|
||||
S_times = Symbol('times')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#def cleave(S, expression, dictionary):
|
||||
# '''
|
||||
# The cleave combinator expects two quotations, and below that an item X.
|
||||
# It first executes [P], with X on top, and saves the top result element.
|
||||
# Then it executes [Q], again with X, and saves the top result.
|
||||
# Finally it restores the stack to what it was below X and pushes the two
|
||||
# results P(X) and Q(X).
|
||||
# '''
|
||||
# (Q, (P, (x, stack))) = S
|
||||
# p = joy((x, stack), P, dictionary)[0][0]
|
||||
# q = joy((x, stack), Q, dictionary)[0][0]
|
||||
# return (q, (p, stack)), expression, dictionary
|
||||
|
||||
|
||||
@inscribe
|
||||
@FunctionWrapper
|
||||
def app1(S, expression, dictionary):
|
||||
'''
|
||||
Given a quoted program on TOS and anything as the second stack item run
|
||||
the program and replace the two args with the first result of the
|
||||
program.
|
||||
::
|
||||
|
||||
... x [Q] . app1
|
||||
-----------------------------------
|
||||
... [x ...] [Q] . infra first
|
||||
|
||||
'''
|
||||
(quote, (x, stack)) = S
|
||||
stack = (quote, ((x, stack), stack))
|
||||
expression = (S_infra, (S_first, expression))
|
||||
return stack, expression, dictionary
|
||||
|
||||
|
||||
@inscribe
|
||||
@FunctionWrapper
|
||||
def app2(S, expression, dictionary):
|
||||
'''Like app1 with two items.
|
||||
::
|
||||
|
||||
... y x [Q] . app2
|
||||
-----------------------------------
|
||||
... [y ...] [Q] . infra first
|
||||
[x ...] [Q] infra first
|
||||
|
||||
'''
|
||||
(quote, (x, (y, stack))) = S
|
||||
expression = (S_infra, (S_first,
|
||||
((x, stack), (quote, (S_infra, (S_first,
|
||||
expression))))))
|
||||
stack = (quote, ((y, stack), stack))
|
||||
return stack, expression, dictionary
|
||||
|
||||
|
||||
@inscribe
|
||||
@FunctionWrapper
|
||||
def app3(S, expression, dictionary):
|
||||
'''Like app1 with three items.
|
||||
::
|
||||
|
||||
... z y x [Q] . app3
|
||||
-----------------------------------
|
||||
... [z ...] [Q] . infra first
|
||||
[y ...] [Q] infra first
|
||||
[x ...] [Q] infra first
|
||||
|
||||
'''
|
||||
(quote, (x, (y, (z, stack)))) = S
|
||||
expression = (S_infra, (S_first,
|
||||
((y, stack), (quote, (S_infra, (S_first,
|
||||
((x, stack), (quote, (S_infra, (S_first,
|
||||
expression))))))))))
|
||||
stack = (quote, ((z, stack), stack))
|
||||
return stack, expression, dictionary
|
||||
|
||||
|
||||
# The current definition above works like this:
|
||||
|
||||
# [P] [Q] while
|
||||
# --------------------------------------
|
||||
# [P] nullary [Q [P] nullary] loop
|
||||
|
||||
# while == [pop i not] [popop] [dudipd] tailrec
|
||||
|
||||
#def while_(S, expression, dictionary):
|
||||
# '''[if] [body] while'''
|
||||
# (body, (if_, stack)) = S
|
||||
# while joy(stack, if_, dictionary)[0][0]:
|
||||
# stack = joy(stack, body, dictionary)[0]
|
||||
# return stack, expression, dictionary
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
from collections import namedtuple
|
||||
from re import compile as RE
|
||||
|
||||
|
||||
Snippet = namedtuple('Snippet', 'sha offset length')
|
||||
|
||||
|
||||
pat = (
|
||||
'{'
|
||||
'\s*'
|
||||
'(?P<sha>[a-f0-9]+)'
|
||||
'\s+'
|
||||
'(?P<offset>\d+)'
|
||||
'\s+'
|
||||
'(?P<length>\d+)'
|
||||
'\s*'
|
||||
'}'
|
||||
)
|
||||
|
||||
|
||||
_PAT = RE(pat)
|
||||
|
||||
|
||||
def to_string(snip):
|
||||
return _ts(*snip)
|
||||
|
||||
|
||||
def _ts(sha, offset, length):
|
||||
return f'{{{sha.decode("ascii")} {offset} {length}}}'
|
||||
|
||||
|
||||
def from_string(text):
|
||||
m = _PAT.match(text)
|
||||
if not m:
|
||||
raise ValueError
|
||||
return _fs(**m.groupdict())
|
||||
|
||||
|
||||
def _fs(sha, offset, length):
|
||||
return Snippet(sha.encode('ascii'), int(offset), int(length))
|
||||
Reference in New Issue
Block a user