You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$M_e(E) \vdash ({\tt d}, {\tt lis})$ is a function which yields the PA addressed instructions ${\tt lis}$ which compute the value of the expression $E$ and stores the result in ${\tt d}$. An optional second argument may provide a custom name for ${\tt d}$
$M_s(S) \vdash {\tt lis}$ is a function which yields the PA addressed instructions ${\tt lis}$ for statement $S$
$\Delta(X)$ is a mapping of program variables to PA identifiers
${\tt newId} \vdash {\tt n}$ is a generator which yields a new and unique identifier
${\tt newAddr} \vdash {\tt l}$ is a generator which yields the next address for a PA instruction.
${\tt newAddr?} \vdash {\tt l}$ is a function which peeks the next address for a PA instruction without incrementing it.
${\tt endAddr?} \vdash {\tt l}$ is a function which yields the address of the returning/ending instruction name of the procedure/loop for which code is being generated.
Note$^1$: If the provided number of arguments $j$ are less than the number of arguments that a function can accept $n$, the remaining ($k \in [j+1, n]$) parameters are filled by defaults at the call site itself. A function call with more than the acceptable number of parameters will never occur in a well-typed XS program
Note$^2$: calls to void functions cannot be used as expressions. A void function call in an expression will never occur in a well-typed XS program
Whilst explicit type casting is not allowed in XS, when code is generated for an expression, there may be one additional step to perform an implicit type cast to the desired type for that expression. An invalid type cast will never be required in a well-typed XS program. This step is omitted from the description of the algorithm above since it would add unnecessary repetitive logic to each case and hinder clarity. In the actual algorithm, $M_e$ takes an extra argument specifying the required type $T_{req}$ and is provided with the inferred type $T_{inf}$ from the type checking phase:
Note$^1$: The instructions highlighted in yellow are not generated when a default block is not present. In that case, ${\tt l_
{default}}$ is the same label as ${\tt l_{end}}$
Note$^2$: The instructions highlighted in pink are repeated as a group
Note$^1$: instructions highlighted in yellow are not generated for a void return.
Note$^2$: An ${\tt endAddr?}$ call will yield the ${\tt l_{end}}$ of the most recently entered for/while/switch/function body. It will never be invoked outside a proper context (outside a switch/for/while/function body) in a well-typed XS program
Note: It is currently unknown what ${\tt breakpoint;}$ and ${\tt dbg\ id;}$ do, however ${\tt breakpoint;}$ seems to pause the XS Runtime in DE with no known way of resuming execution. These may be repurposed for an external debugger in the future.
Note$^1$: ${\tt (2 + i)}$ is a compile-time constant, only binary operations are allowed in the RHS of PA
Note$^2$: The instructions highlighted in green save the values of the registers to the stack so that they can be restored after the procedure finishes. The instructions highlighted in red restore these stored values before the procedure returns
Note$^3$: The instruction highlighted in teal allocates space for $k$ local variables, and the instruction highlighted in orange deallocates this space.
Note$^4$: The instructions highlighted in purple load the parameters passed to the function in registers
3.10. Rule Definitions
Same as § 3.9. Function Definition, except without the purple instructions since rules take no arguments