Skip to content

Commit 6922e6d

Browse files
author
dimo
committed
initial ruby support
1 parent 68ab324 commit 6922e6d

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
2+
3+
import re
4+
from pathlib import Path
5+
from .subprocess_language import SubprocessLanguage
6+
7+
8+
class Ruby(SubprocessLanguage):
9+
file_extension = "rb"
10+
name = "Ruby"
11+
12+
def __init__(self):
13+
super().__init__()
14+
self.start_cmd = ["irb"]
15+
16+
def preprocess_code(self, code):
17+
"""
18+
Add active line markers
19+
Wrap in a tryCatch for better error handling
20+
Add end of execution marker
21+
"""
22+
23+
lines = code.split("\n")
24+
processed_lines = []
25+
26+
for i, line in enumerate(lines, 1):
27+
# Add active line print
28+
processed_lines.append(f'puts "##active_line{i}##"')
29+
processed_lines.append(line)
30+
# Join lines to form the processed code
31+
processed_code = "\n".join(processed_lines)
32+
33+
# Wrap in a tryCatch for error handling and add end of execution marker
34+
processed_code = f"""
35+
begin
36+
{processed_code}
37+
rescue => e
38+
puts "##execution_error##\\n" + e.message
39+
ensure
40+
puts "##end_of_execution##\\n"
41+
end
42+
"""
43+
self.code_line_count = len(processed_code.split("\n"))
44+
#print(processed_code)
45+
return processed_code
46+
47+
def line_postprocessor(self, line):
48+
# If the line count attribute is set and non-zero, decrement and skip the line
49+
if hasattr(self, "code_line_count") and self.code_line_count > 0:
50+
self.code_line_count -= 1
51+
return None
52+
if "nil" in line:
53+
return None
54+
55+
# if re.match(r"^(\s*>>>\s*|\s*\.\.\.\s*|\s*>\s*|\s*\+\s*|\s*)$", line):
56+
# return None
57+
# if line.strip().startswith('[1] "') and line.endswith(
58+
# '"'
59+
# ): # For strings, trim quotation marks
60+
# return line[5:-1].strip()
61+
# if line.strip().startswith(
62+
# "[1]"
63+
# ): # Normal R output prefix for non-string outputs
64+
# return line[4:].strip()
65+
66+
return line
67+
68+
def detect_active_line(self, line):
69+
if "##active_line" in line:
70+
return int(line.split("##active_line")[1].split("##")[0])
71+
return None
72+
73+
def detect_end_of_execution(self, line):
74+
return "##end_of_execution##" in line or "##execution_error##" in line
75+
76+
77+
# import re
78+
79+
# from .subprocess_language import SubprocessLanguage
80+
81+
82+
# class Ruby(SubprocessLanguage):
83+
# file_extension = "rb"
84+
# name = "Ruby"
85+
86+
# def __init__(self):
87+
# super().__init__()
88+
# self.start_cmd = ["ruby"] # Command to start Ruby
89+
90+
# def preprocess_code(self, code):
91+
# """
92+
# Ruby code usually doesn't require preprocessing like R does for line markers,
93+
# but we'll add a similar structure for consistency.
94+
# Wrap in a begin-rescue block for error handling.
95+
# """
96+
97+
# lines = code.split("\n")
98+
# processed_lines = []
99+
100+
# for i, line in enumerate(lines, 1):
101+
# # Add active line print, Ruby uses 'puts' for printing
102+
# processed_lines.append(f'puts "##active_line{i}##"; {line}')
103+
104+
# # Join lines to form the processed code
105+
# processed_code = "\n".join(processed_lines)
106+
107+
# # Wrap in a begin-rescue block for error handling, similar to tryCatch in R
108+
# processed_code = f"""
109+
# begin
110+
# {processed_code}
111+
# rescue => e
112+
# puts "##execution_error##\\n" + e.message
113+
# end
114+
# puts "##end_of_execution##"
115+
# """
116+
# # Track the number of lines for similar reasons as in R, though it might be less necessary in Ruby
117+
# self.code_line_count = len(processed_code.split("\n")) - 1
118+
119+
# return processed_code
120+
121+
# def line_postprocessor(self, line):
122+
# # Similar logic to R for skipping lines if we have a code_line_count
123+
# if hasattr(self, "code_line_count") and self.code_line_count > 0:
124+
# self.code_line_count -= 1
125+
# return None
126+
127+
# # Ruby doesn't use prompts like R's ">", so this can be simplified
128+
# if line.strip() == "":
129+
# return None
130+
# if "##active_line" in line: # Skip active line markers
131+
# return None
132+
133+
# return line
134+
135+
# def detect_active_line(self, line):
136+
# # Similar to R, detect the active line marker
137+
# if "##active_line" in line:
138+
# return int(line.split("##active_line")[1].split("##")[0])
139+
# return None
140+
141+
# def detect_end_of_execution(self, line):
142+
# # Similar to R, detect the end of execution or error markers
143+
# return "##end_of_execution##" in line or "##execution_error##" in line
144+

interpreter/core/computer/terminal/terminal.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .languages.python import Python
77
from .languages.r import R
88
from .languages.react import React
9+
from .languages.ruby import Ruby
910
from .languages.shell import Shell
1011

1112
# Should this be renamed to OS or System?
@@ -15,6 +16,7 @@ class Terminal:
1516
def __init__(self, computer):
1617
self.computer = computer
1718
self.languages = [
19+
Ruby,
1820
Python,
1921
Shell,
2022
JavaScript,

0 commit comments

Comments
 (0)