Skip to content

Commit 393ff3a

Browse files
authored
Add support for R language
add support for R language, update instructions for package installat…
2 parents 7302c63 + 60725eb commit 393ff3a

File tree

3 files changed

+81
-68
lines changed

3 files changed

+81
-68
lines changed

interpreter/code_interpreter.py

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def run_html(html_content):
3535
# Create a temporary HTML file with the content
3636
with tempfile.NamedTemporaryFile(delete=False, suffix=".html") as f:
3737
f.write(html_content.encode())
38-
38+
3939
# Open the HTML file with the default web browser
4040
webbrowser.open('file://' + os.path.realpath(f.name))
4141

@@ -50,6 +50,12 @@ def run_html(html_content):
5050
"start_cmd": sys.executable + " -i -q -u",
5151
"print_cmd": 'print("{}")'
5252
},
53+
"R": {
54+
# R is run from this interpreter with R executable
55+
# in interactive, quiet, and unbuffered mode
56+
"start_cmd": "R -q --vanilla",
57+
"print_cmd": 'print("{}")'
58+
},
5359
"shell": {
5460
# On Windows, the shell start command is `cmd.exe`
5561
# On Unix, it should be the SHELL environment variable (defaults to 'bash' if not set)
@@ -82,7 +88,7 @@ def run_html(html_content):
8288
class CodeInterpreter:
8389
"""
8490
Code Interpreters display and run code in different languages.
85-
91+
8692
They can control code blocks on the terminal, then be executed to produce an output which will be displayed in real-time.
8793
"""
8894

@@ -119,7 +125,7 @@ def update_active_block(self):
119125
"""
120126
# Strip then truncate the output if necessary
121127
self.output = truncate_output(self.output)
122-
128+
123129
# Display it
124130
self.active_block.active_line = self.active_line
125131
self.active_block.output = self.output
@@ -153,15 +159,15 @@ def run(self):
153159
except:
154160
# Sometimes start_process will fail!
155161
# Like if they don't have `node` installed or something.
156-
162+
157163
traceback_string = traceback.format_exc()
158164
self.output = traceback_string
159165
self.update_active_block()
160-
166+
161167
# Before you return, wait for the display to catch up?
162168
# (I'm not sure why this works)
163169
time.sleep(0.1)
164-
170+
165171
return self.output
166172

167173
# Reset output
@@ -178,15 +184,15 @@ def run(self):
178184
except:
179185
# If this failed, it means the code didn't compile
180186
# This traceback will be our output.
181-
187+
182188
traceback_string = traceback.format_exc()
183189
self.output = traceback_string
184190
self.update_active_block()
185-
191+
186192
# Before you return, wait for the display to catch up?
187193
# (I'm not sure why this works)
188194
time.sleep(0.1)
189-
195+
190196
return self.output
191197

192198
if self.language == "python":
@@ -214,7 +220,7 @@ def run(self):
214220
code = "osascript -e " + code
215221
# Append end command
216222
code += '\necho "END_OF_EXECUTION"'
217-
223+
218224
# Debug
219225
if self.debug_mode:
220226
print("Running code:")
@@ -315,7 +321,7 @@ def save_and_display_stream(self, stream, is_error_stream):
315321
print("Recieved output line:")
316322
print(line)
317323
print("---")
318-
324+
319325
line = line.strip()
320326

321327
# Node's interactive REPL outputs a billion things
@@ -334,6 +340,12 @@ def save_and_display_stream(self, stream, is_error_stream):
334340
if re.match(r'^(\s*>>>\s*|\s*\.\.\.\s*)', line):
335341
continue
336342

343+
# R's interactive REPL outputs a million things
344+
# So we clean it up:
345+
if self.language == "R":
346+
if re.match(r'^(\s*>>>\s*|\s*\.\.\.\s*)', line):
347+
continue
348+
337349
# Check if it's a message we added (like ACTIVE_LINE)
338350
# Or if we should save it to self.output
339351
if line.startswith("ACTIVE_LINE:"):
@@ -394,7 +406,7 @@ def process_body(self, body):
394406
# In case it's not iterable:
395407
if not isinstance(body, list):
396408
body = [body]
397-
409+
398410
for sub_node in body:
399411
if hasattr(sub_node, 'lineno'):
400412
new_body.append(self.insert_print_statement(sub_node.lineno))
@@ -405,22 +417,22 @@ def process_body(self, body):
405417
def visit(self, node):
406418
"""Overridden visit to transform nodes."""
407419
new_node = super().visit(node)
408-
420+
409421
# If node has a body, process it
410422
if hasattr(new_node, 'body'):
411423
new_node.body = self.process_body(new_node.body)
412-
424+
413425
# If node has an orelse block (like in for, while, if), process it
414426
if hasattr(new_node, 'orelse') and new_node.orelse:
415427
new_node.orelse = self.process_body(new_node.orelse)
416-
428+
417429
# Special case for Try nodes as they have multiple blocks
418430
if isinstance(new_node, ast.Try):
419431
for handler in new_node.handlers:
420432
handler.body = self.process_body(handler.body)
421433
if new_node.finalbody:
422434
new_node.finalbody = self.process_body(new_node.finalbody)
423-
435+
424436
return new_node
425437

426438
def add_active_line_prints_to_python(code):

0 commit comments

Comments
 (0)