calysto-scheme 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+
2
+ from .kernel import CalystoScheme
@@ -0,0 +1,4 @@
1
+ from calysto_scheme.kernel import CalystoScheme
2
+
3
+ if __name__ == "__main__":
4
+ CalystoScheme.run_as_main()
calysto_scheme/fib.py ADDED
@@ -0,0 +1,8 @@
1
+ def fib(n):
2
+ if n < 2:
3
+ return 1
4
+ else:
5
+ return fib(n - 1) + fib(n - 2)
6
+
7
+ fib(35)
8
+
Binary file
Binary file
Binary file
@@ -0,0 +1,464 @@
1
+ import os
2
+ import sys
3
+ import logging
4
+ import tempfile
5
+
6
+ from metakernel import MetaKernel
7
+ from calysto_scheme import scheme
8
+
9
+ try:
10
+ from IPython.core.latex_symbols import latex_symbols
11
+ from IPython.display import Image
12
+ #from IPython.utils import io
13
+ except Exception:
14
+ Image = None
15
+ latex_symbols = []
16
+
17
+ try:
18
+ import yasi
19
+ yasi.IF_LIKE = [] ## removed "if" so indents then-part and else-part the same
20
+ opts = yasi.parse_args([])
21
+ opts.dialect = "scheme"
22
+ except:
23
+ yasi = None
24
+
25
+ PY3 = (sys.version_info[0] >= 3)
26
+ if PY3:
27
+ PY_STRINGS = (str,)
28
+ else:
29
+ PY_STRINGS = (str, unicode)
30
+
31
+ class CalystoScheme(MetaKernel):
32
+ implementation = 'scheme'
33
+ implementation_version = scheme.__version__
34
+ language = 'scheme'
35
+ language_version = '3.0'
36
+ banner = "Calysto Scheme %s" % scheme.__version__
37
+ language_info = {
38
+ 'mimetype': 'text/x-scheme',
39
+ 'name': 'scheme',
40
+ 'codemirror_mode': {'name': 'scheme'},
41
+ 'pygments_lexer': 'scheme',
42
+ }
43
+
44
+ kernel_json = {
45
+ "argv": ["python3",
46
+ "-m", "calysto_scheme",
47
+ "-f", "{connection_file}"],
48
+ "display_name": "Calysto Scheme %i" % (3 if PY3 else 2),
49
+ "language": "scheme",
50
+ "codemirror_mode": "scheme",
51
+ "name": "calysto_scheme"
52
+ }
53
+ identifier_regex = r'\\?[\w\.][\w\.\?\!\-\>\<]*'
54
+ function_call_regex = r'\(([\w\.][\w\.\?\!\-\>\>]*)[^\)\()]*\Z'
55
+ magic_prefixes = dict(magic='%', shell='!', help='?')
56
+ help_suffix = None
57
+
58
+ def __init__(self, *args, **kwargs):
59
+ super(CalystoScheme, self).__init__(*args, **kwargs)
60
+ ## self.log.setLevel(logging.DEBUG)
61
+ scheme.ENVIRONMENT["raw_input"] = self.raw_input
62
+ scheme.ENVIRONMENT["read"] = self.raw_input
63
+ scheme.ENVIRONMENT["input"] = self.raw_input
64
+
65
+ try:
66
+ import getpass
67
+ getpass.getpass = self.raw_input
68
+ except Exception:
69
+ pass
70
+
71
+ def get_usage(self):
72
+ return """Calysto Scheme
73
+ =========================================
74
+
75
+ Calysto Scheme offers a combination of convenient shell features,
76
+ special commands and a history mechanism for both input (command
77
+ history) and output (results caching, similar to Mathematica).
78
+
79
+ MAIN FEATURES
80
+ -------------
81
+
82
+ * Magic commands: type %magic for information on the magic subsystem.
83
+
84
+ * Dynamic object information:
85
+
86
+ Typing ?word prints detailed information about an object. If
87
+ certain strings in the object are too long (docstrings, code, etc.) they get
88
+ snipped in the center for brevity.
89
+
90
+ Typing ??word gives access to the full information without
91
+ snipping long strings. Long strings are sent to the screen through the less
92
+ pager if longer than the screen, printed otherwise.
93
+
94
+ * Completion in the local namespace, by typing TAB at the prompt.
95
+
96
+ At any time, hitting tab will complete any available commands or
97
+ variable names, and show you a list of the possible completions if there's
98
+ no unambiguous one. It will also complete filenames in the current directory.
99
+
100
+ This feature requires the readline and rlcomplete modules, so it won't work
101
+ if your system lacks readline support (such as under Windows).
102
+
103
+ * Search previous command history in two ways (also requires readline):
104
+
105
+ - Start typing, and then use Ctrl-p (previous,up) and Ctrl-n (next,down) to
106
+ search through only the history items that match what you've typed so
107
+ far. If you use Ctrl-p/Ctrl-n at a blank prompt, they just behave like
108
+ normal arrow keys.
109
+
110
+ - Hit Ctrl-r: opens a search prompt. Begin typing and the system searches
111
+ your history for lines that match what you've typed so far, completing as
112
+ much as it can.
113
+
114
+ - %hist: search history by index (this does *not* require readline).
115
+
116
+ * Persistent command history across sessions.
117
+
118
+ * Logging of input with the ability to save and restore a working session.
119
+
120
+ * System escape with !. Typing !ls will run 'ls' in the current directory.
121
+
122
+ * Input caching system:
123
+
124
+ Offers numbered prompts (In/Out) with input and output caching. All
125
+ input is saved and can be retrieved as variables (besides the usual arrow
126
+ key recall).
127
+
128
+ The following GLOBAL variables always exist (so don't overwrite them!):
129
+ _i: stores previous input.
130
+ _ii: next previous.
131
+ _iii: next-next previous.
132
+ _ih : a list of all input _ih[n] is the input from line n.
133
+
134
+ Additionally, global variables named _i<n> are dynamically created (<n>
135
+ being the prompt counter), such that _i<n> == _ih[<n>]
136
+
137
+ For example, what you typed at prompt 14 is available as _i14 and _ih[14].
138
+
139
+ * Output caching system:
140
+
141
+ For output that is returned from actions, a system similar to the input
142
+ cache exists but using _ instead of _i. Only actions that produce a result
143
+ (NOT assignments, for example) are cached. If you are familiar with
144
+ Mathematica, Jupyter's _ variables behave exactly like Mathematica's %
145
+ variables.
146
+
147
+ The following GLOBAL variables always exist (so don't overwrite them!):
148
+ _ (one underscore): previous output.
149
+ __ (two underscores): next previous.
150
+ ___ (three underscores): next-next previous.
151
+
152
+ Global variables named _<n> are dynamically created (<n> being the prompt
153
+ counter), such that the result of output <n> is always available as _<n>.
154
+
155
+ Finally, a global dictionary named _oh exists with entries for all lines
156
+ which generated output.
157
+
158
+ * Directory history:
159
+
160
+ Your history of visited directories is kept in the global list _dh, and the
161
+ magic %cd command can be used to go to any entry in that list.
162
+ """
163
+
164
+ def get_completions(self, info):
165
+ token = info["help_obj"]
166
+ matches = []
167
+ # from latex
168
+ matches = latex_matches(token)
169
+ if matches:
170
+ return matches
171
+ # from the language environment:
172
+ slist = scheme.execute_string_rm("(get-completions)")
173
+ if not scheme.exception_q(slist):
174
+ for item in slist:
175
+ item_str = str(item)
176
+ if item_str.startswith(token) and item_str not in matches:
177
+ matches.append(item_str)
178
+ # special forms and constants:
179
+ for item in ["assert", "begin", "callback", "catch", "choose",
180
+ "define!", "define", "define-syntax", "define-tests",
181
+ "finally", "func", "help", "if", "raise", "run-tests",
182
+ "try"]:
183
+ if item.startswith(token) and item not in matches:
184
+ matches.append(item)
185
+ # add items from scheme.ENVIRONMENT
186
+ for item in scheme.ENVIRONMENT:
187
+ if item.startswith(token) and item not in matches:
188
+ matches.append(item)
189
+ # add properties and attributes if token is "numpy.ar"
190
+ if "." in token:
191
+ components, partial = token.rsplit(".", 1)
192
+ slist = scheme.execute_string_rm("(get-completions %s)" % components)
193
+ if not scheme.exception_q(slist):
194
+ for item in slist:
195
+ item_str = str(item)
196
+ if item_str.startswith(partial) and item_str not in matches:
197
+ matches.append(components + "." + item_str)
198
+ # done with language-specific completitions
199
+ return matches
200
+
201
+ def set_variable(self, name, value):
202
+ """
203
+ Set a variable in the kernel's enviroment.
204
+ """
205
+ scheme.ENVIRONMENT[name] = value
206
+
207
+ def get_variable(self, name):
208
+ """
209
+ Get a variable in the kernel's enviroment.
210
+ """
211
+ # search through the local env, if one
212
+ reg_env = scheme.GLOBALS["env_reg"]
213
+ if reg_env:
214
+ def get_index(item, ls):
215
+ pos = 0
216
+ while ls != scheme.Symbol("()"):
217
+ if item == ls.car:
218
+ return pos
219
+ ls = ls.cdr
220
+ return None
221
+ symbol_name = scheme.Symbol(name)
222
+ # car 'environment
223
+ # cadr frame: (vector of vars, names)
224
+ current_frame = reg_env = reg_env.cdr
225
+ while current_frame != scheme.Symbol("()"):
226
+ if not hasattr(current_frame, "car"): break
227
+ values = current_frame.car.car # vector of bindings (val . docstring)
228
+ names = current_frame.car.cdr.car # list
229
+ if symbol_name in names:
230
+ index = get_index(symbol_name, names)
231
+ return values[index].car
232
+ current_frame = current_frame.cdr
233
+ # if not found, search through ENVIRONMENT:
234
+ if name in scheme.ENVIRONMENT:
235
+ return scheme.ENVIRONMENT[name]
236
+
237
+ def get_kernel_help_on(self, info, level=0, none_on_fail=False):
238
+ expr = info["help_obj"]
239
+ if expr == "":
240
+ return None
241
+ result = scheme.execute_string_rm("(help %s)" % expr)
242
+ if not scheme.exception_q(result):
243
+ return result
244
+ #return {"text/html": "<b>%s</b>" % result}
245
+ elif expr in ["define", "define!", "func", "callback", "if",
246
+ "help", "define-syntax", "begin", "lambda", "trace-lambda",
247
+ "try", "catch", "finally", "raise", "choose"]:
248
+ help_text = {
249
+ "define": "(define NAME [DOCSTRING] VALUE) define a global variable (special form)",
250
+ "define!": "(define! NAME [DOCSTRING] VALUE) define a variable in the host system (special form)",
251
+ "func": "(func PROCEDURE) for wrapping Scheme procedures as a system function (special form)",
252
+ "callback": "(callback PROCEDURE) returns a host system function for system callbacks (special form)",
253
+ "if": "(if TEXT-EXPR TRUE-EXPR FALSE-EXPR) (special form)",
254
+ "help": "(help ITEM) (special form)",
255
+ "define-syntax": "(define-syntax NAME NAME-TEST ...) (special form)",
256
+ "begin": "(begin EXPR...) (special form)",
257
+ "lambda": "(lambda (VAR...) EXPR...) or (lambda VAR EXPR...) (special form)",
258
+ "trace-lambda": "(trace-lambda NAME (VAR...) EXPR...) or (trace-lambda NAME VAR EXPR...) (special form)",
259
+ "try": "(try EXPR (catch EXCEPTION NAME ...)...) (special form)",
260
+ "catch": "(try EXPR (catch EXCEPTION NAME ...) ...) (special form)",
261
+ "finally": "(try EXPR (catch EXCEPTION NAME ...)... (finally ...)) (special form)",
262
+ "raise": "(raise EXCEPTION) (special form)",
263
+ "choose": "Use (choose ITEM...) to setup non-deterministic interpreter, or use (choose) to go to next choice (special form)"
264
+ }
265
+ return help_text[expr]
266
+ elif none_on_fail:
267
+ return None
268
+ else:
269
+ return "No available help on '%s'" % expr
270
+
271
+ def repr(self, item):
272
+ if isinstance(item, list): # a scheme vector
273
+ items = " ".join(map(self.repr, item))
274
+ try:
275
+ return "#%d(%s)" % (len(item), items)
276
+ except Exception as e:
277
+ return str(e)
278
+ elif isinstance(item, scheme.cons): # a scheme list
279
+ if isinstance(item.car, scheme.Symbol):
280
+ ## HACK: fix me; represent procedues and environments as objs?
281
+ if item.car.name == "procedure":
282
+ return "#<procedure>"
283
+ elif item.car.name == "environment":
284
+ return "#<environment>"
285
+ elif item.car.name == "exception-object":
286
+ return "#<exception>"
287
+ else: # a pair
288
+ retval = []
289
+ current = item
290
+ while isinstance(current, scheme.cons):
291
+ ## HACK: fix me; represent procedues and environments as objs?
292
+ if hasattr(current.car, "name"):
293
+ if current.car.name == "procedure":
294
+ return "(%s)" % ((" ".join(retval)) + " . #<procedure>")
295
+ elif current.car.name == "environment":
296
+ return "(%s)" % ((" ".join(retval)) + " . #<environment>")
297
+ elif current.car.name == "exception-object":
298
+ return "(%s)" % ((" ".join(retval)) + " . #<exception>")
299
+ retval.append(self.repr(current.car))
300
+ current = current.cdr
301
+ retval = " ".join(retval)
302
+ if not (isinstance(current, scheme.Symbol) and
303
+ current.name == "()"):
304
+ retval += " . " + self.repr(current)
305
+ return "(%s)" % retval
306
+ elif isinstance(item, PY_STRINGS):
307
+ retval = repr(item)
308
+ if retval.startswith("'"):
309
+ retval = retval.replace('"', '\\"')
310
+ retval = retval.replace('\n', '\\n')
311
+ return '"' + retval[1:-1] + '"'
312
+ # FIXME: newlines, chars?
313
+ elif isinstance(item, bool):
314
+ return '#t' if item else '#f'
315
+ return repr(item)
316
+
317
+ def do_execute_file(self, filename):
318
+ # for the %run FILENAME magic
319
+ retval = scheme.execute_file_rm(filename);
320
+ if scheme.exception_q(retval):
321
+ traceback = scheme.get_traceback_string(retval)
322
+ ename, evalue = scheme.get_exception_values(retval)
323
+ self.Error(traceback)
324
+ return None
325
+
326
+ def do_execute_direct(self, code):
327
+ try:
328
+ retval = scheme.execute_string_top(code, "In [%s]" % self.execution_count)
329
+ except:
330
+ return "Unhandled Error: " + code
331
+ if scheme.exception_q(retval):
332
+ traceback = scheme.get_traceback_string(retval)
333
+ ename, evalue = scheme.get_exception_values(retval)
334
+ self.Error(traceback)
335
+ self.kernel_resp.update({
336
+ "status": "error",
337
+ 'ename' : ename, # Exception name, as a string
338
+ 'evalue' : evalue, # Exception value, as a string
339
+ 'traceback' : [line + "\n" for line in traceback.split("\n")], # traceback frames as strings
340
+ })
341
+ retval = None
342
+ if retval is scheme.void_value:
343
+ retval = None
344
+ elif scheme.end_of_session_q(retval):
345
+ self.Print("Use ^D to exit from console; use 'Shutdown Kernel' for other Jupyter frontends.")
346
+ retval = None
347
+ return retval
348
+
349
+ def do_function_direct(self, function_name, arg):
350
+ f = self.do_execute_direct(function_name)
351
+ return f(arg)
352
+
353
+ def initialize_debug(self, code):
354
+ self.original_debug_code = code
355
+ self.running = True
356
+ scheme._startracing_on_q_star = True
357
+ scheme.GLOBALS["TRACE_GUI"] = True
358
+ scheme.GLOBALS["TRACE_GUI_COUNT"] = 0
359
+ try:
360
+ retval = scheme.execute_string_rm(code)
361
+ except scheme.DebugException as e:
362
+ retval = "highlight: [%s, %s, %s, %s]" % (e.data[0], e.data[1], e.data[2], e.data[3])
363
+ except:
364
+ return "Unhandled Error: " + code
365
+ return retval
366
+
367
+ def do_execute_meta(self, code):
368
+ if code == "reset":
369
+ return self.initialize_debug(self.original_debug_code)
370
+ elif code == "stop":
371
+ self.running = False
372
+ scheme._startracing_on_q_star = False
373
+ scheme.GLOBALS["TRACE_GUI"] = False
374
+ elif code == "step":
375
+ if not self.running:
376
+ scheme._startracing_on_q_star = False
377
+ scheme.GLOBALS["TRACE_GUI"] = False
378
+ raise StopIteration()
379
+ try:
380
+ scheme.m()
381
+ retval = scheme.trampoline()
382
+ except scheme.DebugException as e:
383
+ if scheme.pc:
384
+ return "highlight: [%s, %s, %s, %s]" % (e.data[0], e.data[1], e.data[2], e.data[3])
385
+ else:
386
+ self.running = False
387
+ except:
388
+ return "Unhandled Error: " + code
389
+ elif code.startswith("inspect "):
390
+ variable = code[8:].strip()
391
+ self.Print("%s => %s" % (variable, self.repr(self.get_variable(variable))))
392
+ return None
393
+
394
+ def do_is_complete(self, code):
395
+ # status: 'complete', 'incomplete', 'invalid', or 'unknown'
396
+ ## First, remove magic lines:
397
+ ## need to distinguish between "%magic", and "%magic\n"
398
+ if code.startswith("%"):
399
+ lines = code.split("\n")
400
+ start_line = 0
401
+ for line in lines:
402
+ if not line.startswith("%"):
403
+ break
404
+ start_line += 1
405
+ code = ("\n".join(lines[start_line:]))
406
+ if lines[-1] == '':
407
+ return {'status' : 'complete'}
408
+ elif code == '':
409
+ return {'status' : 'incomplete'}
410
+ if yasi is not None:
411
+ data = yasi.indent_code(code + "\n(", opts) ## where does next expression go?
412
+ if data["indented_code"][-1] == "(":
413
+ return {'status' : 'complete'}
414
+ else:
415
+ return {'status' : 'incomplete',
416
+ 'indent': data["indented_code"][-1][:-1]}
417
+ elif scheme.ready_to_eval(code):
418
+ return {'status' : 'complete'}
419
+ else:
420
+ return {'status' : 'incomplete',
421
+ 'indent': ' ' * 4}
422
+
423
+ def handle_plot_settings(self):
424
+ """
425
+ Override of base method. Set up matplotlib plotting options
426
+ """
427
+ try:
428
+ import matplotlib
429
+ import matplotlib.pyplot as plt
430
+ except Error:
431
+ matplotlib = None
432
+
433
+ if matplotlib is not None:
434
+ if self.plot_settings["backend"] == "inline":
435
+ matplotlib.use("Agg")
436
+
437
+ def show():
438
+ with tempfile.NamedTemporaryFile(suffix=".png") as fp:
439
+ plt.savefig(fp.name)
440
+ if Image is not None:
441
+ return Image(fp.name)
442
+ else:
443
+ return None
444
+
445
+ plt.show = show
446
+
447
+
448
+ def latex_matches(text):
449
+ """
450
+ Match Latex syntax for unicode characters.
451
+ After IPython.core.completer
452
+ """
453
+ slashpos = text.rfind('\\')
454
+ if slashpos > -1:
455
+ s = text[slashpos:]
456
+ if s in latex_symbols:
457
+ # Try to complete a full latex symbol to unicode
458
+ return [latex_symbols[s]]
459
+ else:
460
+ # If a user has partially typed a latex symbol, give them
461
+ # a full list of options \al -> [\aleph, \alpha]
462
+ matches = [k for k in latex_symbols if k.startswith(s)]
463
+ return matches
464
+ return []
@@ -0,0 +1,38 @@
1
+ (define equal=?
2
+ (letrec
3
+ ((equal=?
4
+ (lambda (e1 e2)
5
+ (cond
6
+ ((and (null? e1) (null? e2)) #t)
7
+ ((or (null? e1) (null? e2)) #f)
8
+ ((and (number? e1) (number? e2)) (= e1 e2))
9
+ ((or (number? e1) (number? e2)) #f)
10
+ ((and (pair? e1) (pair? e2))
11
+ (and (equal=? (car e1) (car e2))
12
+ (equal=? (cdr e1) (cdr e2))))
13
+ (else #f)))))
14
+ equal=?))
15
+
16
+ ;; for testing floating-point equality to within a given tolerance
17
+ (define equal-approx?
18
+ (lambda (epsilon)
19
+ (lambda (n1 n2)
20
+ (and (number? n1)
21
+ (number? n2)
22
+ (<= (abs (- n1 n2)) epsilon)))))
23
+
24
+ (define equal-sets?
25
+ (letrec
26
+ ((f1? (lambda (x1 x2) (and (f2? x1) (f2? x2) (f5? x1 x2) (f5? x2 x1))))
27
+ (f2? (lambda (x) (and (list? x) (f3? x))))
28
+ (f3? (lambda (x) (cond ((null? x) #t) ((f4? (car x) (cdr x)) #f) (else (f3? (cdr x))))))
29
+ (f4? (lambda (x y) (and (not (null? y)) (or (equal? (car y) x) (f4? x (cdr y))))))
30
+ (f5? (lambda (x1 x2) (or (null? x1) (and (f4? (car x1) x2) (f5? (cdr x1) x2))))))
31
+ f1?))
32
+
33
+ (define equal-multisets?
34
+ (letrec
35
+ ((f1? (lambda (x1 x2) (and (list? x1) (list? x2) (f5? x1 x2) (f5? x2 x1))))
36
+ (f4? (lambda (x y) (and (not (null? y)) (or (equal? (car y) x) (f4? x (cdr y))))))
37
+ (f5? (lambda (x1 x2) (or (null? x1) (and (f4? (car x1) x2) (f5? (cdr x1) x2))))))
38
+ f1?))