about summary refs log tree commit diff
path: root/compilation
diff options
context:
space:
mode:
Diffstat (limited to 'compilation')
-rw-r--r--compilation/top-level.e247
1 files changed, 171 insertions, 76 deletions
diff --git a/compilation/top-level.e b/compilation/top-level.e
index 7c714cb..0cc5a93 100644
--- a/compilation/top-level.e
+++ b/compilation/top-level.e
@@ -16,13 +16,30 @@
 
 
 : compilation-definition-top-level-filename ;
-: compilation-definition-static-filenames 8 + ;
-: compilation-definition-dynamic-filenames 2 8 * + ;
-: compilation-definition-boot-filenames 3 8 * + ;
-: compilation-definition-compile-header 4 8 * + ;
-: compilation-definition-compile-footer 5 8 * + ;
+: compilation-definition-executable-type 8 + ;
+: compilation-definition-static-filenames 2 8 * + ;
+: compilation-definition-dynamic-filenames 3 8 * + ;
+: compilation-definition-boot-filenames 4 8 * + ;
+: compilation-definition-compile-header 5 8 * + ;
+: compilation-definition-compile-body 6 8 * + ;
+: compilation-definition-compile-footer 7 8 * + ;
 : allocate-compilation-definition
-  6 8 * allocate ;
+  8 8 * allocate ;
+
+s" :raw-executable" keyword
+s" :forth-executable" keyword
+
+~ (definition structure pointer --)
+: zero-compilation-definition
+  dup compilation-definition-top-level-filename 0 swap !
+  dup compilation-definition-executable-type 0 swap !
+  dup compilation-definition-static-filenames 0 swap !
+  dup compilation-definition-dynamic-filenames 0 swap !
+  dup compilation-definition-boot-filenames 0 swap !
+  dup compilation-definition-compile-header 0 swap !
+  dup compilation-definition-compile-body 0 swap !
+  dup compilation-definition-compile-footer 0 swap !
+  drop ;
 
 
 ~   This accepts a pointer to an existing buffer for file contents to be
@@ -44,84 +61,137 @@
 
 
 ~ (static source filename list, dynamic source filename list, boot source
-~  filename list -- source to precompile, source to copy to log,
-~  source to copy textually)
+~  filename list -- source to label transform, source to log-load transform,
+~  boot source)
 : read-inputs
-  here @ dup
-  ~ (static source filename list, dynamic source filename list,
-  ~  boot source filename list, source to precompile, buffer point)
-  4 pick read-inputs-from-filename-list
-  0 pack8 8 packalign here !
-  ~ (static source filename list, dynamic source filename list,
-  ~  boot source filename list, source to precompile)
-
-  here @ dup
-  ~ (static source filename list, dynamic source filename list,
-  ~  boot source filename list, source to precompile, source to copy to log,
-  ~  buffer point)
-  5 pick read-inputs-from-filename-list
-  4 pick read-inputs-from-filename-list
-  0 pack8 8 packalign here !
+  2 pick {
+    here @ dup
+    ~ (static source filename list, dynamic source filename list,
+    ~  boot source filename list, source to label-transform, buffer point)
+    4 pick read-inputs-from-filename-list
+    0 pack8 8 packalign here !
+  } { 0 } if-else
   ~ (static source filename list, dynamic source filename list,
-  ~  boot source filename list, source to precompile, source to copy to log)
-
-  here @ dup
+  ~  boot source filename list, source to label-transform)
+
+  3 pick 3 pick || {
+    here @ dup
+    ~ (static source filename list, dynamic source filename list,
+    ~  boot source filename list, source to label-transform,
+    ~  source to log-load transform, buffer point)
+    5 pick dup { read-inputs-from-filename-list } { drop } if-else
+    4 pick dup { read-inputs-from-filename-list } { drop } if-else
+    0 pack8 8 packalign here !
+  } { 0 } if-else
   ~ (static source filename list, dynamic source filename list,
-  ~  boot source filename list, source to precompile, source to copy to log,
-  ~  source to copy textually, buffer point)
-  4 pick read-inputs-from-filename-list
-  0 pack8 8 packalign here !
+  ~  boot source filename list, source to label-transform,
+  ~  source to log-load transform)
+
+  2 pick {
+    here @ dup
+    ~ (static source filename list, dynamic source filename list,
+    ~  boot source filename list, source to label-transform,
+    ~  source to log-load transform, boot source, buffer point)
+    4 pick read-inputs-from-filename-list
+    0 pack8 8 packalign here !
+  } { 0 } if-else
   ~ (static source filename list, dynamic source filename list,
-  ~  boot source filename list, source to precompile, source to copy to log,
-  ~  source to copy textually)
+  ~  boot source filename list, source to label-transform,
+  ~  source to log-load transform, boot source)
 
   4 roll drop 4 roll drop 4 roll drop ;
 
 
-~ (output memory start, current output point,
-~  compile-header execution token, compile-footer execution token,
-~  source to precompile, source to copy to log, source to include textually
+~ (output memory start, current output point, definition structure pointer,
+~  source to label-transform, source to log-load transform, boot source
 ~  -- output memory start, current output point)
 : output-contents
-  7 roll 7 roll
-  ~ (compile-header execution token, compile-footer execution token,
-  ~  source to precompile, source to copy to log, source to include textually,
-  ~  output memory start, current output point)
-
-  ~ Invoke the provided header callback.
-  7 roll execute
-  ~ (compile-footer execution token, source to precompile,
-  ~  source to copy to log, source to include textually, output memory start,
+  6 roll 6 roll
+  ~ (definition structure pointer, source to label-transform,
+  ~  source to log-load transform, boot source, output memory start,
   ~  current output point)
 
-  elf-file-header
-  elf-program-header
+  ~ Switch based on the executable type.
+  5 pick compilation-definition-executable-type @
+  ~ (definition structure pointer, source to label-transform,
+  ~  source to log-load transform, boot source, output memory start,
+  ~  current output point, executable type)
 
-  output-cold-start
+  dup :raw-executable = {
+    drop 3roll drop 3roll drop 3roll drop
+  ~ (definition structure pointer, output memory start, current output point)
 
-  ~ Warm start and the log-loaded source.
-  output-warm-start-header
-  4 roll log-load-transform
-  ~ (compile-footer execution token, source to precompile,
-  ~  source to include textually, output memory start, current output point)
-  output-warm-start-post-log-load-transform
-  output-warm-start-attach-boot-source
-  output-warm-start-footer
+    ~ Invoke the provided header callback, if it's nonzero.
+    2 pick compilation-definition-compile-header @
+    dup { execute } { drop } if-else
 
-  ~ The label-transformed source.
-  4 roll label-transform
-  ~ (compile-footer execution token, source to include textually,
-  ~  output memory start, current output point, final entry pointer)
+    ~ Invoke the provided body callback, if it's nonzero.
+    2 pick compilation-definition-compile-body @
+    dup { execute } { drop } if-else
 
-  ~ The boot source.
-  4 roll output-boot-source
-  ~ (compile-footer execution token, output memory start,
-  ~  current output point)
+    ~ Invoke the provided footer callback, if it's nonzero.
+    2 pick compilation-definition-compile-footer @
+    dup { execute } { drop } if-else
+
+    3roll drop
+
+    ~ (output memory start, current output point)
+    exit
+  } if
+
+  dup :forth-executable = {
+    drop
+    ~ (definition structure pointer, source to label-transform,
+    ~  source to log-load transform, boot source, output memory start,
+    ~  current output point)
+
+    ~ Invoke the provided header callback, if it's nonzero.
+    5 pick compilation-definition-compile-header @
+    dup { execute } { drop } if-else
+
+    elf-file-header
+    elf-program-header
 
-  ~ Invoke the provided footer callback.
-  3roll execute
-  ~ (output memory start, current output point)
-  ;
+    output-cold-start
+
+    ~ Warm start and the log-loaded source.
+    output-warm-start-header
+    4 roll log-load-transform
+    ~ (definition structure pointer, source to label-transform, boot source,
+    ~  output memory start, current output point)
+    output-warm-start-post-log-load-transform
+    output-warm-start-attach-boot-source
+    output-warm-start-footer
+
+    ~ The label-transformed source.
+    4 roll label-transform
+    ~ (definition structure pointer, boot source, output memory start,
+    ~  current output point, final entry pointer)
+
+    3unroll
+
+    ~ Invoke the provided body callback, if it's nonzero.
+    4 pick compilation-definition-compile-body @
+    dup { execute } { drop } if-else
+
+    3roll
+
+    ~ The boot source.
+    4 roll output-boot-source
+    ~ (definition structure pointer, output memory start,
+    ~  current output point)
+
+    ~ Invoke the provided footer callback, if it's nonzero.
+    2 pick compilation-definition-compile-footer @
+    dup { execute } { drop } if-else
+
+    3roll drop
+
+    ~ (output memory start, current output point)
+    exit
+  } if
+
+  ." Invalid executable type in compilation definition." 1 sys-exit ;
 
 
 ~   Given a compilation-definition structure which is a description of an
@@ -130,21 +200,22 @@
 ~
 ~ (definition structure pointer --)
 : enchant-from-definition
+  ~   We do this work here, rather than inside output-contents, because it
+  ~ would be wasteful to do it in every iteration of the label-loop.
   dup dup dup
   compilation-definition-boot-filenames @ 3unroll
   compilation-definition-dynamic-filenames @ 3unroll
   compilation-definition-static-filenames @ 3unroll
   read-inputs
-  ~ (definition structure pointer, source to precompile,
-  ~  source to copy to log, source to copy textually)
+  ~ (definition structure pointer, source to label-transform,
+  ~  source to log-load transform, boot source)
 
   ~   We need an execution token to pass to label-loop. There's no reason to
   ~ create a dictionary entry for it; we just allocate space for the
   ~ executable word body directly.
   here @
   docol ,
-  4 pick compilation-definition-compile-header @ literal
-  4 pick compilation-definition-compile-footer @ literal
+  5 roll literal
   4 roll literal
   3 roll literal
   swap literal
@@ -183,6 +254,11 @@
 ~
 ~ (definition structure pointer --)
 : inscribe-from-definition
+  ~   If we're inscribing something other than "evoke", we need to load
+  ~ evoke's source also, first.
+  s" evoke-executable-data" find dup { entry-to-execution-token execute } if
+  swap
+
   ~   We begin by constructing the full text of all the source that will be
   ~ run inside the scope of the hex transform. That necessarily includes not
   ~ only the compilation machinery, but the transformation system. Notably
@@ -190,17 +266,36 @@
   ~ "enchant", and having a stray unused copy of inscribe is harmless, so we
   ~ don't try to exclude it.
   here @ dup
-  ~ (definition structure pointer, hex-transformed source pointer,
-  ~  output point)
+  ~ (parent definition structure pointer, definition structure pointer,
+  ~  hex-transformed source pointer, output point)
+
+  3 pick 3 pick != {
+    3 pick compilation-definition-static-filenames @
+    dup { read-inputs-from-filename-list } { drop } if-else
+  } if
 
   2 pick compilation-definition-static-filenames @
-  read-inputs-from-filename-list
+  dup { read-inputs-from-filename-list } { drop } if-else
+
+  3 pick 3 pick != {
+    3 pick compilation-definition-dynamic-filenames @
+    dup { read-inputs-from-filename-list } { drop } if-else
+  } if
 
   2 pick compilation-definition-dynamic-filenames @
-  read-inputs-from-filename-list
+  dup { read-inputs-from-filename-list } { drop } if-else
+
+  3 pick 3 pick != {
+    3 pick compilation-definition-boot-filenames @
+    dup { read-inputs-from-filename-list } { drop } if-else
+  } if
 
   2 pick compilation-definition-boot-filenames @
-  read-inputs-from-filename-list
+  dup { read-inputs-from-filename-list } { drop } if-else
+
+  4 roll drop
+  ~ (definition structure pointer, hex-transformed source pointer,
+  ~  output point)
 
   ~   The top-level source file will try to look up its own filename, but this
   ~ is all on standard input, so it doesn't have one. We must deceive it!