summary refs log tree commit diff
path: root/core.e
diff options
context:
space:
mode:
Diffstat (limited to 'core.e')
-rw-r--r--core.e69
1 files changed, 53 insertions, 16 deletions
diff --git a/core.e b/core.e
index c10ac00..51ab9f7 100644
--- a/core.e
+++ b/core.e
@@ -1200,12 +1200,8 @@ here !
 
 ~ (output point, alignment byte count -- output point)
 : packalign
-  2dup /% drop 0branch [ 8 8 * , ]
-  swap 0 pack8 swap branch [ -11 8 * , ]
-  drop ;
-  ~ TODO this is the implementation we could use if we had more flow-control
-  ~ { 2dup /% drop { drop exit } unless
-  ~  swap 0 pack8 swap } forever ;
+  { 2dup /% drop { drop exit } unless
+    swap 0 pack8 swap } forever ;
 
 
 ~ Binary unpacking
@@ -1265,13 +1261,11 @@ here !
 ~ assembly, or with high-level flow control, but it doesn't seem urgent...
 
 : max
-  2dup >=
-  0branch [ 2 8 * , ] swap
+  2dup >= { swap } if
   drop ;
 
 : min
-  2dup <=
-  0branch [ 2 8 * , ] swap
+  2dup <= { swap } if
   drop ;
 
 : over swap dup 3unroll ;
@@ -1280,15 +1274,11 @@ here !
 ~   Standard Forth doesn't have equivalents of our ndrop and ndup. The HP
 ~ calls them DROPN and DUPN but that doesn't go well with ie. 2dup or 3roll,
 ~ so we do it like this.
-: ndrop
-  dup 0branch [ 6 8 * , ] swap drop 1-
-  branch [ -7 8 * , ]
-  drop ;
+: ndrop { dup } { swap drop 1- } while drop ;
 
 : ndup
   dup 1+ swap
-  dup 0branch [ 9 8 * , ] swap dup pick 3unroll swap 1-
-  branch [ -10 8 * , ]
+  { dup } { swap dup pick 3unroll swap 1- } while
   2drop ;
 
 : 3drop drop drop drop ;
@@ -1301,3 +1291,50 @@ here !
 
 : align-floor dup 3unroll /% swap drop * ;
 
+
+~   Find-in is the main word that provides the capability to look up words by
+~ name, though it's usually used via "find" rather than being called directly.
+~
+~   Find-in traverses the linked list formed by a particular dictionary's
+~ next-entry pointers, looking for an entry that matches a given name. The
+~ dictionary pointer is the pointer (not handle) to the root of the list,
+~ which runs from newest to oldest. For example, dereferencing the value of
+~ "latest" gives the pointer to the main dictionary, which can be passed to
+~ find-in.
+~
+~   Having find-in separated out is convenient when working with alternate
+~ dictionaries, but the main reason for having it is not convenience but
+~ necessity: During Evocation's startup, there is a period before global
+~ variables are easily accessible, so there would be no way to implement
+~ "find". The warm-start routine (see execution.e and transform.e) has the
+~ job of fixing that, and it makes extensive use of find-in to do so.
+~
+~ TODO this probably deserves its own file?
+~
+~ (dictionary pointer, string pointer -- entry pointer or 0)
+: find-in
+  ~ It will be more convenient to have the entry pointer on top.
+  swap
+
+  {
+    ~ If the entry pointer is null, exit.
+    ~ (name pointer to find, current entry pointer)
+    dup 0 = { swap drop exit } if
+
+    ~ Check this entry's "hidden" flag.
+    ~ (name pointer to find, current entry pointer)
+    dup entry-flags@ 0x80 & 0x80 != {
+      ~ Test whether this entry is a match.
+      ~ (name pointer to find, current entry pointer)
+      2dup 10 + stringcmp 0 = {
+        ~ If we're here, it's a match. Clean up our working state and exit.
+        ~ (name pointer to find, current entry pointer)
+        swap drop exit
+      } if
+    } if
+
+    ~ If we're here, it's not a match; traverse the pointer and repeat.
+    ~ (name pointer to find, current entry pointer)
+    @
+  } forever ;
+