Files
ueforth/site/internals.html
2022-02-27 20:59:19 -08:00

110 lines
3.1 KiB
HTML

<!DOCTYPE html>
<!--
Copyright 2021 Bradley D. Nelson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<head>
<meta charset="UTF-8">
<title>µEforth Internals</title>
<link rel="stylesheet" href="static/eforth.css">
</head>
<body>
<h1>µEforth Internals</h1>
{{MENU}}
<p>
µEforth (micro-Eforth) simplifies EForth even futher, by building just enough
of the core of the system in C to allow the rest to be be built in proper Forth.
</p>
<p>
A handful of "tricky" words that involve internal loops or many steps are built in their own
functions:
</p>
<pre>
FIND ( a n -- xt | 0 )
PARSE ( ch -- a n )
S&gt;NUMBER? ( a n -- n f | 0 )
CREATE ( "name" -- )
EVALUATE1 ( -- )
</pre>
<p>
This includes <code>EVALUATE1</code> which parses a single word and
interprets or compiles it (reusing <code>PARSE</code>,
<code>FIND</code>, and <code>S&gt;NUMBER?</code>).
</p>
<p>
See <a href="https://github.com/flagxor/eforth/blob/main/common/core.h">core.h</a>.
</p>
<p>
A few global variables connect parsing and compilation state between
C and Forth (by way of a memory region accessed via <code>'SYS</code>):
</p>
<pre>
'TIB --- Pointer to the Translation Input Buffer
#TIB --- Length of the Translation Input Buffer
&gt;IN --- Number of characters consumed from TIB
BASE --- Numeric base for printing and parsing
STATE --- State of compiling, -1 for compiling, 0 for interpreting
CURRENT --- Pointer to pointer to last word of current vocabulary
CONTEXT --- Pointer to pointer to last word of context vocabulary
'NOTFOUND --- Execution token of a handler to call on word not found
</pre>
<p>
Error handling is routed via a deferred callback in <code>'NOTFOUND</code>
used when a word is absent from the dictionary.
This is eventually directed to an error routing that prints
a proper error, once I/O and exceptions are available.
</p>
<p>
<a href="https://en.wikipedia.org/wiki/X_Macro">X-Macros</a>
are then used to build up a small set of core opcodes defined in 1-3 lines each:
</p>
<pre>
0= 0&lt; + U/MOD */MOD AND OR XOR
LSHIFT RSHIFT DUP SWAP OVER DROP
@ SL@ SW@ C@ ! L! W! C! SP@ SP! RP@ RP!
&gt;R R&gt; R@ : ; EXIT
EXECUTE BRANCH 0BRANCH DONEXT DOLIT
ALITERAL CELL DOES&gt; IMMEDIATE 'SYS
</pre>
<p><b>NOTE: Later to reduce the use of the RAM heap and improve performance,
additional non-essential extra opcodes were added in place of high-level
words.</b></p>
<p>
See <a href="https://github.com/flagxor/eforth/blob/main/common/opcodes.h">opcodes.h</a>.
</p>
<p>
I/O and access to systems outside Forth are connected via a few per platform words.
Typically this set of words should be minimal, while still allowing relevant parts
of the host system to be available to Forth.
</p>