Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
100644 99 lines (74 sloc) 4.294 kb
e7aed76 @Benabik Notes on REPLs
Benabik authored
1 Read, Execute, and Print Loops
2 ==============================
4 REPLs have some unique requirements from standard compilation:
6 * Maintaining scope across multiple invocations of the compiler.
7 * Compiling small fragments of code (often expressions instead of
8 statements).
9 * Automatic processing of results (printing, format, history)
11 This document describes the issues and some general design ideas for their
12 solution, but currently lacks concrete designs. It should be updated as
13 implementing a PACT REPL gets closer to reality.
15 Scope
16 -----
18 Generally, users of a REPL expect that functions and variables defined in
19 one line to be available in successive lines. Compiling each line as a
20 separate program means that all this information is lost. Therefore, some
21 semblance of scope must be maintained through both the compiler and
22 evaluation.
24 Users also generally expect to be able to redeclare variables created in
25 the REPL (and possibly those outside, depending on language standards).
26 The simplest way to model this behavior is that each line of the REPL
27 creates a new scope embedded inside the scope from the previous line. To
28 prevent this nesting from exploding memory requirements, flattening all
29 previous scopes to a single "outer" scope for the next line is desired.
31 ### Compiler
33 Issues of outer scopes need to be handled in compilers constantly.
34 However, in this case, we have two particular needs. First, the compiler
35 needs to accept an outer scope as an argument. Second, the compiler needs
36 to output scope information in addition to the code. This output is what
37 gets passed back into the compiler for the next line. This allows the
38 compiler to generate variable and function accesses correctly across lines
39 of the REPL.
41 In addition, the compiler will need to be certain not to store variables in
42 registers as we'd like to be able to garbage collect contexts after each
43 line. Likely the compiler should default to using lexical variables or
44 storing variables in a context object.
46 ### Evaluation
48 Not only do the locations of variables and functions need to be preserved
49 for the compiler, the actual data needs to be preserved for the user. The
50 "Execute" portion of the REPL will need to handle setting up the context
51 for the evaluated code. This includes ensuing that the correct subroutines
52 are available, setting up the lexical environment, and possibly passing and
53 saving a context object.
55 ### Custom Lexpad
57 Parrot's lexical operators (find_lex and store_lex) already use vtable
58 functions to access the LexPad PMC. It may be useful to create a custom
59 LexPad to store variables inside of a hash (or a hash per type) instead of
60 registers. This makes handling variables in a REPL identical to handling
61 lexical variables to the compiler and ensures that all data is updated
62 properly.
66 Fragment Compilation
67 --------------------
69 Generally a REPL is compiling far smaller units than a normal program.
70 Users expect to able to write a single expression rather than a full
71 program. Compiler writers will need to be able to handle that in their
72 parsers and call the appropriate hooks from the REPL.
74 This is also related to the idea that the PAST::AST compiler should be very
75 liberal in the code that it accepts. Given a bare expression, it should
76 output an unnamed subroutine that runs the given code and returns the
77 result. This implies that subroutines, the call to return, and other
78 standard boilerplate are automatically handled by PACT. There should be
79 hooks to make it simple for HLLs to customize that boilerplate as well.
83 Processing Results
84 ------------------
86 Once the code has been compiled and run, the final section of the loop is
87 to print the results. The REPL will have to determine the type and number
88 of results and handle them appropriately. (Remember that PCC allows for
89 return values to be as complex as parameters.)
91 Each return value needs to be converted to a string. There should be
92 options for switching between the `get_string` VTABLE, dumper, and a custom
93 function to format the output.
95 REPLs become even more useful when you can refer to old results (i.e.
96 `irb`'s `_` and `__[n]`). Obviously the details of how it is accessed will
97 vary per HLL, but the REPL framework should make storing and recalling this
98 information easy.
Something went wrong with that request. Please try again.