about summary refs log tree commit diff
path: root/language
diff options
context:
space:
mode:
Diffstat (limited to 'language')
-rw-r--r--language/boot-source-footer.e15
-rw-r--r--language/dynamic/command-line.e53
2 files changed, 65 insertions, 3 deletions
diff --git a/language/boot-source-footer.e b/language/boot-source-footer.e
index e95fc0e..8889c0f 100644
--- a/language/boot-source-footer.e
+++ b/language/boot-source-footer.e
@@ -2,7 +2,18 @@
 ~ last thing in the boot-source. It has the responsibility of switching from
 ~ processing boot-source into the regular interaction mode.
 
-process-command-line-arguments
+: finish-boot-source
+  ~   Once we do the relink, nothing after that point in the boot source will
+  ~ be read. Since we do have another operation to do before we actually hand
+  ~ over control to "quit", we need to do the relink in a compiled word like
+  ~ this.
+  relink-main-input-buffer-to-stdin
 
-relink-main-input-buffer-to-stdin
+  ~   It may be helpful, if you're doing anything interesting at the command
+  ~ line, to keep this order of operations in mind.
+  process-command-line-arguments ;
+
+~   Notionally we could have this word be non-hidden, but there's no reason to
+~ ever use it again, so out of a spirit of tidiness...
+x' finish-boot-source make-hidden execute
 
diff --git a/language/dynamic/command-line.e b/language/dynamic/command-line.e
index 8e2d812..4b3ab6d 100644
--- a/language/dynamic/command-line.e
+++ b/language/dynamic/command-line.e
@@ -1,3 +1,28 @@
+~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~ ~~ Command-line parameter semantics ~~
+~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~
+~   The Evocation executable runs as a command-line tool. As part of that, it
+~ accepts command-line parameters via the POSIX argc/argv interface. The code
+~ in this file implements the semantics of those parameters.
+~
+~   The rule is quite simple: Each parameter is treated as a single word, and
+~ run as if by "interpret". When a parameter is neither a regular word nor an
+~ integer literal, if it looks like it could be a source code filename, the
+~ file it names is read as if by "include", except that the success flag is
+~ discarded.
+~
+~   Nothing special is done to make command-line parameters appear as if
+~ they're an input stream; they're not. They're special words that are invoked
+~ before standard input is touched. Anything words run as command-line
+~ parameters try to do to standard input will draw on standard input as usual,
+~ despite that not being where they themselves come from, which will likely
+~ cause unwanted behavior. See language/boot-source-footer.e for the exact
+~ sequence of events during startup.
+~
+~   In particular, this means that words such as s" and ', which try to read
+~ input, are unlikely to do what you want as command-line parameters.
+
 8 2 * allocate s" argument-scan-state" variable
 : argument-scan-state-next-argument-handle ;
 : argument-scan-state-n-remaining-arguments 8 + ;
@@ -11,6 +36,28 @@
   argument-scan-state argument-scan-state-next-argument-handle @
   argument-scan-state argument-scan-state-n-remaining-arguments @ ;
 
+
+~   This tests whether a string looks like it could be an Evocation
+~ source-code filename.
+~
+~   Specifically, it looks for an extension of *.e. Also, it disallows ".e" by
+~ itself as a filename, requiring the length to be at least three characters.
+~
+~   This comparison is done case-sensitively. This means that, even on a
+~ case-insensitive filesystem, from Evocation's perspective we always require
+~ the extension to be treated as lowercase.
+~
+~ (string pointer -- boolean)
+: is-possible-source-filename
+  dup stringlen
+  ~ (string pointer, length)
+  dup 2 < {
+    2 - + s" .e" stringcmp 0 =
+  } {
+    2drop 0
+  } if-else ;
+
+
 ~ (argument pointer -- *)
 : process-command-line-argument
   dup find dup {
@@ -34,7 +81,11 @@
       } if-else
     } {
       ~ (argument pointer)
-      ." No such word: " emitstring newline
+      dup is-possible-source-filename {
+        include drop
+      } {
+        ." No such word: " emitstring newline
+      } if-else
     } if-else
   } if-else ;