Skip to content

Commit 0166dac

Browse files
committed
Add simple eval example, base builtin on exec, gets functools.partial working.
1 parent 4861c66 commit 0166dac

File tree

5 files changed

+28
-2
lines changed

5 files changed

+28
-2
lines changed

bin/echo_vm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ def _handle_result(result: Result[Any]) -> int:
5151
tb = result.get_exception().traceback
5252
assert isinstance(tb, etraceback.ETraceback)
5353
for filename, lineno in etraceback.walk(tb):
54-
_print_surrounding(filename, lineno)
54+
if os.path.exists(filename):
55+
_print_surrounding(filename, lineno)
56+
else:
57+
print(f' {filename}:{lineno}', file=sys.stderr)
5558
termcolor.cprint(str(result), color='red', file=sys.stderr)
5659
error = True
5760
else:

py_samples/simple_eval.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
assert eval('x+x', {'x': 42}) == 42+42

src/echo/ebuiltins.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44

55
from echo.eobjects import get_guest_builtin
66

7+
# These are all the builtins that we implement in a virtualized fashion.
78
BUILTINS = tuple("""len str int bool super type object list dict tuple
89
bytearray
910
property staticmethod classmethod sum
10-
map iter next enumerate any all exec hash vars
11+
map iter next enumerate any all exec eval hash vars
1112
hasattr getattr setattr isinstance issubclass repr callable min max dir
1213
BaseException Exception
1314
""".split())
15+
16+
# These are the builtins that we expose directly from the underlying Python
17+
# implementation. Eventually one would want all of these to be virtualized.
1418
PASSTHRU = tuple("""range slice float reversed set frozenset zip sorted
1519
memoryview bytes complex id
1620
compile

src/echo/interp.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ def import_path(path: Text, module_name: Text, fully_qualified_name: Text,
265265
def _do_exec(args: Tuple[Any, ...],
266266
kwargs: Dict[Text, Any],
267267
ictx: ICtx) -> Result[None]:
268+
"""Implements the `exec` builtin."""
268269
assert 1 <= len(args) <= 3 and not kwargs, (args, kwargs)
269270
source, globals_, locals_ = none_filler(args, 3)
270271
if isinstance(source, types.CodeType):
@@ -277,3 +278,20 @@ def _do_exec(args: Tuple[Any, ...],
277278
if res.is_exception():
278279
return res
279280
return Result(None)
281+
282+
283+
@check_result
284+
@register_builtin('eval')
285+
def _do_eval(args: Tuple[Any, ...],
286+
kwargs: Dict[Text, Any],
287+
ictx: ICtx) -> Result[None]:
288+
"""Implements the `eval` builtin."""
289+
source, globals_, locals_ = none_filler(args, 3)
290+
if isinstance(source, types.CodeType):
291+
code = source
292+
else:
293+
assert isinstance(source, str), type(source)
294+
code = compile(source, '<string>', 'eval')
295+
res = interp(code, globals_=globals_, ictx=ictx, name='eval',
296+
locals_dict=locals_, in_function=False)
297+
return res

0 commit comments

Comments
 (0)