• R/O
  • SSH

Joypy: Commit

Main interpreter and library.


Commit MetaInfo

Revision178c94b1fc59d902195c0f616eb4ccebc7f9c497 (tree)
Time2018-07-18 02:49:09
AuthorSimon Forman <sforman@hush...>
CommiterSimon Forman

Log Message

i got used to it, but Jupyter likes 4

Change Summary

Incremental Difference

diff -r 9717e6a3a594 -r 178c94b1fc59 joy/utils/types.py
--- a/joy/utils/types.py Tue Jul 17 10:47:50 2018 -0700
+++ b/joy/utils/types.py Tue Jul 17 10:49:09 2018 -0700
@@ -5,77 +5,77 @@
55
66
77 class AnyJoyType(object):
8- '''
9- Joy type variable. Represents any Joy value.
10- '''
11-
12- accept = tuple, int, float, long, complex, str, unicode, bool, Symbol
13- prefix = 'a'
14-
15- def __init__(self, number):
16- self.number = number
17-
18- def __repr__(self):
19- return self.prefix + str(self.number)
8+ '''
9+ Joy type variable. Represents any Joy value.
10+ '''
2011
21- def __eq__(self, other):
22- return (
23- isinstance(other, self.__class__)
24- and other.prefix == self.prefix
25- and other.number == self.number
26- )
12+ accept = tuple, int, float, long, complex, str, unicode, bool, Symbol
13+ prefix = 'a'
2714
28- def __ge__(self, other):
29- return (
30- issubclass(other.__class__, self.__class__)
31- or isinstance(other, self.accept)
32- )
15+ def __init__(self, number):
16+ self.number = number
3317
34- def __le__(self, other):
35- # 'a string' >= AnyJoyType() should be False.
36- return issubclass(self.__class__, other.__class__)
18+ def __repr__(self):
19+ return self.prefix + str(self.number)
3720
38- def __add__(self, other):
39- return self.__class__(self.number + other)
40- __radd__ = __add__
21+ def __eq__(self, other):
22+ return (
23+ isinstance(other, self.__class__)
24+ and other.prefix == self.prefix
25+ and other.number == self.number
26+ )
4127
42- def __hash__(self):
43- return hash(repr(self))
28+ def __ge__(self, other):
29+ return (
30+ issubclass(other.__class__, self.__class__)
31+ or isinstance(other, self.accept)
32+ )
33+
34+ def __le__(self, other):
35+ # 'a string' >= AnyJoyType() should be False.
36+ return issubclass(self.__class__, other.__class__)
37+
38+ def __add__(self, other):
39+ return self.__class__(self.number + other)
40+ __radd__ = __add__
41+
42+ def __hash__(self):
43+ return hash(repr(self))
4444
4545
4646 class BooleanJoyType(AnyJoyType):
47- accept = bool
48- prefix = 'b'
47+ accept = bool
48+ prefix = 'b'
4949
5050
5151 class NumberJoyType(AnyJoyType):
52- accept = int, float, long, complex
53- prefix = 'n'
52+ accept = int, float, long, complex
53+ prefix = 'n'
5454
5555
5656 class FloatJoyType(NumberJoyType):
57- accept = float
58- prefix = 'f'
57+ accept = float
58+ prefix = 'f'
5959
6060
6161 class IntJoyType(FloatJoyType):
62- accept = int
63- prefix = 'i'
62+ accept = int
63+ prefix = 'i'
6464
6565
6666 class TextJoyType(FloatJoyType):
67- accept = basestring
68- prefix = 't'
67+ accept = basestring
68+ prefix = 't'
6969
7070
7171 class StackJoyType(AnyJoyType):
7272
73- accept = tuple
74- prefix = 's'
73+ accept = tuple
74+ prefix = 's'
7575
76- def __nonzero__(self):
77- # Imitate () at the end of cons list.
78- return False
76+ def __nonzero__(self):
77+ # Imitate () at the end of cons list.
78+ return False
7979
8080
8181 class JoyTypeError(Exception): pass
@@ -97,178 +97,178 @@
9797
9898
9999 def relabel(left, right):
100- '''
101- Re-number type variables to avoid collisions between stack effects.
102- '''
103- return left, _1000(right)
100+ '''
101+ Re-number type variables to avoid collisions between stack effects.
102+ '''
103+ return left, _1000(right)
104104
105105
106106 def _1000(right):
107- if not isinstance(right, tuple):
108- return 1000 + right
109- return tuple(_1000(n) for n in right)
107+ if not isinstance(right, tuple):
108+ return 1000 + right
109+ return tuple(_1000(n) for n in right)
110110
111111
112112 def delabel(f, seen=None, c=None):
113- '''
114- Fix up type variable numbers after relabel().
115- '''
116- if seen is None:
117- assert c is None
118- seen, c = {}, Counter()
113+ '''
114+ Fix up type variable numbers after relabel().
115+ '''
116+ if seen is None:
117+ assert c is None
118+ seen, c = {}, Counter()
119119
120+ try:
121+ return seen[f]
122+ except KeyError:
123+ pass
124+
125+ if not isinstance(f, tuple):
120126 try:
121- return seen[f]
122- except KeyError:
123- pass
127+ seen[f] = f.__class__(c[f.prefix] + 1)
128+ except (TypeError, # FunctionJoyTypes break this.
129+ AttributeError): # Symbol
130+ seen[f] = f
131+ else:
132+ c[f.prefix] += 1
133+ return seen[f]
124134
125- if not isinstance(f, tuple):
126- try:
127- seen[f] = f.__class__(c[f.prefix] + 1)
128- except (TypeError, # FunctionJoyTypes break this.
129- AttributeError): # Symbol
130- seen[f] = f
131- else:
132- c[f.prefix] += 1
133- return seen[f]
134-
135- return tuple(delabel(inner, seen, c) for inner in f)
135+ return tuple(delabel(inner, seen, c) for inner in f)
136136
137137
138138 def unify(u, v, s=None):
139- '''
140- Return a substitution dict representing a unifier for u and v.
141- '''
142- if s is None:
143- s = {}
144- elif s:
145- u = reify(s, u)
146- v = reify(s, v)
147-
148- if isinstance(u, AnyJoyType) and isinstance(v, AnyJoyType):
149- if u >= v:
150- s[u] = v
151- elif v >= u:
152- s[v] = u
153- else:
154- raise JoyTypeError('Cannot unify %r and %r.' % (u, v))
139+ '''
140+ Return a substitution dict representing a unifier for u and v.
141+ '''
142+ if s is None:
143+ s = {}
144+ elif s:
145+ u = reify(s, u)
146+ v = reify(s, v)
155147
156- elif isinstance(u, tuple) and isinstance(v, tuple):
157- if len(u) != len(v) != 2:
158- raise ValueError(repr((u, v))) # Bad input.
159- (a, b), (c, d) = u, v
160- s = unify(b, d, unify(a, c, s))
148+ if isinstance(u, AnyJoyType) and isinstance(v, AnyJoyType):
149+ if u >= v:
150+ s[u] = v
151+ elif v >= u:
152+ s[v] = u
153+ else:
154+ raise JoyTypeError('Cannot unify %r and %r.' % (u, v))
161155
162- elif isinstance(v, tuple):
163- if not _stacky(u):
164- raise JoyTypeError('Cannot unify %r and %r.' % (u, v))
165- s[u] = v
156+ elif isinstance(u, tuple) and isinstance(v, tuple):
157+ if len(u) != len(v) != 2:
158+ raise ValueError(repr((u, v))) # Bad input.
159+ (a, b), (c, d) = u, v
160+ s = unify(b, d, unify(a, c, s))
166161
167- elif isinstance(u, tuple):
168- if not _stacky(v):
169- raise JoyTypeError('Cannot unify %r and %r.' % (v, u))
170- s[v] = u
162+ elif isinstance(v, tuple):
163+ if not _stacky(u):
164+ raise JoyTypeError('Cannot unify %r and %r.' % (u, v))
165+ s[u] = v
171166
172- else:
173- raise JoyTypeError('Cannot unify %r and %r.' % (u, v))
167+ elif isinstance(u, tuple):
168+ if not _stacky(v):
169+ raise JoyTypeError('Cannot unify %r and %r.' % (v, u))
170+ s[v] = u
174171
175- return s
172+ else:
173+ raise JoyTypeError('Cannot unify %r and %r.' % (u, v))
174+
175+ return s
176176
177177
178178 def _stacky(thing):
179- return thing.__class__ in {AnyJoyType, StackJoyType}
179+ return thing.__class__ in {AnyJoyType, StackJoyType}
180180
181181
182182 def _compose(f, g):
183- '''
184- Return the stack effect of the composition of two stack effects.
185- '''
186- # Relabel, unify, update, delabel.
187- (f_in, f_out), (g_in, g_out) = relabel(f, g)
188- fg = reify(unify(g_in, f_out), (f_in, g_out))
189- return delabel(fg)
183+ '''
184+ Return the stack effect of the composition of two stack effects.
185+ '''
186+ # Relabel, unify, update, delabel.
187+ (f_in, f_out), (g_in, g_out) = relabel(f, g)
188+ fg = reify(unify(g_in, f_out), (f_in, g_out))
189+ return delabel(fg)
190190
191191
192192 def compose(*functions):
193- '''
194- Return the stack effect of the composition of some of stack effects.
195- '''
196- return reduce(_compose, functions)
193+ '''
194+ Return the stack effect of the composition of some of stack effects.
195+ '''
196+ return reduce(_compose, functions)
197197
198198
199199 def compilable(f):
200- '''
201- Return True if a stack effect represents a function that can be
202- automatically compiled (to Python), False otherwise.
203- '''
204- return isinstance(f, tuple) and all(imap(compilable, f)) or _stacky(f)
200+ '''
201+ Return True if a stack effect represents a function that can be
202+ automatically compiled (to Python), False otherwise.
203+ '''
204+ return isinstance(f, tuple) and all(imap(compilable, f)) or _stacky(f)
205205
206206
207207 def doc_from_stack_effect(inputs, outputs):
208- '''
209- Return a crude string representation of a stack effect.
210- '''
211- switch = [False] # Do we need to display the '...' for the rest of the main stack?
212- i, o = _f(inputs, switch), _f(outputs, switch)
213- if switch[0]:
214- i.append('...')
215- o.append('...')
216- return '(%s--%s)' % (
217- ' '.join(reversed([''] + i)),
218- ' '.join(reversed(o + [''])),
219- )
208+ '''
209+ Return a crude string representation of a stack effect.
210+ '''
211+ switch = [False] # Do we need to display the '...' for the rest of the main stack?
212+ i, o = _f(inputs, switch), _f(outputs, switch)
213+ if switch[0]:
214+ i.append('...')
215+ o.append('...')
216+ return '(%s--%s)' % (
217+ ' '.join(reversed([''] + i)),
218+ ' '.join(reversed(o + [''])),
219+ )
220220
221221
222222 def _f(term, switch):
223- a = []
224- while term and isinstance(term, tuple):
225- item, term = term
226- a.append(item)
227- assert isinstance(term, (tuple, StackJoyType)), repr(term)
228- a = [_to_str(i, term, switch) for i in a]
229- return a
223+ a = []
224+ while term and isinstance(term, tuple):
225+ item, term = term
226+ a.append(item)
227+ assert isinstance(term, (tuple, StackJoyType)), repr(term)
228+ a = [_to_str(i, term, switch) for i in a]
229+ return a
230230
231231
232232 def _to_str(term, stack, switch):
233- if not isinstance(term, tuple):
234- if term == stack:
235- switch[0] = True
236- return '[...]'
237- return (
238- '[...%i]' % term.number
239- if isinstance(term, StackJoyType)
240- else str(term)
241- )
233+ if not isinstance(term, tuple):
234+ if term == stack:
235+ switch[0] = True
236+ return '[...]'
237+ return (
238+ '[...%i]' % term.number
239+ if isinstance(term, StackJoyType)
240+ else str(term)
241+ )
242242
243- a = []
244- while term and isinstance(term, tuple):
245- item, term = term
246- a.append(_to_str(item, stack, switch))
247- assert isinstance(term, (tuple, StackJoyType)), repr(term)
248- if term == stack:
249- switch[0] = True
250- end = '' if term == () else '...'
251- #end = '...'
252- else:
253- end = '' if term == () else '...%i' % term.number
254- a.append(end)
255- return '[%s]' % ' '.join(a)
243+ a = []
244+ while term and isinstance(term, tuple):
245+ item, term = term
246+ a.append(_to_str(item, stack, switch))
247+ assert isinstance(term, (tuple, StackJoyType)), repr(term)
248+ if term == stack:
249+ switch[0] = True
250+ end = '' if term == () else '...'
251+ #end = '...'
252+ else:
253+ end = '' if term == () else '...%i' % term.number
254+ a.append(end)
255+ return '[%s]' % ' '.join(a)
256256
257257
258258 def compile_(name, f, doc=None):
259- '''
260- Return a string of Python code implementing the function described
261- by the stack effect. If no doc string is passed doc_from_stack_effect()
262- is used to generate one.
263- '''
264- i, o = f
265- if doc is None:
266- doc = doc_from_stack_effect(i, o)
267- return '''def %s(stack):
259+ '''
260+ Return a string of Python code implementing the function described
261+ by the stack effect. If no doc string is passed doc_from_stack_effect()
262+ is used to generate one.
263+ '''
264+ i, o = f
265+ if doc is None:
266+ doc = doc_from_stack_effect(i, o)
267+ return '''def %s(stack):
268268 """
269269 ::
270270
271- %s
271+ %s
272272
273273 """
274274 %s = stack
@@ -276,16 +276,16 @@
276276
277277
278278 def __(*seq):
279- stack = StackJoyType(23)
280- for item in seq: stack = item, stack
281- return stack
279+ stack = StackJoyType(23)
280+ for item in seq: stack = item, stack
281+ return stack
282282
283283
284284
285285 def stack_effect(*inputs):
286286
287- def _stack_effect(*outputs):
288- pass
287+ def _stack_effect(*outputs):
288+ pass
289289
290290 return _stack_effect
291291
@@ -302,92 +302,92 @@
302302
303303
304304 def defs():
305- '''
306- Return a dict of named stack effects.
307- '''
308- at = __(s0, i1), __(a1)
309- drop = take = __(s0, i1), __(s1)
310- cons = __(a1, s0), __((a1, s0),)
311- ccons = compose(cons, cons)
312- dup = __(a1,), __(a1, a1)
313- dupd = __(a2, a1), __(a2, a2, a1)
314- dupdd = __(a3, a2, a1), __(a3, a3, a2, a1)
315- first = __((a1, s1),), __(a1,)
316- inscribe = __(t1), __()
317- over = __(a2, a1), __(a2, a1, a2)
318- pop = __(a1), __()
319- popd = __(a2, a1,), __(a1)
320- popdd = __(a3, a2, a1,), __(a2, a1,)
321- popop = __(a2, a1,), __()
322- popopd = __(a3, a2, a1,), __(a1)
323- popopdd = __(a4, a3, a2, a1,), __(a2, a1)
324- rest = __((a1, s0),), __(s0,)
325- rolldown = __(a1, a2, a3), __(a2, a3, a1)
326- rollup = __(a1, a2, a3), __(a3, a1, a2)
327- rrest = compose(rest, rest)
328- second = compose(rest, first)
329- stack = s0, (s0, s0)
330- swaack = (s1, s0), (s0, s1)
331- swap = __(a1, a2), __(a2, a1)
332- swons = compose(swap, cons)
333- third = compose(rest, second)
334- tuck = __(a2, a1), __(a1, a2, a1)
335- uncons = __((a1, s0),), __(a1, s0)
336- unswons = compose(uncons, swap)
337- stuncons = compose(stack, uncons)
338- stununcons = compose(stack, uncons, uncons)
339- unit = __(a1), __((a1, ()))
340- of = compose(swap, at)
341- clear = s0, s1
305+ '''
306+ Return a dict of named stack effects.
307+ '''
308+ at = __(s0, i1), __(a1)
309+ drop = take = __(s0, i1), __(s1)
310+ cons = __(a1, s0), __((a1, s0),)
311+ ccons = compose(cons, cons)
312+ dup = __(a1,), __(a1, a1)
313+ dupd = __(a2, a1), __(a2, a2, a1)
314+ dupdd = __(a3, a2, a1), __(a3, a3, a2, a1)
315+ first = __((a1, s1),), __(a1,)
316+ inscribe = __(t1), __()
317+ over = __(a2, a1), __(a2, a1, a2)
318+ pop = __(a1), __()
319+ popd = __(a2, a1,), __(a1)
320+ popdd = __(a3, a2, a1,), __(a2, a1,)
321+ popop = __(a2, a1,), __()
322+ popopd = __(a3, a2, a1,), __(a1)
323+ popopdd = __(a4, a3, a2, a1,), __(a2, a1)
324+ rest = __((a1, s0),), __(s0,)
325+ rolldown = __(a1, a2, a3), __(a2, a3, a1)
326+ rollup = __(a1, a2, a3), __(a3, a1, a2)
327+ rrest = compose(rest, rest)
328+ second = compose(rest, first)
329+ stack = s0, (s0, s0)
330+ swaack = (s1, s0), (s0, s1)
331+ swap = __(a1, a2), __(a2, a1)
332+ swons = compose(swap, cons)
333+ third = compose(rest, second)
334+ tuck = __(a2, a1), __(a1, a2, a1)
335+ uncons = __((a1, s0),), __(a1, s0)
336+ unswons = compose(uncons, swap)
337+ stuncons = compose(stack, uncons)
338+ stununcons = compose(stack, uncons, uncons)
339+ unit = __(a1), __((a1, ()))
340+ of = compose(swap, at)
341+ clear = s0, s1
342342
343- eq = ge = gt = le = lt = ne = __(n1, n2), __(b1)
344-
345- and_ = __(b1, b2), __(b3)
346- bool_ = not_ = __(a1), __(b1)
347- eh = compose(dup, bool_)
348-
349- add = div = floordiv = mod = mul = pow_ = sub = truediv = \
350- lshift = rshift = __(n1, n2), __(n3,)
351- sqr = compose(dup, mul)
352- abs_ = floor = sqrt = succ = pred = neg = __(n1,), __(n2,)
353- divmod_ = pm = __(n2, n1), __(n4, n3)
343+ eq = ge = gt = le = lt = ne = __(n1, n2), __(b1)
354344
355- first_two = compose(uncons, uncons, pop)
356- fourth = compose(rest, third)
357- of = compose(swap, at)
345+ and_ = __(b1, b2), __(b3)
346+ bool_ = not_ = __(a1), __(b1)
347+ eh = compose(dup, bool_)
358348
359- _Tree_add_Ee = compose(pop, swap, rolldown, rrest, ccons)
360- _Tree_get_E = compose(popop, second)
361- _Tree_delete_clear_stuff = compose(rollup, popop, rest)
362- _Tree_delete_R0 = compose(over, first, swap, dup)
349+ add = div = floordiv = mod = mul = pow_ = sub = truediv = \
350+ lshift = rshift = __(n1, n2), __(n3,)
351+ sqr = compose(dup, mul)
352+ abs_ = floor = sqrt = succ = pred = neg = __(n1,), __(n2,)
353+ divmod_ = pm = __(n2, n1), __(n4, n3)
363354
364- return {
365- name.rstrip('_'): stack_effect
366- for name, stack_effect in locals().iteritems()
367- }
355+ first_two = compose(uncons, uncons, pop)
356+ fourth = compose(rest, third)
357+ of = compose(swap, at)
358+
359+ _Tree_add_Ee = compose(pop, swap, rolldown, rrest, ccons)
360+ _Tree_get_E = compose(popop, second)
361+ _Tree_delete_clear_stuff = compose(rollup, popop, rest)
362+ _Tree_delete_R0 = compose(over, first, swap, dup)
363+
364+ return {
365+ name.rstrip('_'): stack_effect
366+ for name, stack_effect in locals().iteritems()
367+ }
368368
369369
370370 DEFS = defs()
371371
372372
373373 def show():
374- for name, stack_effect_comment in sorted(DEFS.iteritems()):
375- t = ' *'[compilable(stack_effect_comment)]
376- print name, '=', doc_from_stack_effect(*stack_effect_comment), t
374+ for name, stack_effect_comment in sorted(DEFS.iteritems()):
375+ t = ' *'[compilable(stack_effect_comment)]
376+ print name, '=', doc_from_stack_effect(*stack_effect_comment), t
377377
378378
379379 def generate_library_code(f=None):
380- if f is None:
381- import sys
382- f = sys.stdout
383- print >> f, '# GENERATED FILE. DO NOT EDIT.\n'
384- for name, stack_effect_comment in sorted(DEFS.iteritems()):
385- if not compilable(stack_effect_comment):
386- continue
387- print >> f
388- print >> f, compile_(name, stack_effect_comment)
389- print >> f
380+ if f is None:
381+ import sys
382+ f = sys.stdout
383+ print >> f, '# GENERATED FILE. DO NOT EDIT.\n'
384+ for name, stack_effect_comment in sorted(DEFS.iteritems()):
385+ if not compilable(stack_effect_comment):
386+ continue
387+ print >> f
388+ print >> f, compile_(name, stack_effect_comment)
389+ print >> f
390390
391391
392392 if __name__ == '__main__':
393- show()
393+ show()
Show on old repository browser