Skip to content

Commit

Permalink
🪲 Add support for numbers in return statements (#5414)
Browse files Browse the repository at this point in the history
Fixes #5170
With this PR, `return` statements try to convert their output to integers and floats and output strings if the number conversion fails. This change is required because the output of a function cannot be used in an arithmetic operation.

**How to test**
Navigate to level 14 and run the following program. Ensure that it completes without an error:
```
define round with x
    return x

r = call round with 1
print r + 1
```
  • Loading branch information
boryanagoncharenko authored Apr 16, 2024
1 parent a06152e commit 8021295
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 59 deletions.
9 changes: 8 additions & 1 deletion hedy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2425,7 +2425,14 @@ def call(self, meta, args):
def returns(self, meta, args):
argument_string = self.print_ask_args(meta, args)
exception = self.make_index_error_check_if_list(args)
return exception + f"return f'''{argument_string}'''"
return exception + textwrap.dedent(f"""\
try:
return int(f'''{argument_string}''')
except ValueError:
try:
return float(f'''{argument_string}''')
except ValueError:
return f'''{argument_string}'''""")

def number(self, meta, args):
# try all ints? return ints
Expand Down
11 changes: 11 additions & 0 deletions tests/Tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,17 @@ def value_exception_transpiled():
def index_exception_transpiled():
return '"""Runtime Index Error"""'

@staticmethod
def return_transpiled(arg):
return textwrap.dedent(f"""\
try:
return int(f'''{arg}''')
except ValueError:
try:
return float(f'''{arg}''')
except ValueError:
return f'''{arg}'''""")

# Used to overcome indentation issues when the above code is inserted
# in test cases which use different indentation style (e.g. 2 or 4 spaces)

Expand Down
55 changes: 29 additions & 26 deletions tests/test_level/test_level_12.py
Original file line number Diff line number Diff line change
Expand Up @@ -2403,10 +2403,10 @@ def test_function_use(self):
print call func with 1, 2""")

expected = textwrap.dedent(f"""\
def func(n1, n2):
return f'''{{{self.addition_transpiled('n1', 'n2')}}}'''
print(f'''{{func(1, 2)}}''')""")
expected = self.dedent(
"def func(n1, n2):",
(self.return_transpiled(f"{{{self.addition_transpiled('n1', 'n2')}}}"), ' '),
"print(f'''{func(1, 2)}''')")

self.multi_level_tester(
code=code,
Expand Down Expand Up @@ -2444,10 +2444,31 @@ def test_function_use_builtin_name(self):
print call sum with 1, 2""")

expected = textwrap.dedent(f"""\
def sum(n1, n2):
return f'''{{{self.addition_transpiled('n1', 'n2')}}}'''
print(f'''{{sum(1, 2)}}''')""")
expected = self.dedent(
"def sum(n1, n2):",
(self.return_transpiled(f"{{{self.addition_transpiled('n1', 'n2')}}}"), ' '),
"print(f'''{sum(1, 2)}''')")

self.multi_level_tester(
code=code,
max_level=16,
skip_faulty=False,
expected=expected
)

def test_function_returns_number(self):
code = textwrap.dedent("""\
define func with n1, n2
return n1 + n2
a = call func with 1, 2
print a + 3""")

expected = self.dedent(
"def func(n1, n2):",
(self.return_transpiled(f"{{{self.addition_transpiled('n1', 'n2')}}}"), ' '),
"a = func(1, 2)",
f"print(f'''{{{self.addition_transpiled('a', '3')}}}''')")

self.multi_level_tester(
code=code,
Expand Down Expand Up @@ -2516,24 +2537,6 @@ def test_addition(self):
expected=expected
)

def test_return_values(self):
code = textwrap.dedent("""\
define func with n1, n2
return n1 + n2
print call func with 1, 2""")

expected = textwrap.dedent(f"""\
def func(n1, n2):
return f'''{{{self.addition_transpiled('n1', 'n2')}}}'''
print(f'''{{func(1, 2)}}''')""")

self.single_level_tester(
code=code,
skip_faulty=False,
expected=expected
)

def test_source_map(self):
code = textwrap.dedent("""\
price = 0.0
Expand Down
66 changes: 34 additions & 32 deletions tests/test_level/test_level_14.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,38 +451,40 @@ def test_simple_function(self):
print ""
call test_function_3 with 6""")

expected = textwrap.dedent(f"""\
def test_function_1():
_int = 1
return f'''Test function {{_int}}'''
def test_function_2(_int):
return f'''Test function {{_int}}'''
def test_function_3(_input):
if convert_numerals('Latin', _input)!=convert_numerals('Latin', 5):
print(f'''NE5''')
if convert_numerals('Latin', _input)<convert_numerals('Latin', 5):
print(f'''LT5''')
if convert_numerals('Latin', _input)<=convert_numerals('Latin', 5):
print(f'''LTE5''')
if convert_numerals('Latin', _input)>convert_numerals('Latin', 5):
print(f'''GT5''')
if convert_numerals('Latin', _input)>=convert_numerals('Latin', 5):
print(f'''GTE5''')
if convert_numerals('Latin', _input) == convert_numerals('Latin', '5'):
print(f'''E5''')
print(f'''{{test_function_1()}}''')
print(f'''{{test_function_2(2)}}''')
m = 3
print(f'''{{test_function_2(m)}}''')
print(f'''{{test_function_2(4.0)}}''')
print(f'''{{test_function_2('5')}}''')
print(f'''{{test_function_2({self.number_cast_transpiled('1.5')} * {self.number_cast_transpiled('4')})}}''')
print(f'''''')
test_function_3(4)
print(f'''''')
test_function_3(5)
print(f'''''')
test_function_3(6)""")
expected = self.dedent(
"""\
def test_function_1():
_int = 1""",
(self.return_transpiled(f"Test function {{_int}}"), ' '),
"def test_function_2(_int):",
(self.return_transpiled(f"Test function {{_int}}"), ' '),
f"""\
def test_function_3(_input):
if convert_numerals('Latin', _input)!=convert_numerals('Latin', 5):
print(f'''NE5''')
if convert_numerals('Latin', _input)<convert_numerals('Latin', 5):
print(f'''LT5''')
if convert_numerals('Latin', _input)<=convert_numerals('Latin', 5):
print(f'''LTE5''')
if convert_numerals('Latin', _input)>convert_numerals('Latin', 5):
print(f'''GT5''')
if convert_numerals('Latin', _input)>=convert_numerals('Latin', 5):
print(f'''GTE5''')
if convert_numerals('Latin', _input) == convert_numerals('Latin', '5'):
print(f'''E5''')
print(f'''{{test_function_1()}}''')
print(f'''{{test_function_2(2)}}''')
m = 3
print(f'''{{test_function_2(m)}}''')
print(f'''{{test_function_2(4.0)}}''')
print(f'''{{test_function_2('5')}}''')
print(f'''{{test_function_2({self.number_cast_transpiled('1.5')} * {self.number_cast_transpiled('4')})}}''')
print(f'''''')
test_function_3(4)
print(f'''''')
test_function_3(5)
print(f'''''')
test_function_3(6)""")

output = textwrap.dedent("""\
Test function 1
Expand Down

0 comments on commit 8021295

Please sign in to comment.