Text-based interpreter: Add continuation, Refactor interpreter

Source: Internet
Author: User
Tags eval exception handling

Perhaps before joining the continuation, it is important to talk about the cost of doing it so much. After all, the results are the same with no continuation calculation. However, this is a series of interests, learning this knowledge should be entirely out of curiosity and fun ideas. That's why I'm not going to tell you. Through control continuation can achieve call-with-current-continuation and exception handling functions.

Let me briefly describe how the interpreter works after joining the continuation. The interpreter after joining the continuation is working in an iterative manner. The number of States in the iteration is two, the first is an expression to be evaluated or the value being evaluated, and the second is continuation. Assuming that the interpreter's input is $m$, the initial state is expressed as $\left<m, {mt}\right>_v$. The first state amount is an expression $m$, at which point the interpreter begins to evaluate the $m$. The process is represented by a notation $\rightarrow_{v}$. This process may save some of the "next steps" to continuation. At the end of the evaluation, the state becomes $\left<v, \kappa\right>_c$ (if there is no infinite loop). Notice that the subscript turns into C, $V $ is a value, so no longer evaluated, the next step is to remove the "next thing" from continuation $\kappa$. This process is also called "Apply continuation $\kappa$ to value $v$", expressed in notation $\rightarrow_{c}$. An interpreter's execution process is $\rightarrow_{v}$ and $\rightarrow_{c}$ alternately, just like the alternating of yin and yang in Taiji. Interpreter execution to the final state will become $\left<v, {mt}\right>_c$, has been evaluated $v$, and there is no "next thing to do", that is, run the end of the output $v$. Having said so much, essentially the whole process is still a sentence: recursive iteration. Incidentally, the interpreter after adding continuation is called CK machine.

List all evaluation procedures so far (Call-by-value): \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} eval (x) &=& X \ eval (b) &=& b \ Eval (\lambda x.m) &=& \lambda x.m \ eval (+ \; M \; N) &=& eval (M) + eval (n) \ eval (-\; M \; N) &=& eval (M)-eval (n) \ eval ({Iszero} \; m) &=& {true} \ \ && \text{where} eval (m) = 0 \ eval ({Iszero} \; m) &=& {false}, \ && \text{where} eval (m) \neq 0 \ eval ((M \; N) &=& eval (l[x \leftarrow eval (N)]) \ && \text{which} eval (M) = \lambda x.l \ eval ({fix} \; X_1 \; X_2 \; M) &=& \lambda x_2.m[x_1 \leftarrow ({fix} \; X_1 \; X_2 \; M)] \end{array}\end{equation*} below describes how to add continuation in each case.

Value and fix expression

The value is the simplest case of direct application of continuation. \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \left<x, \kappa\right>_v &\rightarrow_v& \left<x, \kappa\right >_c \ \left<b, \kappa\right>_v &\rightarrow_v& \left<b, \kappa\right>_c \ \left<\lambda X.M , \kappa\right>_v &\rightarrow_v& \left<\lambda x.m, \kappa\right>_c \ \end{array}\end{equation*}

Fix expressions and values are similar: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \left< ({fix} \; X_1 \; X_2 \; M), \kappa\right>_v &\rightarrow_v& \left<\lambda x_2.m[x_1 \leftarrow ({fix} \; X_1 \; X_2 \; M)], \kappa\right>_c \end{array}\end{equation*}

(fixx1x2m), κv→vλx2.m[x1← (fixx1x2m)],κc

Basic operations

Use $ (o^n \; M_1 \; M_2 \; ... \; M_n) $ represents the basic operation, where $o^n$ is an operator, $M _1, ..., m_n$ is a parameter, $n $ is the number of arguments. In our language there are currently two basic operations of two parameters $o^2=\{+,-\}$ and a single parameter of the basic Operation $o^1=\{{iszero}\}$.

The

evaluates all parameters before calculating the base operation. This provides a value from left to right. When the interpreter asks for the value of the $i$ parameter $m_i$, the data that needs to be saved to the continuation is: operator $o^n$, value that has been obtained $v_1, ..., v_{i-1}$ (where $v_1=eval (M), ..., V_{i-1}=eval (m_ {i-1}) $) and parameters that have not been evaluated $m_{i+1}, ..., m_n$. Therefore, the continuation that contains the basic operations is defined as: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \kappa &=& {MT} \ &|& \LEFT<{OPD}, \kappa, O^n, (v_1; ... \; V_{i-1}), (m_{i+1} \;. \; m_n) \right> \end{array} \end{equation*}

The evaluation process is: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \left< (O^n \; M_1 \; M_2 \; ... \; M_n), \kappa\right>_v &\rightarrow_v& \left<m_1, \left<{opd}, \kappa, O^n, (m_2; ... \; M_n), () \right>\right>_v \ \left<v, \left<{opd}, \kappa, O^n, (m_{i+1} \; M_n), (v_1;.; \; V_{i-1}) \right>\right>_c &\rightarrow_c& \left<m_{i+1}, \LEFT<{OPD}, \kappa, O^n, (...; M_n), (v_1;.; \; v_{i-1} V \right>\right>_v \ \left<v, \left<{opd}, \kappa, O^n, (), (v_1 \;.. \; V_{n-1}) \right>\right>_c &\rightarrow_c& \left<v ', \kappa\right>_c \ && \text{where} V ' = O^n (V_1, ..., v_{n-1}, V) \end{array}\end{equation*}

(onm1m2 ...) Mn), Κv V,opd,κ,on, (mi+1...mn), (V1 ... VI1) c V,opd,κ,on, (), (V1 ... VN1) C→v→c→c M1,opd,κ,on, (M2 ... Mn), () v Mi+1,opd,κ,on, (...) Mn), (V1 ... VI1V) v V′,κc of which V′=on (V1,..., vn1,v)

Function call

Function calls $ (M \; N) $ to first calculate the value of the $m$, $N $ to save to continuation: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \left< (M \; N), \kappa\right>_v &\rightarrow_v& \left<m, \left<{arg}, \kappa, N\right>\right>_v \end{array }\end{equation*} $M $ After the calculation is taken out from the continuation $n$ calculation (we use the Call-by-value call), while saving $m$ results $v$: \begin{equation*}\begin{ ARRAY}{LCL} \left<v, \left<{arg}, \kappa, N\right>\right>_c &\rightarrow_c& \left<n, \left< {fun}, \kappa, V\right>\right>_v \end{array}\end{equation*} $N $ also after the calculation, make a $\beta$: \begin{equation*}\begin{ ARRAY}{LCL} \left<v, \left<{fun}, \kappa, \lambda x.l\right>\right>_c &\rightarrow_c& \left<l[ X \leftarrow V], \kappa\right>_v \end{array}\end{equation*} This is an interesting place to see that the last $\beta$ of the function call will not increase the continuation. The process of calculating the parameters in the basic operation, the process of calculating the function in the function call, and the calculation of the parameters are the processes that lead to the continuation growth in all evaluation process. It is also generally thought that this position of the function in the function call (that is, $ (M \; N) $ $m$ This position is also the parameter position, so judging a function call is not the basis of the tail call: This function call expression is not in a parameter position, if in the parameter position, it is not the tail call.

The evaluation process above has added two continuation: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \kappa &=& ... \ &|& \left<{arg} , \kappa, n\right> \ &|& \left<{fun}, \kappa, V\right> \end{array} \end{equation*}

κ=| | ... arg,κ,nfun,κ,v

Code implementation

function value-of/k is $\rightarrow_v$. function Apply-cont is $\rightarrow_c$. Write the code to note that calls to value-of/and Apply-cont must be tail calls.

Code for Procedure $\rightarrow_v$:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.