diff options
author | dos-reis <gdr@axiomatics.org> | 2008-01-28 04:16:25 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2008-01-28 04:16:25 +0000 |
commit | a27cc2ac7bf6a0ad60cc6c9f949a988d0444bb4e (patch) | |
tree | cb71095e082c97f38f06f11828ca1f898ba3f72e /src | |
parent | 58cae19381750526539e986ca1de122803ac2293 (diff) | |
download | open-axiom-a27cc2ac7bf6a0ad60cc6c9f949a988d0444bb4e.tar.gz |
* boot/Makefile.pamphlet: Remove.
* boot/translator.boot: New.
* boot/translator.boot: Remove.
* boot/tokens.boot: New.
* boot/tokens.boot.pamphlet: Remove.
* boot/scanner.boot: New.
* boot/scanner.boot.pamphlet: Remove.
* boot/pile.boot: New.
* boot/pile.boot.pamphlet: Remove.
* boot/parser.boot: New.
* boot/parser.boot.pamphlet: New.
* boot/initial-env.lisp: New.
* boot/initial-env.lisp.pamphlet: Remove.
* boot/includer.boot: New.
* boot/includer.boot.pamphlet: Remove.
* boot/ast.boot: New.
* boot/ast.boot.pamphlet: Remove.
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 20 | ||||
-rw-r--r-- | src/boot/Makefile.in | 191 | ||||
-rw-r--r-- | src/boot/Makefile.pamphlet | 1630 | ||||
-rw-r--r-- | src/boot/ast.boot | 1087 | ||||
-rw-r--r-- | src/boot/includer.boot | 390 | ||||
-rw-r--r-- | src/boot/includer.boot.pamphlet | 1226 | ||||
-rw-r--r-- | src/boot/initial-env.lisp (renamed from src/boot/initial-env.lisp.pamphlet) | 174 | ||||
-rw-r--r-- | src/boot/parser.boot | 1041 | ||||
-rw-r--r-- | src/boot/pile.boot | 143 | ||||
-rw-r--r-- | src/boot/scanner.boot | 514 | ||||
-rw-r--r-- | src/boot/strap/ast.clisp (renamed from src/boot/ast.boot.pamphlet) | 1517 | ||||
-rw-r--r-- | src/boot/strap/includer.clisp | 553 | ||||
-rw-r--r-- | src/boot/strap/parser.clisp (renamed from src/boot/parser.boot.pamphlet) | 1161 | ||||
-rw-r--r-- | src/boot/strap/pile.clisp (renamed from src/boot/pile.boot.pamphlet) | 171 | ||||
-rw-r--r-- | src/boot/strap/scanner.clisp (renamed from src/boot/scanner.boot.pamphlet) | 537 | ||||
-rw-r--r-- | src/boot/strap/tokens.clisp | 352 | ||||
-rw-r--r-- | src/boot/strap/translator.clisp (renamed from src/boot/translator.boot.pamphlet) | 861 | ||||
-rw-r--r-- | src/boot/tokens.boot | 411 | ||||
-rw-r--r-- | src/boot/tokens.boot.pamphlet | 897 | ||||
-rw-r--r-- | src/boot/translator.boot | 751 |
20 files changed, 5719 insertions, 7908 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c52458b5..5bdbf5f8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,25 @@ 2008-01-27 Gabriel Dos Reis <gdr@cs.tamu.edu> + * boot/Makefile.pamphlet: Remove. + * boot/translator.boot: New. + * boot/translator.boot: Remove. + * boot/tokens.boot: New. + * boot/tokens.boot.pamphlet: Remove. + * boot/scanner.boot: New. + * boot/scanner.boot.pamphlet: Remove. + * boot/pile.boot: New. + * boot/pile.boot.pamphlet: Remove. + * boot/parser.boot: New. + * boot/parser.boot.pamphlet: New. + * boot/initial-env.lisp: New. + * boot/initial-env.lisp.pamphlet: Remove. + * boot/includer.boot: New. + * boot/includer.boot.pamphlet: Remove. + * boot/ast.boot: New. + * boot/ast.boot.pamphlet: Remove. + +2008-01-27 Gabriel Dos Reis <gdr@cs.tamu.edu> + Fix SF/1872551 * interp/c-util.boot (dollarIfRepHack): New. (RepIfRepHack): Likewise. diff --git a/src/boot/Makefile.in b/src/boot/Makefile.in index 94d98c33..c438d385 100644 --- a/src/boot/Makefile.in +++ b/src/boot/Makefile.in @@ -1,9 +1,68 @@ +## Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd. +## All rights reserved. +## Copyright (C) 2007-2008, Gabriel Dos Reis. +## All rights reserved. +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## +## - Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## +## - Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## +## - Neither the name of The Numerical ALgorithms Group Ltd. nor the +## names of its contributors may be used to endorse or promote products +## derived from this software without specific prior written permission. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +## IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +## PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +## OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +## + +## +## Abstract: +## OpenAxiom is built in layers. The first layer is contructed into +## an image called `bootsys'. The `bootsys' image is used +## to translate Boot code to Common Lisp code. Since a Boot coded +## interpreter is needed to translate the code for the Boot coded +## interpreter we have a ``boot-strapping'' problem. In order to get +## the whole process to start we need certain files kept in +## common lisp form. This directory contains those files. +## + +## We start with a Lisp image created in a previous build step (src/lisp). +## That image is used to build Boot translator executable through the +## entire bootstrap process. + AXIOM_LOCAL_LISP_sources = initial-env.lisp AXIOM_LOCAL_LISP = ../lisp/lisp$(EXEEXT) -PROCLAIMS=(load "$(srcdir)/boot-proclaims.lisp") + +## FASLs that comprises `bootsys' +boot_SOURCES = initial-env.lisp $(boot_sources) +boot_sources = tokens.boot includer.boot scanner.boot \ + pile.boot ast.boot parser.boot translator.boot +boot_clisp = $(boot_sources:.boot=.clisp) boot_objects = initial-env.$(FASLEXT) $(boot_sources:.boot=.$(FASLEXT)) +# Garbage produced by GCL during compilation +boot_data = $(boot_sources:.boot=.data) +boot_fn = $(boot_sources:.boot=.fn) + +## ## ECL's program construction model is not based on image-dumping. It is ## closer to `traditional C' application building. Therefore, since ## bootsys is an augmentation of base-lisp, we need to have the objects @@ -12,28 +71,10 @@ ifeq (@axiom_lisp_flavor@,ecl) boot_objects_extra = ../lisp/core.$(FASLEXT) endif -boot_SOURCES = \ - initial-env.lisp.pamphlet \ - $(addsuffix .pamphlet, $(boot_sources)) - -pamphlets = Makefile.pamphlet $(boot_SOURCES) -boot_sources = tokens.boot includer.boot scanner.boot \ - pile.boot ast.boot parser.boot translator.boot - -boot_clisp = $(boot_sources:.boot=.clisp) -boot_data = $(boot_sources:.boot=.data) -boot_fn = $(boot_sources:.boot=.fn) -boot_cached_clisp = $(boot_sources:.boot=.clisp) - -COMPILE_LISP = \ - $(axiom_build_document) --tag=lisp --mode=compile --output=$@ - -BOOT_TO_LISP = \ - $(axiom_build_document) --tag=boot --mode=translate \ - --use=./prev-stage/bootsys $< - +# reference to this directory from toplevel subdir = src/boot/ +## Make rule toplevel entry points. .PHONY: all-ax all-boot all: all-ax all-boot @@ -43,119 +84,139 @@ stamp: $(axiom_build_bindir)/bootsys$(EXEEXT) @rm -f stamp $(STAMP) $@ +## The final `bootsys' image. $(axiom_build_bindir)/bootsys$(EXEEXT): stage2/bootsys$(EXEEXT) $(mkinstalldirs) $(axiom_build_bindir) $(INSTALL_PROGRAM) stage2/bootsys$(EXEEXT) $(axiom_build_bindir) -.PRECIOUS: stage0/%.clisp -.PRECIOUS: stage0/%.$(FASLEXT) +.PRECIOUS: strap/%.$(FASLEXT) + +## +## The bootstrapping `bootsys' image. +## -stage0_boot_clisp = $(addprefix stage0/, $(boot_clisp)) +# The bootstrapping Lisp code is cached in the subdirectory strap/. +# It is built first, followed by stage 1, and stage 2 `bootsys' images. +strap_boot_clisp = $(addprefix strap/, $(boot_clisp)) -stage0_boot_objects = $(addprefix stage0/, $(boot_objects)) +strap_boot_objects = \ + $(addprefix strap/, $(boot_objects)) -stage0/stamp: stage0/bootsys$(EXEEXT) +strap/stamp: strap/bootsys$(EXEEXT) @rm -f $@ @$(STAMP) $@ -stage0/bootsys$(EXEEXT): $(stage0_boot_objects) +strap/bootsys$(EXEEXT): $(strap_boot_objects) $(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|"\ - --output=$@ --load-directory=stage0 \ - $(boot_objects_extra) $(stage0_boot_objects) + --output=$@ --load-directory=strap \ + $(boot_objects_extra) $(strap_boot_objects) -.PRECIOUS: %/.started -%/.started: - $(mkinstalldirs) $* - $(STAMP) $@ - -$(stage0_boot_objects): $(AXIOM_LOCAL_LISP) - -stage0/%.clisp: $(srcdir)/%.boot.pamphlet stage0/.started - $(axiom_build_document) --tangle=$*.clisp --output=$@ $< +$(strap_boot_objects): $(AXIOM_LOCAL_LISP) -%/initial-env.$(FASLEXT): initial-env.lisp %/.started - $(AXIOM_LOCAL_LISP) -- --compile --output=$@ $< +## +## Stage 1 `bootsys' image. +## .PRECIOUS: stage1/%.$(FASLEXT) .PRECIOUS: stage1/%.clisp +stage1_boot_clisp = $(addprefix stage1/, $(boot_clisp)) + +stage1_boot_objects = \ + $(addprefix stage1/, $(boot_objects)) + stage1/stamp: stage1/bootsys$(EXEEXT) rm -f $@ $(STAMP) $@ -stage1/bootsys$(EXEEXT): $(addprefix stage1/, $(boot_objects)) +stage1/bootsys$(EXEEXT): $(stage1_boot_objects) $(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|" \ --output=$@ --load-directory=stage1 \ - $(boot_objects_extra) $(addprefix stage1/, $(boot_objects)) + $(boot_objects_extra) $(stage1_boot_objects) + +stage1/%.clisp: %.boot strap/stamp stage1/.started + strap/bootsys -- --translate --output=$@ $< + -stage1/%.clisp: %.boot stage0/stamp stage1/.started - stage0/bootsys -- --translate --output=$@ $< +## +## Stage 2 `bootsys' image. +## .PRECIOUS: stage2/%.$(FASLEXT) .PRECIOUS: stage2/%.clisp +stage2_boot_clisp = $(addprefix stage2/, $(boot_clisp)) + +stage2_boot_objects = \ + $(addprefix stage2/, $(boot_objects)) + stage2/stamp: stage2/bootsys$(EXEEXT) @echo Building stage 2 $(STAMP) $@ -stage2/bootsys$(EXEEXT): $(addprefix stage2/, $(boot_objects)) +stage2/bootsys$(EXEEXT): $(stage2_boot_objects) $(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|" \ --output=$@ --load-directory=stage2 \ - $(boot_objects_extra) $(addprefix stage2/, $(boot_objects)) + $(boot_objects_extra) $(stage2_boot_objects) stage2/%.clisp: %.boot stage1/stamp stage2/.started stage1/bootsys -- --translate --output=$@ $< +## +## Generic rules for compiling FASLs +## + +.PRECIOUS: %/.started +%/.started: + $(mkinstalldirs) $* + $(STAMP) $@ + ## Dependency for various modules. ## FIXME: This should be automatically extracted from the ## Boot source file at packaging time. +%/initial-env.$(FASLEXT): initial-env.lisp %/.started + $(AXIOM_LOCAL_LISP) -- --compile --output=$@ $< + %/tokens.$(FASLEXT): %/tokens.clisp %/initial-env.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< + $(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $< %/includer.$(FASLEXT): %/includer.clisp %/tokens.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< + $(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $< %/scanner.$(FASLEXT): %/scanner.clisp %/tokens.$(FASLEXT) %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< + $(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $< %/pile.$(FASLEXT): %/pile.clisp %/scanner.$(FASLEXT) %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< + $(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $< %/ast.$(FASLEXT): %/ast.clisp %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< + $(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $< %/parser.$(FASLEXT): %/parser.clisp %/ast.$(FASLEXT) %/scanner.$(FASLEXT) \ %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< + $(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $< %/translator.$(FASLEXT): %/translator.clisp %/parser.$(FASLEXT) \ %/ast.$(FASLEXT) %/pile.$(FASLEXT) %/scanner.$(FASLEXT) \ %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -.PRECIOUS: %.boot -%.boot: $(srcdir)/%.boot.pamphlet - $(axiom_build_document) --tangle $< -.PRECIOUS: %.boot + $(AXIOM_LOCAL_LISP) -- --output=$@ --compile --load-directory=$* $< -%.boot: $(srcdir)/%.boot.pamphlet - $(axiom_build_document) --tangle $< -.PRECIOUS: %.lisp -initial-env.lisp: initial-env.lisp.pamphlet - $(axiom_build_document) --tangle $< +## +## Cleaning mess +## mostlyclean-local: @rm -f $(axiom_build_bindir)/bootsys$(EXEEXT) @rm -rf prev-stage - @rm -rf stage0 stage1 stage2 + @rm -rf strap stage1 stage2 @rm -f *.data *.fn @rm -f stamp clean-local: mostlyclean-local @rm -f $(boot_sources) - @rm -f *.clisp *.lisp + @rm -f *.clisp distclean-local: clean-local diff --git a/src/boot/Makefile.pamphlet b/src/boot/Makefile.pamphlet deleted file mode 100644 index 6ce07945..00000000 --- a/src/boot/Makefile.pamphlet +++ /dev/null @@ -1,1630 +0,0 @@ -%% Oh Emacs, this is a -*- Makefile -*-, so give me tabs. -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/Makefile} Pamphlet} -\author{Timothy Daly \and Gabriel Dos~Reis} - -\begin{document} -\maketitle - -\begin{abstract} - \Tool{OpenAxiom} is built in layers. The first layer is contructed into - an image called {\bf bootsys}. The \Tool{bootsys} image is used - to translate Boot code to Common Lisp code. Since a Boot coded - interpreter is needed to translate the code for the Boot coded - interpreter we have a ``boot-strapping'' problem. In order to get - the whole process to start we need certain files kept in - common lisp form. This directory contains those files. -\end{abstract} -\eject - -\tableofcontents -\eject - -\section{Introduction} -\label{sec:intro} - -The Scratchpad language is implemented by using a mixture of Lisp and -a more convenient language for writing Lisp called \emph{Boot}. -This document contains a description of the Boot language, and some -details of the resulting Lisp programs. -The description of the translation -functions available are at the end of this file. - -The main difference between Lisp and Boot is in the syntax for -the application of a function to its argument. -The Lisp format [[(F X Y Z)]], means, when [[F]] is a function, -the application of [[F]] to its arguments [[X]], [[Y]], and [[Z]], -is written in Boot as [[F(X,Y,Z)]]. -When [[F]] is a special Lisp word it will be written -in Boot by using some other syntactic construction, such as spelling -in CAPITAL LETTERS. - -Boot contains an easy method of writing expressions that denote lists, -and provides an analogous method of writing patterns containing variables -and constants which denote a particular class of lists. The pattern -is matched against a particular list at run time, -and if the list belongs to the class then its variables will -take on the values of components of the list. Similarly, Boot provides -an easy way of writting discriminated unions or algebraic types, and -pattern matching as found in ML. - - A second convenient feature provided by Boot is a method of -writing programs that iterate over the elements of one or more lists -and which either transform the state of the machine, or -produce some object from the list or lists. - - -\section{Boot To Common Lisp Translaters} -\label{sec:boot-to-cl} - -The Boot to Common Lisp translation is organized in several -separate logical phases. At the moment, those phases are not -really separate; but from a logical point of view, it is better -to think of them that way. - - -\subsection{The Boot Includer} -\label{sec:boot-to-cl:includer} - -The Boot Includer is the module that reads Boot codes from source files. -The details of the Includer, as well as the grammar of the include -files are to be found in \File{includer.boot} - - -\subsection{The Scanner} -\label{sec:boot-to-cl:scanner} - -The tokenization process is implemented in \File{scanner.boot}. Further -details about keywords and reserved identifiers are available in -\File{tokens.boot}. - - -\subsection{Piling} -\label{sec:boot-to-cl:piling} - -The Boot language uses layout to delimit blocks of expressions. After -the scanner pass, and before the parser pass is another pass called -\emph{piling}. The piling pass inserts tokens to unambiguously delimit -the boundaries of piles. This is implemented in -\File{pile.boot} - - -\subsection{The Parser} -\label{sec:boot-to-cl:piling} - -The Boot parser is implemented in \File{parser.boot}. It is a hand-written -recursive descent parser -based on \emph{parser combinators} methodology. Thoe files also -implicitly defines the grammar of the Boot language. - - -\subsection{The Transformer} -\label{sec:boot-to-cl:transfo} - -As observed earlier, the Boot language was originally defined as a syntactic -sugar over Common Lisp. Consequently, it semantics is defined by -tranformation to Lisp. The transformers are defined in -\File{ast.boot}. - -\subsection{Utils} -\label{sec:boot-to-cl:utils} - -Finally, the file \File{translator.boot} is a pot-pourri of many utility -functions. It also contains the entry points to the Boot translater. - - -\section{Boot} -\label{sec:boot} - -\subsection{Lines and Commands} - -If the first character of a line is a closing parenthesis the line -is treated as a command which controls the lines that will be -passed to the translater rather than being passed itself. -The command [[)include filename]] filemodifier will for example -be replaced by the lines in the file [[filename filemodifier]]. - -If a line starts with a closing parenthesis it will be called a command -line, otherwise it will be called a plain line. -The command lines are -\begin{verbatim} -name as written - -Include )include filename filemodifier -IncludeLisp )includelisp filename filemodifier -If )if bootexpression -Else )else -ElseIf )elseif bootexpression -EndIf )endif -Fin )fin -Say )say string -Eval )eval bootexpression -EvalStrings )evalstrings bootexpression -Package )package packagename - -SimpleLine::= PlainLine | Include | IncludeLisp |Say | Eval | EvalStrings - | Package -\end{verbatim} - -A [[PlainLine]] is delivered to the translater as is. - -An [[Include]] delivers the lines in the file filename.filemodifier, -treated as boot lines. - -An [[IncludeLisp]] delivers the lines in the specified file, treated as Lisp -lines. The only comments allowed in lisp files that are included in -this way require that the semicolon is at the beginning of the line. - -A [[Say]] outputs the remainder of the line to the console, - delivering nothing to the translater. - -An [[Eval]] translates the reminder of the line, assumed to be - written in Boot, to Lisp, and evaluates it, delivering nothing to - the translater. - -An [[EvalStrings]] also translates and evaluates the rest of the line - but this time assumes that the Boot expression denotes a list - of strings which are then delivered to the translater - instead of the EvalString line. The strings are treated as Boot lines. - -It is also possible to include or exclude lines based upon some -condition which is the result of translating and evaluating -the boot expression that follows an )if or )elseif command. -This construction will be called a Conditional. A file will be -composed from SimpleLines and Conditionals. A file is either -terminated by the end of file or by a Fin line. -\begin{verbatim} -Components ::=(SimpleLine | Conditional)* - -File ::= Components ( Fin | empty) - -A conditional is bracketed by an If and an EndIf. - -Conditional ::= If Components Elselines EndIf -\end{verbatim} - -If the boot expression following the )if has value true then the -Components are delivered but not the ElseLines, -otherwise the Components are ignored ,and the ElseLines -are delivered to the translater. In any case the lines after -the EndIf are then processed. -\begin{verbatim} -ElseLines ::= Else Components | ElseIf Components ElseLines | empty -\end{verbatim} - -When the Elselines of a Conditional is being included then if an -"Else Components" phrase is encountered then the following -Components are included -otherwise if an "ElseIf Components ElseLines" phrase is encountered then -the boot expression following the )elseif is evaluated and -if true the following Components are included, if false the -following ElseLines is included. - - -\subsection{Boot syntax and semantics} - -The semantics of Boot was originally defined by translation to Lisp. -Ideally, we would like to give it a self-contained semantics, -without explicitly referring to Lisp, or if we must we should use -lambda calculus. - -\subsubsection{Source character set} -\label{sec:boot:char-set} - -???What is the source character set??? That of Common Lisp? - -\subsubsection{Identifiers} -\label{sec:boot:identifier} - -The standard identifiers start with a letter ([[a-z]] or [[A-Z]]) -dollar sign ([[$]]), question mark ([[?]]), or the percent sign -([[\%]]), and are followed by any number of letters, digits, single -quotes([[']]), question marks, or percent signs. -It is possible however, by using the escape character ([[\_]]), -to construct identifiers that contain any -characters except the blank or newline character. The rules in this case -are that an escape character followed by any non-blank character -will start an identifier with that character. Once an identifier -has been started either in this way or by a letter, [[$]], or -[[%]], then it may be continued either with a letter, digit, -quote , question mark or percent sign, or with -an escape character followed by any non-blank character. -Certain words having the form of identifiers are not classified as -such, but are reserved words. They are listed below. - -An identifier ends when a blank or end of line is encountered, or -an escape character followed by a blank or end of line, or a -character which is not a letter, digit, quote, question mark -or percent sign is found. Two identifiers are equal if the -strings produced by replacing each escape followed by a character -by that character are equal character by character. - -\subsubsection{Numbers} -\label{sec:boot:number} - -Integers start with a digit ([[0-9]]) and are followed by any number -of digits. The syntax for floating point numbers is -\begin{verbatim} -<.I | I. | I.I> <E|e> <+ | - | empty> I -\end{verbatim} -where I is an integer. - -\subsubsection{Strings} -\label{sec:boot:string} - -Strings of characters are enclosed by double quote signs. They cannot -span two or more lines and an escape character within a string will -include the next character regardless of its nature. -The meaning of a string depends somewhat on the context in which -it is found, but in general a bare string denotes the interned atom -making up its body whereas when it is preceded by a single quote (') -it denotes the string of characters enclosed. - -\subsubsection{S-expressions} -\label{sec:boot:s-expression} - -An s-expression is preceded by a single quote and is followed by -a Lisp s-expression. -\begin{verbatim} -sexpression ::=identifier | integer | MINUS integer | float | string - | QUOTE sexpression | parenthesized sexpression1 - -sexpression1 ::=sexpression (DOT sexpression | sexpression1)| empty -\end{verbatim} - -There are two ways to quote an iddentifier: either 'name or "name", which -both give rise to (QUOTE name). However a string that is a -component of an sexpression will denote the string unless it is the -sole component of the s-expression in which case it denotes a string -i.e. '"name" gives rise to "name" in Lisp rather than (QUOTE "name"). - - -\subsubsection{Keywords} -\label{sec:boot:keyword} - -The table of key words follows, each is given an upper case -name for use in the description of the syntax. -\begin{verbatim} - as written name - - and AND - by BY - case CASE - cross CROSS - else ELSE - for FOR - if IF - in IN - is IS - isnt ISNT - of OF - or OR - repeat REPEAT - return RETURN - structure STRUCTURE - then THEN - until UNTIL - where WHERE - while WHILE - . DOT - : COLON - , COMMA - ; SEMICOLON - * TIMES - ** POWER - / SLASH - + PLUS - - MINUS - < LT - > GT - <= LE - >= GE - = SHOEEQ - ^ NOT - ^= NE - .. SEG - # LENGTH - => EXIT - := BEC - == DEF - ==> MDEF - ( OPAREN - ) CPAREN - (| OBRACK - |) CBRACK - [ OBRACK - ] CBRACK - suchthat BAR - ' QUOTE - | BAR -\end{verbatim} - -\subsubsection{Primary} -\label{sec:boot:primar-expr} - -\begin{verbatim} -constant::= integer | string | float | sexpression -\end{verbatim} - -The value of a constant does not depend on the context in which it -is found. -\begin{verbatim} -primary::= name | constant | construct | block | tuple | pile -\end{verbatim} - -The primaries are the simplest constituents of the language and -either denote some object or perform some transformation of the -machine state, or both. -The statements are the largest constituents and enclosing them -in parentheses converts them into a primary. - -An alternative method of grouping uses indentation to indicate the -parenthetical structure. -A number of lines whose first non-space characters are in the same -column will be called a \emph{pile}. The translater first tokenizes the -lines producing identifier, key word, integer, string or float tokens, -and then examines the pile structure of a Boot program -in order to add additional tokens called [[SETTAB]], [[BACKTAB]] -and [[BACKSET]]. -These tokens may be considered as commands for creating a pile. -The [[SETTAB]] starts a new line indented from the previous line and -pushes the resulting column number on to a stack of tab positions. -The [[BACKTAB]] will start a new line at the column position found -at the head of the stack and removes it from the stack. -The [[BACKSET]] has the same effect as a [[BACKTAB]] immediately followed -by a [[SETTAB]]. -The meaning of a sequence of tokens containing [[SETTAB]], -[[BACKTAB]], and [[BACKSET]] is the same the sequence in which each -[[SETTAB]] is replaced by [[OPAREN]] , each [[BACKTAB]] is replaced by -[[CPAREN]], and each [[BACKSET]] is replaced by [[SEMICOLON]]. By -construction the [[BACKTABS]] and [[SETTABS]] are properly nested. -\begin{verbatim} -listof(p,s)== p | p s ... s p - -parenthesized s ::= OPAREN s CPAREN -piled s ::= SETTAB s BACKTAB - -blockof s ::= parenthesized (listof (s,SEMICOLON)) -pileof s ::= piled (listof (s,BACKSET )) -\end{verbatim} - -A pileof s has the same meaning as a blockof s. -There is however a slight difference because piling is weaker than -separation by semicolons. In other words the pile items -may be listof(s,SEMICOLON). -In other words if statements::= listof(statement,SEMICOLON) then -we can have a pileof statements which has the same meaning as -the flattened sequence formed by replacing -all [[BACKSET]]'s by [[SEMICOLON]]'s. - -A blockof statement is translated to a compound statement -e.g. in the absence of any exits, -(a;b;c;d) is translated to (PROGN a b c d). - -\subsubsection{Selectors} -\label{sec:boot:selector} - -\begin{verbatim} -selector::= leftassociative(primary, DOT) -\end{verbatim} - -A selector [[a.b]] denotes some component of a structure, and in -general is translated to [[(ELT a b)]]. There are some special identifiers -that may be used in the [[b]] position to denote list components, of which -more later. -The [[DOT]] has a greater precedence than juxtaposition and is -left associative, For example -\begin{verbatim} -a.b.c is grouped as (a.b).c which is translated to - (ELT (ELT a b) c) - -application ::= selector selector ... selector - -\end{verbatim} - -Application of function to argument is denoted by juxtaposition. - -A sequence of selectors is right associative and so -[[f g h x]] is grouped as [[f(g(h x))]]. The applications [[f x]] and -[[f(x)]] -mean the application of [[f]] to [[x]] and get translated to -the Lisp [[(f x)]]. The application of a function to the empty list -is written [[f()]], meaning the Lisp [[(f)]]. [[f(x,y,z)]] gets translated to -the Lisp [[(f x y z)]]. -Common Lisp does not permit a variable to occur in operator position, -so that when f is a variable its application has to be -put in argument position of a [[FUNCALL]] or [[APPLY]]. -[[f(x,y,z)]] has to be replaced by [[FUNCALL(f,x,y)]] which gets translated to -the Lisp [[(FUNCALL f x y z)]]. -In Common Lisp each symbol might refer -to two objects a function and a non-function. In order to resolve -this ambiguity when a function symbol appears in a context other -than operator position it has to be preceded by the symbol [[FUNCTION]]. -Also it is possible to produce the function type symbol from the -non-function symbol by applying [[SYMBOL-FUNCTION]] to it. - -Certain reserved words called infixed operators namely -[[POWER]], [[TIMES]], [[SLASH]], [[PLUS]], [[MINUS]], [[IS]], -[[EQ]], [[NE]] , [[GT]], [[GE]], [[LT]], [[LE]], [[IN]], [[AND]], -[[OR]], indicate application by being placed between their 2 arguments. - -Infixed application may be either right- or left-associative. -\begin{verbatim} -rightassociative(p,o)::= p o p o p o ... o p - == p o (p o (p o ... o p))) - -leftassociative(p,o)::= p o p o p o ... o p - == (((p o p) o p) o ...) o p - - -exponent ::= rightassociative(application,POWER) - -reduction ::= (infixedoperator |string | thetaname) SLASH application -\end{verbatim} - -In a reduction the application denotes a list of items and -operator [[SLASH]] application accumulates the list elements from the -left using the operator -\begin{verbatim} -e.g. +/[a,b,c] means (((0+a)+b)+c) -\end{verbatim} - -Only certain operators are provided with values when the list is empty -they are [[and]], [[or]], [[+]], [[*]], [[max]], [[min]], [[append]], -[[union]]. However any function can be used as an operator by enclosing it -in double quotes. In this case the reduction is not applicable to an -empty list. -\begin{verbatim} -multiplication ::= rightassociative(exponent,TIMES|SLASH) | reduction - -minus ::= MINUS multiplication | multiplication - -arith ::= leftasscociative(minus,PLUS | MINUS) - -is ::= arith | arith (IS | ISNT) pattern - -comparison ::= is (EQ | NE | GT | GE | LT | LE | IN) is | is - -and ::= leftassociative (comparison,AND) - -return ::= and | RETURN and - -expression ::= leftassociative(return,OR) -\end{verbatim} - -The infixed operators denote application of the function to its -two arguments. To summarize, -the infixed operators are, in order of decreasing precedence -strengths. -\begin{verbatim} - . - juxtaposition - ** - * / - + - - is - = ^= > >= < <= in - and - or -\end{verbatim} - -\subsubsection{Conditionals} -\label{sec:boot:conditional} - -\begin{verbatim} -conditional ::= IF where THEN where | - IF where THEN where ELSE where - -IF a THEN b is translated to (COND (a b)) and -IF a THEN b else c is translated to (COND (a b) (T c)) - -statement::= conditional | loop | expression -\end{verbatim} - -\subsubsection{Loops} -\label{sec:boot:iteration} - -\begin{verbatim} -loop ::= crossproduct REPEAT statement | REPEAT statement - -iterator ::= forin | suchthat | until | while - -iterators ::= iterator iterator ... iterator - -crossproduct ::=rightassociative(iterators,CROSS) - -suchthat ::= BAR where - -while ::= WHILE expression - -until ::= UNTIL expression - -forin ::= for variable IN segment | - for variable IN segment BY arith - -segment::= arith | arith SEG arith | arith SEG -\end{verbatim} - -A loop performs an iterated transformation of the state which is -specified by its statement component and its iterators. -The forin construction introduces a new variable which is assigned -the elements of the list which is the value of the segment in the order -in which they appear in the list . - -A segment of the form [[arith]] denotes a list, -and segments of the form [[arith SEG arith]] and -[[arith SEG]] denote terminating and non-terminating -arithmetic progressions. -The [[BY arith]] option is the step size, if omitted the step is [[1]]. - -Two or more [[forin]]'s may control a loop. -The associated lists are scanned in parallel and -a variable of one [[forin]] may not appear in the segment expression that -denotes the list in a second [[forin]]. -Such a variable may however occur in the conditions for filtering or -introduced by a [[suchthat]], or for termination introduced by a -while iterator, and in the statement of the loop. -The [[forin]] variables are local to the statement, the conditions -that follow a [[while]] or [[suchthat]] in the same list of iterators and -have no meaning outside them. -The loop will be terminated when one of its [[forin]] lists is null, or -if the condition in a [[while]] is not satisfied. The list -elements are filtered by all the [[suchthat]] conditions. -The ordering of the iterators is irrelevant to the meaning, so it is -best to avoid side effects within the conditions for filtering and -termination. - -It is possible to control a loop by using a \emph{cross-product} of iterators. -The iteration in the case [[iterators1 CROSS iterators2]] is over -all pairs of list items one from the list denoted by -iterators1 and the other from the list denoted by iterators2. -In this case the variables introduced [[forin]] statements in -[[iterators1]] may be used in [[iterators2]]. - -\subsubsection{Lists} -\label{sec:boot:list} - -Boot contains a simple way of specifying lists that are constructed -by [[CONS]] and [[APPEND]], or by transforming one list to another in a -systematic manner. -\begin{verbatim} -construct ::= OBRACK construction CBRACK - -construction ::= comma | comma iteratortail - -iteratortail ::= REPEAT iterators | iterators -\end{verbatim} - -A construct expression denotes a list and may also have a list -of controlling iterators having the same syntax as a loop. In this -case the expression is enclosed in brackets and the iterators follow -the expression they qualify, rather than preceding it. - -In the case that there are no iterators the construct expression -denotes a list by listing its components separated by commas, or by -a comma followed by a colon. In the simple case in which there are no -colons the Boot expression [a,b,c,d] translates to the Lisp -[[(LIST a b c d)]] or [[(CONS a (CONS b (CONS c (CONS d NIL))))]]. - -When elements are separated by comma colon, however, the expression -that follows will be assumed to denote a list which will be appended -to the following list, rather than consed. An exception to this rule -is that a colon preceding the last expression is translated to -the expression itself. If it immediately preceded by a CONS -then it need not denote a list. - -For example: -\begin{verbatim} -[] is translated to the empty list NIL -[a] is translated to the 1-list (LIST a) or (CONS a NIL) -[:a] is translated to a -[a,b] is translated to the 2-list (LIST a b) or (CONS a (CONS b NIL)) -[:a,b] is translated to (APPEND a (CONS b NIL)) -[a,:b] is translated to (CONS a b) -[:a,:b] is translated to (APPEND a b) -[:a,b,c] is translated to (APPEND a (CONS b (CONS c NIL))) -[a,:b,c] is translated to (CONS a (APPEND b (CONS c NIL))) -[a,b,:c] is translated to (CONS a (CONS b c)) -\end{verbatim} - -If the construct expression has iterators that control the production -of the list the resulting list depends on the form of the comma -expression. -i.e. -\begin{verbatim} -construction ::= comma iteratortail -\end{verbatim} - -If the comma expression is recognised as denoting a list -by either preceding it by a colon, or having commas at top level -as above, then the successive values are appended. If not then -the successive values are consed. -e.g. -\begin{verbatim} -[f i for i in x] denotes the list formed by applying f to each - member of the list x. - -[:f i for i in 0..n] denotes the list formed by appending the - lists f i for each i in 0..n. -\end{verbatim} - -\subsubsection{Patterns} -\label{sec:boot:pattern} - -\begin{verbatim} -is ::= arith | arith IS pattern -\end{verbatim} - -The pattern in the proposition [[arith IS pattern]] has the same form -as the construct phrase without iterators. In this case, however it -denotes a class of lists rather than a list, and is composed -from identifiers rather than expressions. The proposition -is translated into a program that tests whether the arith expression -denotes a list that belongs to the class. If it does then the value -of the is expression is true and the identifiers in -the pattern are assigned the values of the corresponding -components of the list. If the list does not match the pattern -the value of the is expression is false and the values of the -identifier might be changed in some unknown way that reflects the -partial success of the matching. -Because of this uncertainty, -it is advisable to use the variables in a pattern -as new definitions rather than assigning to variables that are -defined elsewhere. -\begin{verbatim} -pattern::= identifier | constant | [ patternlist ] -\end{verbatim} - -The value of [[arith IS identifier]] is [[true]] and the value of -[[arith]] is assigned to the [[identifier]]. -[[(PROGN (SETQ identifier arith) T)]] -The expression [[arith IS constant]] is translated to -[[(EQUAL constant arith)]]. -The expression arith [[IS [ pattenlist ] ]] -produces a program which tests whether arith denotes a list -of the right length and that each patternitem matches the corresponding -list component. - -\begin{verbatim} -patternitem ::= EQ application | DOT | pattern | name := pattern -\end{verbatim} - -If the [[patternitem]] is [[EQ application]] then the value is true if -the component is [[EQUAL]] to the value of the application expression. -If the [[patternitem]] is [[DOT]] then the value is [[true]] regardless of the -nature of the component. It is used as a place-holder to test -whether the component exists. -If the patternitem is pattern then the component is matched against -the pattern as above. -If the [[patternitem]] is [[name:=pattern]] then the component is -matched against -the pattern as above, and if the value is [[true]] the component is assigned -to the name. This last provision enables both a component and -its components to be given names. -\begin{verbatim} -patternlist ::= listof(patternitem,COMMA)| - listof(patternitem,COMMA) COMMA patterntail - patterntail - -patterncolon ::= COLON patternitem - -patterntail ::= patterncolon | - patterncolon COMMA listof(patternitem,COMMA) -\end{verbatim} - -The [[patternlist]] may contain one colon to indicate that the following -patternitem can match a list of any length. In this case -the matching rule is to construct the expression -with [[CONS]] and [[APPEND]] from the pattern as shown above and then test -whether the list can be constructed in this way, and if so -deduce the components and assign them to identifiers. - -The effect of a pattern that occurs as a variable in a for iterator -is to filter the list by the pattern. -\begin{verbatim} -forin ::= for pattern IN segment -\end{verbatim} - -is translated to two iterators -\begin{verbatim} - for g IN segment | g IS pattern -\end{verbatim} -where [[g]] is an invented identifier. -\begin{verbatim} -forin ::= for (name:=pattern) IN segment -\end{verbatim} - -is translated to two iterators -\begin{verbatim} - for name IN segment BAR name IS pattern -\end{verbatim} - -in order to both filter the list elements, and name both elements and -their components. - -\subsubsection{Assignments} -\label{sec:boot:assignment} - -A pattern may also occur on the left hand side of an assignment -statement, and has a slightly different meaning. -The purpose in this case is to give names to the components -of the list which is the value of the right hand side. -In this case no checking -is done that the list matches the pattern precisely and the only -effect is to construct the selectors that correspond to -the identifiers in the pattern, apply them to the value of the -right hand side and assign the selected components -to the corresponding identifiers. -The effect of applying [[CAR]] or [[CDR]] to arguments to which they are not -applicable will depend on the underlying Lisp system. -\begin{verbatim} -assignment::= assignvariable BECOMES assignment| statement - -assignvariable := OBRACK patternlist CBRACK | assignlhs -\end{verbatim} - -The assignment having a pattern as its left hand side is reduced -as explained above to one or more assignments having an identifier -on the left hand side. -The meaning of the assignment depends on whether the identifier -starts with a dollar sign or not, if it is and whether it is followed by -[[:local]] or [[:fluid]]. -If the identifier does not start with a dollar sign it -is treated as local to the body of the function in which it -occurs, and -if it is not already an argument of the function, -a declaration to that effect is added to the Lisp code -by adding a [[PROG]] construction at top level within the body of the -function definition. Note also the all local variables and fluid variables -are treated this way, resulting in initialization to [[nil]] before -execution of the body of the function. Consequently care must be -exercised when assigning to Lisp special global variables. If you -do not want that implicitly initialization to [[nil]], then use the -explicit [[SETQ]] Lisp special form in an application syntax. - -If such an identifier assignment does not occur in the body -of a function but in a top level expression then -it is also treated as a local. The sole exception to this rule -is when the top level expression is an assignment to an identifier -in which case it is treated as global. - -If the left hand side of an assignment is an identifier that starts with -a dollar sign it will not be classified as a local but will -be treated as non-local. If it is also followed by [[:local]] then it -will be treated as a declaration of a [[FLUID]] (VMLisp) or [[SPECIAL]] -variable (Common Lisp) which will be given an initial value which is the -value of the right hand side of the assignment statement. -The [[FLUID]] or [[SPECIAL]] variables may be referred to or assigned to -by functions that are applied in the body of the declaration. - -If the left hand side of an assignment statement is -an identifier that does not start with a dollar sign followed -by [[:local]] then it will also be treated as a [[FLUID]] or [[SPECIAL]] -declaration, however it may only be assigned to in the body -of the function in which the assignment it occurs. -\begin{verbatim} -assignment::= assignvariable BECOMES assignment | statement - -assignvariable := OBRACK patternlist CBRACK | assignlhs - -assignlhs::= name | name COLON local | - name DOT primary DOT ... DOT primary -\end{verbatim} - -If the left hand side of an assignment has the form -\begin{verbatim} - name DOT primary DOT ... DOT primary -\end{verbatim} -the assignment statement will denote an updating of some component -of the value of name. In general [[name DOT primary := statement]] -will get translated to [[(SETELT name primary statement)]] or -[[(SETF (ELT name primary) statement)]] -There are however certain identifiers that denote components of -a list which will get translated to statements that update that -component (see appendix) e.g. -\begin{verbatim} -a.car:=b is translated to (SETF (CAR a) b) in Common Lisp. -\end{verbatim} -The iterated [[DOT]] is used to update components of components -and e.g - -\begin{verbatim} -a.b.c:=d is translated to (SETF (ELT (ELT a b)c) d) - -exit::= assignment | assignment EXIT where -\end{verbatim} - -The exit format [[assignment EXIT where]] is used to give a value to -a blockof or pileof statements in which it occurs at top level. - -The expression -\begin{verbatim} - (a =>b;c) will be translated to if a then b else c or - (COND (a b) (T c)) -\end{verbatim} - -If the exit is not a component of a blockof or pileof statements -then -\begin{verbatim} -a=>b will be translated to (COND (a b)) -\end{verbatim} - -\subsubsection{Definitions} - -Functions may be defined using the syntax -\begin{verbatim} -functiondefinition::= name DEF where | name variable DEF where - - -variable ::= parenthesized variablelist | pattern - -variableitem ::= - name| pattern | name BECOMES pattern | name IS pattern - -variablelist ::= variableitem | COLON name | - variableitem COMMA variablelist -\end{verbatim} - -Function definitions may only occur at top level or after a [[where]]. -The [[name]] is the name of the function being defined, and the -most frequently used form of the [[variable]] is either a single name -or a parenthesized list of names separated by commas. -In this case the translation to Lisp is straightforward, for example: -\begin{verbatim} -f x == E or f(x)==E is translated to (DEFUN f (x) TE) -f (x,y,z)==E is translated to (DEFUN f (x y z) TE) -f ()==E is translated to (DEFUN f () TE) -\end{verbatim} - -where [[TE]] is the translation of [[E]]. -At top level -\begin{verbatim} -f==E is translated to (DEFUN f () TE) -\end{verbatim} - -The function being defined is that which when applied to its arguments -produces the value of the body as result where the variables -in the body take on the values of its arguments. - -A pattern may also occur in the variable of a definition of a function -and serves the purpose, similar to the left hand side of assignments, -of naming the list components. -The phrase -\begin{verbatim} - name pattern DEF where -is translated to - name g DEF (pattern:=g;where) -\end{verbatim} - -similarly -\begin{verbatim} - name1 name2 := pattern DEF where or name1 name2 is pattern DEF where - -are both translated to - name1 name2 DEF (pattern:=name2;where) -\end{verbatim} - -similarly for patterns that occur as components of a list of -variables. order -\begin{verbatim} -variablelist ::= - variableitem | COLON name | variableitem COMMA variablelist -\end{verbatim} - -The parenthesized [[variablelist]] that occurs as a variable of a function -definition can contain variables separated by commas but can also -have a comma colon as its last separator. - -This means that the function is applicable to lists of different -sizes and that only the first few elements corresponding to the -variables separated by commas are named, and -the last name after the colon denotes the rest of the list. - -Macros may be defined only at top level, and must always have a variable -\begin{verbatim} -macrodefinition::= name variable MDEF where -\end{verbatim} - -The effect of a [[macrodefinition]] is to produce a Lisp macro -which is applied to arguments that are treated as expressions, rather -than their values, and whose result if formed by first substituting -the expressions for occurrences of the variables within the body -and then evaluating the resulting expression. - -\subsubsection{Where Clauses} -\label{sec:boot:where-clause} - -Expressions may be qualified by one or more function definitions -using the syntax -\begin{verbatim} -where ::= exit | exit WHERE qualifier - -qualifier ::= functiondefinition | - pileof (functiondefinition) | blockof functiondefinition -\end{verbatim} - -The functions may only be used within the expression that is qualified. -This feature has to be used with some care, however, because -a where clause may only occur within a function body, and -the component functions are extruded, so to speak, from their contexts -renamed, and made into top level function definitions. -As a result the variables of the outer function cannot be referred to -within the inner function. -If a qualifying function has the format [[name DEF where]] then -the [[where]] phrase is substituted for all occurences of the name -within the expression qualified. -If an expression is qualified by a phrase that is not a -function definition then the result will be a compound statement -in which the qualifying phrase is followed by the qualified phrase. - -\subsubsection{Tuples} -\label{sec:boot:tuples} - -Although a tuple may appear syntactically -in any position occupied by a primary -it will only be given meaning when it is the argument to a function. -To denote a list it has to be enclosed in brackets rather than -parentheses. A tuple at top level is treated as if its components -appeared at top level in the order of the list. -\begin{verbatim} -tuple::= parenthesized (listof (where,COMMA)) -\end{verbatim} - -\subsubsection{Blocks and Piles} -\label{sec:boot:block} - -\begin{verbatim} -block::= parenthesized (listof (where,SEMICOLON)) -pile::= piled (listof (listof(where,SEMICOLON),BACKSET)) -A block or a pile get translated to a compound statement or PROGN -\end{verbatim} - -\subsubsection{Top Level} -\label{sec:boot:top-level} - -\begin{verbatim} -toplevel ::= functiondefinition | macrodefinition | primary -\end{verbatim} - -\subsubsection{Translation Functions} -\label{sec:boot:translation} - -\begin{verbatim} -(boottocl "filename") -translates the file "filename.boot" to -the common lisp file "filename.clisp" -\end{verbatim} - -\begin{verbatim} -(bootclam "filename") -translates the file "filename.boot" to -the common lisp file "filename.clisp" -\end{verbatim} - -producing, for each function a -hash table to store previously computed values indexed by argument -list. The function first looks in the hash table for the result -if there returns it, if not computes the result and stores it in the -table. - -\begin{verbatim} -(boottoclc "filename") -translates the file "filename.boot" to -the common lisp file "filename.clisp" -with the original boot code as comments -\end{verbatim} - -\begin{verbatim} -(boot "filename") -translates the file "filename.boot" to -the common lisp file "filename.clisp", -compiles it to the file "filename.bbin" -and loads the bbin file. -\end{verbatim} - -\begin{verbatim} -(bo "filename") -translates the file "filename.boot" -and prints the result at the console -\end{verbatim} - -\begin{verbatim} -(stout "string") translates the string "string" -and prints the result at the console -\end{verbatim} - -\begin{verbatim} -(sttomc "string") translates the string "string" -to common lisp, and compiles the result. -\end{verbatim} - -\begin{verbatim} -(fc "functionname" "filename") -attempts to find the boot function -functionname in the file filename, -if found it translates it to common -lisp, compiles and loads it. -\end{verbatim} - -\begin{verbatim} -BOOT_-COMPILE_-DEFINITION_-FROM_-FILE(fn,symbol) - is similar to fc, fn is the file name but symbol is the symbol - of the function name rather than the string. -(fn,symbol) -\end{verbatim} - -\begin{verbatim} -BOOT_-EVAL_-DEFINITION_-FROM_-FILE(fn,symbol) -attempts to find the definition of symbol in file fn, but this time -translation is followed by EVAL rather than COMPILE -\end{verbatim} - -\begin{verbatim} -(defuse "filename") -Translates the file filename, and writes a report of the -functions defined and not used, and used and not defined in the -file filename.defuse -\end{verbatim} - -\begin{verbatim} -(xref "filename") -Translates the file filename, and writes a report of the -names used, and where used to the file filename.xref -\end{verbatim} - -\subsection{Reserved identifiers} -\label{sec:boot:reserved-identifiers} - -The following identifiers are reserved by Boot. -\begin{verbatim} - and append apply atom car cdr cons copy - croak drop exit false first function genvar IN - is isnt lastNode LAST list member mkpf nconc - nil not NOT nreverse null or otherwise PAIRP - removeDuplicates rest reverse setDifference - setIntersection setPart setUnion size strconc substitute - take true PLUS MINUS TIMES POWER SLASH LT - GT LE GE SHOEEQ NE T -\end{verbatim} - -The following identifiers designate special accessor functions in Boot. -\begin{verbatim} - setName setLabel setLevel setType setVar setLeaf - setLeaf setDef aGeneral aMode aTree aValue - attributes cacheCount cacheName cacheReset cacheType env - expr CAR mmCondition mmDC mmImplementation - mmSignature mmTarget mode op opcode opSig - CDR sig source streamCode streamDef streamName - target -\end{verbatim} - - -\section{The Makefile} -\label{sec:Makefile} - -When all of the native object files are produced we construct a -lisp image that contains the boot translator, called [[bootsys]], which -lives in the [[$(axiom_target_bindir)]] directory. This [[bootsys]] image -is critical for the rest of the makefiles to succeed. - -There are two halves of this file. the first half compiles the .lisp files -that live in the src/boot directory. the second half compiles the .clisp -files (which are generated from the .boot files). It is important that -the .clisp files are kept in the src/boot directory for the boot translator -as they cannot be recreated without a boot translator (a bootstrap problem). - -An important subtlety is that files in the boot translator depend on the -file npextras. there are 3 macros in npextras that must be in the lisp -workspace (\verb$|shoeOpenInputFile| |shoeOpenOutputFile| memq$). - -\subsection{Environment} -\label{sec:Makefile:env} - -\subsubsection{Lisp Images} -\label{sec:Makefile:env:lisp-images} - -We will use create and use several lisp images during the build -process. We name them here for convenience. - -\paragraph{[[AXIOM_LOCAL_LISP]].} We start with a Lisp image -created in a previous build step (src/lisp). That image is used -to build Boot translator executable through the entire bootstrap process. -<<environment>>= -AXIOM_LOCAL_LISP_sources = initial-env.lisp -AXIOM_LOCAL_LISP = ../lisp/lisp$(EXEEXT) -@ - - -\section{Proclaim optimization} -\label{sec:proclaim} - -GCL, and possibly other common lisps, can generate much better -code if the function argument types and return values are proclaimed. - -In theory what we should do is scan all of the functions in the system -and create a file of proclaim definitions. These proclaim definitions -should be loaded into the image before we do any compiles so they can -allow the compiler to optimize function calling. - -GCL has an approximation to this scanning which we use here. - -The first step is to build a version of GCL that includes gcl\_collectfn. -This file contains code that enhances the lisp compiler and creates a -hash table of structs. Each struct in the hash table describes information -that about the types of the function being compiled and the types of its -arguments. At the end of the compile-file this hash table is written out -to a ".fn" file. - -The second step is to build axiom images (depsys, interpsys, AXIOMsys) -which contain the gcl\_collectfn code. - -The third step is to build the system. This generates a .fn file for -each lisp file that gets compiled. - -The fourth step is to build the proclaims.lisp files. There is one -proclaims.lisp file for -boot (boot-proclaims.lisp), -interp (interp-proclaims.lisp), and -algebra (algebra-proclaims.lisp). - -To build the proclaims file (e.g. for interp) we: -\begin{verbatim} -(a) cd to obj/linux/interp -(b) (yourpath)/axiom/obj/linux/bin/lisp -(c) (load "sys-pkg.lsp") -(d) (mapcar #'load (directory "*.fn")) -(e) (with-open-file (out "interp-proclaims.lisp" :direction :output) - (compiler::make-proclaims out)) -\end{verbatim} -Note that step (c) is only used for interp, not for boot. - -The fifth step is to copy the newly constructed proclaims file back -into the src/interp diretory (or boot, algebra). - -In order for this information to be used during compiles we define -<<environment>>= -PROCLAIMS=(load "$(srcdir)/boot-proclaims.lisp") - -@ - -\section{Special Commands} -\label{sec:special-commands} - -We are working in a build environment that combines Makefile -technology with Lisp technology. Instead of invoking a command -like {\bf gcc} and giving it arguments we will be creating -Lisp S-expressions and piping them into a Lisp image. The -Lisp image starts, reads the S-expression from standard input, -evaluates it, and finding an end-of-stream on standard input, exits. - - -\section{The Boot Compiler} -\label{sec:boot-compiler} - -This section describes the set of object files that make the Boot compiler. - -\subsection{The Bootstrap files} -\label{sec:boot-compiler:bootstrap} - -This is a list of all of the files that must be loaded to construct the -boot translator image. -<<environment>>= -boot_objects = initial-env.$(FASLEXT) $(boot_sources:.boot=.$(FASLEXT)) - -## ECL's program construction model is not based on image-dumping. It is -## closer to `traditional C' application building. Therefore, since -## bootsys is an augmentation of base-lisp, we need to have the objects -## that made up base-lisp too. -ifeq (@axiom_lisp_flavor@,ecl) -boot_objects_extra = ../lisp/core.$(FASLEXT) -endif - -boot_SOURCES = \ - initial-env.lisp.pamphlet \ - $(addsuffix .pamphlet, $(boot_sources)) - -pamphlets = Makefile.pamphlet $(boot_SOURCES) -@ - -[[$(boot_sources)]] is a list of the boot file targets. If you modify a -boot file you'll have to explicitly build the clisp files and -merge the generated code back into the pamphlet by hand. The -assumption is that if you know enough to change the fundamental -bootstrap files you know how to migrate the changes back. -This process, by design, does not occur automatically (though it -could). - -The Boot compiler, [[bootsys]], is built from a set of source files -written in Boot. Note that the order is -important as earlier files will contain code needed by later files. -<<environment>>= -boot_sources = tokens.boot includer.boot scanner.boot \ - pile.boot ast.boot parser.boot translator.boot - -boot_clisp = $(boot_sources:.boot=.clisp) -boot_data = $(boot_sources:.boot=.data) -boot_fn = $(boot_sources:.boot=.fn) -@ -These source files use macros defined in the first set, and they be compiled -in an environment where those macros are present. - - - -The Boot source file for [[bootsys]] are automatically extracted --- -only during bootstrap --- from the pamphlets into the current build -directory. When bootstrapping, they are the inputs to the stage0, stage1 - [[bootsys]] compilers. - -<<boot from pamphlet>>= -.PRECIOUS: %.boot -%.boot: $(srcdir)/%.boot.pamphlet - $(axiom_build_document) --tangle $< -@ - -Since the Boot language is defined as a syntactic sugar over Lisp -(a reasonably tasty sugar), the -the second set of source files (written in Boot) is first translated -to Lisp, and the result of that translation is subsequently compiled to -native object files. - -Partly for bootstrapping reasons, and partly because OpenAxiom (therefore -Boot) is not yet widespread, the pamphlets for the source files written -in Boot currently keep a cache of their translated versions. Hopefully -the maintainance of that cache will be unnecessary as the build machinery -becomes more and more improved, and OpenAxiom gets in widespread use. -<<environment>>= -boot_cached_clisp = $(boot_sources:.boot=.clisp) -@ - -\section{Bootstrapping Boot} -\label{sec:bootstrapping} - -When the system is configured for bootstrap, we build the Boot compiler --- -[[bootsys]] --- in three steps: -\begin{enumerate} -\item a stage-0 Boot compiler, built from the cached (Lisp) source files; - -\item a stage-1 Boot compiler, built the original Boot source files using the - stage-0 Boot compiler; - -\item and a stage-2 Boot compiler, built from original Boot source files - using the stage-2 Boot compiler. -\end{enumerate} -Notice that in last two steps, the source file written in Boot are first -translated to Lisp using the freshly built Boot compiler, and the resulting -Lisp files subsequently compiled to natve object files. - -Ideally, we should also compare the intermediate Lisp source files from -stage 1 and 2 to detect possible miscompilation. We don't do that -for the moment. - -\subsection{Compiling the Boot source files} -\label{sec:bootstrapping:source-files} - -We compile the Boot compiler source files written in Boot only -at stage 1 and 2 (when bootstrapping). As explained earlier, the -compilation of these files proceeds in two steps: -\begin{enumerate} -\item Translate the Boot source files to Lisp code, -\item compile the resulting Lisp source files to native object code. -\end{enumerate} - -<<compile Boot files from pamphlets>>= -## Dependency for various modules. -## FIXME: This should be automatically extracted from the -## Boot source file at packaging time. - -%/tokens.$(FASLEXT): %/tokens.clisp %/initial-env.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -%/includer.$(FASLEXT): %/includer.clisp %/tokens.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -%/scanner.$(FASLEXT): %/scanner.clisp %/tokens.$(FASLEXT) %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -%/pile.$(FASLEXT): %/pile.clisp %/scanner.$(FASLEXT) %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -%/ast.$(FASLEXT): %/ast.clisp %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -%/parser.$(FASLEXT): %/parser.clisp %/ast.$(FASLEXT) %/scanner.$(FASLEXT) \ - %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -%/translator.$(FASLEXT): %/translator.clisp %/parser.$(FASLEXT) \ - %/ast.$(FASLEXT) %/pile.$(FASLEXT) %/scanner.$(FASLEXT) \ - %/includer.$(FASLEXT) - $(AXIOM_LOCAL_LISP) -- --compile --load-directory=$* $< - -<<boot from pamphlet>> -@ - -\subsection{Building [[bootsys]]} -\label{sec:bootstrapping:build-bootsys} - -\subsection{The various bootstrapping stages} -\label{sec:bootstrapping:stages} - -The bootstrapping phase is carried out in three stages: -\begin{itemize} -\item[Stage 0] we compile the cached Lisp translations of the Boot codes. - Currently, these translations are functionally equivalent - to the final \Tool{bootsys} we get out of the bootstrap. Ideally, - this should just be powerfull enough to translate the \Tool{bootsys} - Boot codes. The compilation of thee Lisp code is done with the - Lisp image [[$(AXIOM_LOCAL_LISP)]]. - -\item[Stage 1] Using the \Tool{bootsys} built from the previous - stage (\eg{} from - cached Lisp translations), we build a new \Tool{bootsys} from the - Boot codes proper. -\label{sec:bootstrapping:stages} - -\item[Stage 2] Finally, we build another (and final) \Tool{bootsys} image - using the \Tool{bootsys} from Stage 1. This is the \Tool{bootsys} - image that is used to build the rest of the OpenAxiom system. -\end{itemize} - -Stage 1 and Stage 2 are structurally identical. Ideally, we should be -doing a bootstrap compare. - -Although all the \Tool{bootsys} images are powerful enough to -compile Boot codes directly, we don't use them for compilation. -Instead, we the fresh, clean, [[$(AXIOM_LOCAL_LISP)]] image. -The reason is that the process of compiling a Boot source file -may have the side effect of loading a module in the compiler (as -by-product of resolving module dependencies). But such module -will contain objects already present in the compiler and being -used. Consequently, we must use a fresh image to guarantee -clean and reproductible build and semantics. Notice that only -the compilation of \Tool{bootsys} itself needs that care. -The rest of the OpenAxiom system should use \Tool{bootsys} to -compile Boot codes, instead of manually going through the -Lisp translation phase. - - -\subsubsection{Stage 0} -\label{sec:bootstrapping:stages:stage-0} - -We build the stage-0 Boot compiler from the cached Lisp souces code. -<<stage 0 boot compiler>>= -.PRECIOUS: stage0/%.clisp -.PRECIOUS: stage0/%.$(FASLEXT) - -stage0_boot_clisp = $(addprefix stage0/, $(boot_clisp)) - -stage0_boot_objects = $(addprefix stage0/, $(boot_objects)) - -stage0/stamp: stage0/bootsys$(EXEEXT) - @rm -f $@ - @$(STAMP) $@ - -stage0/bootsys$(EXEEXT): $(stage0_boot_objects) - $(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|"\ - --output=$@ --load-directory=stage0 \ - $(boot_objects_extra) $(stage0_boot_objects) - - -.PRECIOUS: %/.started -%/.started: - $(mkinstalldirs) $* - $(STAMP) $@ - -$(stage0_boot_objects): $(AXIOM_LOCAL_LISP) - -stage0/%.clisp: $(srcdir)/%.boot.pamphlet stage0/.started - $(axiom_build_document) --tangle=$*.clisp --output=$@ $< - -%/initial-env.$(FASLEXT): initial-env.lisp %/.started - $(AXIOM_LOCAL_LISP) -- --compile --output=$@ $< -@ - -\subsubsection{Stage 1} -\label{sec:bootstrapping:stages:stage-1} - -<<stage 1 boot compiler>>= -.PRECIOUS: stage1/%.$(FASLEXT) -.PRECIOUS: stage1/%.clisp - -stage1/stamp: stage1/bootsys$(EXEEXT) - rm -f $@ - $(STAMP) $@ - -stage1/bootsys$(EXEEXT): $(addprefix stage1/, $(boot_objects)) - $(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|" \ - --output=$@ --load-directory=stage1 \ - $(boot_objects_extra) $(addprefix stage1/, $(boot_objects)) - -stage1/%.clisp: %.boot stage0/stamp stage1/.started - stage0/bootsys -- --translate --output=$@ $< -@ - -\subsubsection{Stage 2} -\label{sec:bootstrapping:stages:stage-2} - -<<stage 2 boot compiler>>= -.PRECIOUS: stage2/%.$(FASLEXT) -.PRECIOUS: stage2/%.clisp - -stage2/stamp: stage2/bootsys$(EXEEXT) - @echo Building stage 2 - $(STAMP) $@ - -stage2/bootsys$(EXEEXT): $(addprefix stage2/, $(boot_objects)) - $(AXIOM_LOCAL_LISP) -- --make --main="|AxiomCore|::|topLevel|" \ - --output=$@ --load-directory=stage2 \ - $(boot_objects_extra) $(addprefix stage2/, $(boot_objects)) - -stage2/%.clisp: %.boot stage1/stamp stage2/.started - stage1/bootsys -- --translate --output=$@ $< -@ - -<<bootstrap>>= -<<stage 0 boot compiler>> - -<<stage 1 boot compiler>> - -<<stage 2 boot compiler>> -@ - - -\section{Making the documentation} -\label{sec:doc} - -\subsection{Compiling Lisp files without deps from pamphlets} -<<initial-env.lisp>>= -.PRECIOUS: %.lisp - -initial-env.lisp: initial-env.lisp.pamphlet - $(axiom_build_document) --tangle $< -@ - -\subsection{boot from pamphlet} -<<boot from pamphlet>>= -.PRECIOUS: %.boot - -%.boot: $(srcdir)/%.boot.pamphlet - $(axiom_build_document) --tangle $< -@ - - -\section{Making the documentation} -<<environment>>= - -COMPILE_LISP = \ - $(axiom_build_document) --tag=lisp --mode=compile --output=$@ - -BOOT_TO_LISP = \ - $(axiom_build_document) --tag=boot --mode=translate \ - --use=./prev-stage/bootsys $< -@ - -\section{Cleanup} -<<cleanup>>= -mostlyclean-local: - @rm -f $(axiom_build_bindir)/bootsys$(EXEEXT) - @rm -rf prev-stage - @rm -rf stage0 stage1 stage2 - @rm -f *.data *.fn - @rm -f stamp - -clean-local: mostlyclean-local - @rm -f $(boot_sources) - @rm -f *.clisp *.lisp - -distclean-local: clean-local -@ - - -\section{Global variables} - -The Boot implementation uses a number of global variables -for communication between several routines. Some of them follow -the syntactic convention of starting their names with [[$]]. Some -don't. - -\subsection{[[$linepos]]} - -\subsection{[[$f]]} - -\subsection{[[$r]]} - -\subsection{[[$ln]]} - -\subsection{[[$sz]]} - -\subsection{[[$n]]} - -\subsection{[[$floatok]]} - -\subsection{[[$bfClamming]]} - -\subsection{[[$GenVarCounter]]} - -\subsection{[[$inputstream]]} - -\subsection{[[$stack]]} - -\subsection{[[$stok]]} - -\subsection{[[$ttok]]} - -\subsection{[[$op]]} - -\subsection{[[$wheredefs]]} - -\subsection{[[$typings]]} - -\subsection{[[$returns]]} - -\subsection{[[$bpCount]]} - -\subsection{[[$bpParentCount]]} - -\subsection{[[$lispWordTable]]} - -\subsection{[[$bootUsed]]} - -\subsection{[[$bootDefinedTwice]]} - -\subsection{[[$used]]} - -\subsection{[[$letGenVarCounter]]} - -\subsection{[[$isGenVarCounter]]} - -\subsection{[[$inDefIS]]} - -\subsection{[[$fluidVars]]} - -\subsection{[[$locVars]]} - -\subsection{[[$dollarVars]]} - - - - -\section{The Makefile} -<<*>>= -<<environment>> - -subdir = src/boot/ - -.PHONY: all-ax all-boot -all: all-ax all-boot - -all-ax all-boot: stamp - -stamp: $(axiom_build_bindir)/bootsys$(EXEEXT) - @rm -f stamp - $(STAMP) $@ - -$(axiom_build_bindir)/bootsys$(EXEEXT): stage2/bootsys$(EXEEXT) - $(mkinstalldirs) $(axiom_build_bindir) - $(INSTALL_PROGRAM) stage2/bootsys$(EXEEXT) $(axiom_build_bindir) - -<<bootstrap>> - -<<compile Boot files from pamphlets>> -<<initial-env.lisp>> - -<<cleanup>> -@ - -\eject -\begin{thebibliography}{99} -\bibitem{1} src/boot/boothdr.lisp.pamphlet -\bibitem{2} src/boot/includer.boot.pamphlet -\bibitem{3} src/boot/pile.boot.pamphlet -\bibitem{4} src/boot/scanner.boot.pamphlet -\bibitem{5} src/boot/exports.lisp.pamphlet -\bibitem{7} src/boot/translator.boot.pamphlet -\bibitem{8} src/boot/parser.boot.pamphlet -\bibitem{9} src/boot/tokens.boot.pamphlet -\bibitem{10} src/boot/ast.boot.pamphlet -\end{thebibliography} -\end{document} diff --git a/src/boot/ast.boot b/src/boot/ast.boot new file mode 100644 index 00000000..4c0c02d4 --- /dev/null +++ b/src/boot/ast.boot @@ -0,0 +1,1087 @@ +-- Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd. +-- All rights reserved. +-- Copyright (C) 2007-2008, Gabriel Dos Reis. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + +-- +-- Abstract: +-- This file defines the AST data structure and helper functions +-- for representing Boot programs. +-- + +module '"boot-ast" +import '"includer" + +)package "BOOTTRAN" + +++ True means that Boot functions should be translated to use +++ hash tables to remember values. By default, functions are +++ translated with the obvious semantics, e.g. no caching. +$bfClamming := false + +++ A Boot string is no different from a Lisp string. Same holds +++ for symbols and sequences. In an ideal world, these would be +++ built-in/library data types. +String <=> STRING +Symbol <=> SYMBOL +Sequence <=> SEQUENCE + +++ Ideally, we would like to say that a List T if either nil or a +++ cons of a T and List of T. However, we don't support parameterized +++ alias definitions yet. +List <=> nil or cons + +++ Currently, the Boot processor uses Lisp symbol datatype for names. +++ That causes the BOOTTRAN package to contain more symbols than we would +++ like. In the future, we want want to intern `on demand'. How that +++ interacts with renaming is to be worked out. +structure Name == Name(Symbol) + +structure Ast == + Command(String) -- includer command + Module(String) -- module declaration + Import(String) -- import module + ImportSignature(Name, Signature) -- import function declaration + TypeAlias(Name, List, List) -- type alias definition + Signature(Name, Mapping) -- op: S -> T + Mapping(Ast, List) -- (S1, S2) -> T + SuffixDot(Ast) -- x . + Quote(Ast) -- 'x + EqualName(Name) -- =x -- patterns + Colon(Name) -- :x + QualifiedName(Name, Name) -- m::x + Bracket(Ast) -- [x, y] + UnboundedSegment(Ast) -- 3.. + BoundedSgement(Ast, Ast) -- 2..4 + Tuple(List) -- comma-separated expression sequence + ColonAppend(Ast, Ast) -- [:y] or [x, :y] + Is(Ast, Ast) -- e is p -- patterns + Isnt(Ast, Ast) -- e isnt p -- patterns + Reduce(Ast, Ast) -- +/[...] + PrefixExpr(Name, Ast) -- #v + Call(Ast, Sequence) -- f(x, y , z) + InfixExpr(Name, Ast, Ast) -- x + y + ConstantDefinition(Name, Ast) -- x == y + Definition(Name, List, Ast, Ast) -- f x == y + Macro(Name, List, Ast) -- m x ==> y + SuchThat(Ast) -- | p + Assignment(Ast, Ast) -- x := y + While(Ast) -- while p -- iterator + Until(Ast) -- until p -- iterator + For(Ast, Ast, Ast) -- for x in e by k -- iterator + Exit(Ast, Ast) -- p => x + Iterators(List) -- list of iterators + Cross(List) -- iterator cross product + Repeat(Sequence, Ast) -- while p repeat s + Pile(Sequence) -- pile of expression sequence + Append(Sequence) -- concatenate lists + Case(Ast, Sequence) -- case x of ... + Return(Ast) -- return x + Where(Ast, Sequence) -- e where f x == y + Structure(Ast, Sequence) -- structure Foo == ... + +-- TRUE if we are currently building the syntax tree for an 'is' +-- expression. +$inDefIS := false + +bfGenSymbol()== + $GenVarCounter:=$GenVarCounter+1 + INTERN(CONCAT ('"bfVar#",STRINGIMAGE $GenVarCounter)) + +bfListOf x==x + +bfColon x== ["COLON",x] + +bfColonColon(package, name) == + INTERN(SYMBOL_-NAME name, package) + +bfSymbol x== + STRINGP x=> x + ['QUOTE,x] + +bfDot()== "DOT" + +bfSuffixDot x==[x,"DOT"] + +bfEqual(name)== ["EQUAL",name] + +bfBracket(part) == part + +bfPile(part) == part + +bfAppend x== APPLY(function APPEND,x) + +bfColonAppend (x,y) == + if null x + then + if y is ["BVQUOTE",:a] + then ["&REST",["QUOTE",:a]] + else ["&REST",y] + else cons(CAR x,bfColonAppend(CDR x,y)) + +bfDefinition(bflhsitems, bfrhs,body) == + ['DEF,bflhsitems,bfrhs,body] + +bfMDefinition(bflhsitems, bfrhs,body) == + bfMDef('MDEF,bflhsitems,bfrhs,body) + +bfCompDef x == + case x of + ConstantDefinition(n, e) => x + otherwise => + x is [def, op, args, body] => + bfDef(def,op,args,body) + coreError '"invalid AST" + +bfBeginsDollar x== EQL('"$".0,(PNAME x).0) + +compFluid id== ["FLUID",id] + +compFluidize x== + IDENTP x and bfBeginsDollar x=>compFluid x + ATOM x =>x + EQCAR(x,"QUOTE")=>x + cons(compFluidize(CAR x),compFluidize(CDR x)) + +bfTuple x== ["TUPLE",:x] + +bfTupleP x==EQCAR(x,"TUPLE") + +bfTupleIf x== + if bfTupleP x + then x + else bfTuple x + +bfTupleConstruct b == + a:= if bfTupleP b + then cdr b + else [b] + or/[x is ["COLON",.] for x in a] => bfMakeCons a + ["LIST",:a] + +bfConstruct b == + a:= if bfTupleP b + then cdr b + else [b] + bfMakeCons a + +bfMakeCons l == + null l => NIL + l is [["COLON",a],:l1] => + l1 => ['APPEND,a,bfMakeCons l1] + a + ['CONS,first l,bfMakeCons rest l] + +bfFor(bflhs,U,step) == + if EQCAR (U,'tails) + then bfForTree('ON, bflhs, CADR U) + else + if EQCAR(U,"SEGMENT") + then bfSTEP(bflhs,CADR U,step,CADDR U) + else bfForTree('IN, bflhs, U) + +bfForTree(OP,lhs,whole)== + whole:=if bfTupleP whole then bfMakeCons cdr whole else whole + ATOM lhs =>bfINON [OP,lhs,whole] + lhs:=if bfTupleP lhs then CADR lhs else lhs + EQCAR(lhs,"L%T") => + G:=CADR lhs + [:bfINON [OP,G,whole],:bfSuchthat bfIS(G,CADDR lhs)] + G:=bfGenSymbol() + [:bfINON [OP,G,whole],:bfSuchthat bfIS(G,lhs)] + + +bfSTEP(id,fst,step,lst)== + initvar:=[id] + initval:=[fst] + inc:=if ATOM step + then step + else + g1:=bfGenSymbol() + initvar:=cons(g1,initvar) + initval:=cons(step,initval) + g1 + final:=if ATOM lst + then lst + else + g2:=bfGenSymbol() + initvar:=cons(g2,initvar) + initval:=cons(lst,initval) + g2 + ex:= + null lst=> [] + INTEGERP inc => + pred:=if MINUSP inc then "<" else ">" + [[pred,id,final]] + [['COND,[['MINUSP,inc], + ["<",id,final]],['T,[">",id,final]]]] + suc:=[['SETQ,id,["+",id,inc]]] + [[initvar,initval,suc,[],ex,[]]] + + +bfINON x== + [op,id,whole]:=x + if EQ(op,"ON") + then bfON(id,whole) + else bfIN(id,whole) + +bfIN(x,E)== + g:=bfGenSymbol() + [[[g,x],[E,nil],[['SETQ,g,['CDR, g]]],[], + [['OR,['ATOM,g],['PROGN,['SETQ,x,['CAR,g]] ,'NIL]]],[]]] + +bfON(x,E)== + [[[x],[E],[['SETQ,x,['CDR, x]]],[], + [['ATOM,x]],[]]] + +bfSuchthat p== [[[],[],[],[p],[],[]]] + +bfWhile p== [[[],[],[],[],[bfNOT p],[]]] + +bfUntil p== + g:=bfGenSymbol() + [[[g],[nil],[['SETQ,g,p]],[],[g],[]]] + +bfIterators x==["ITERATORS",:x] + +bfCross x== ["CROSS",:x] + +bfLp(iters,body)== + EQCAR (iters,"ITERATORS")=>bfLp1(CDR iters,body) + bfLpCross(CDR iters,body) + +bfLpCross(iters,body)== + if null cdr iters + then bfLp(car iters,body) + else bfLp(car iters,bfLpCross(cdr iters,body)) + +bfSep(iters)== + if null iters + then [[],[],[],[],[],[]] + else + f:=first iters + r:=bfSep rest iters + [append(i,j) for i in f for j in r] + +bfReduce(op,y)== + a:=if EQCAR(op,"QUOTE") then CADR op else op + op:=bfReName a + init:=GET(op,"SHOETHETA") + g:=bfGenSymbol() + g1:=bfGenSymbol() + body:=['SETQ,g,[op,g,g1]] + if null init + then + g2:=bfGenSymbol() + init:=['CAR,g2] + ny:=['CDR,g2] + it:= ["ITERATORS",:[[[[g],[init],[],[],[],[g]]],bfIN(g1,ny)]] + bfMKPROGN [['L%T,g2,y],bfLp(it,body)] + else + init:=car init + it:= ["ITERATORS",:[[[[g],[init],[],[],[],[g]]],bfIN(g1,y)]] + bfLp(it,body) + +bfReduceCollect(op,y)== + if EQCAR (y,"COLLECT") + then + body:=y.1 + itl:=y.2 + a:=if EQCAR(op,"QUOTE") then CADR op else op + op:=bfReName a + init:=GET(op,"SHOETHETA") + bfOpReduce(op,init,body,itl) + else + a:=bfTupleConstruct (y.1) + bfReduce(op,a) + +-- delayed collect + +bfDCollect(y,itl)== ["COLLECT",y,itl] + +bfDTuple x== ["DTUPLE",x] + +bfCollect(y,itl) == + y is ["COLON",a] => bf0APPEND(a,itl) + y is ["TUPLE",:.] => + newBody:=bfConstruct y + bf0APPEND(newBody,itl) + bf0COLLECT(y,itl) + +bf0COLLECT(y,itl)==bfListReduce('CONS,y,itl) + + +bf0APPEND(y,itl)== + g:=bfGenSymbol() + body:=['SETQ,g,['APPEND,['REVERSE,y],g]] + extrait:= [[[g],[nil],[],[],[],[['NREVERSE,g]]]] + bfLp2(extrait,itl,body) + +bfListReduce(op,y,itl)== + g:=bfGenSymbol() + body:=['SETQ,g,[op,y,g]] + extrait:= [[[g],[nil],[],[],[],[['NREVERSE,g]]]] + bfLp2(extrait,itl,body) + +bfLp1(iters,body)== + [vars,inits,sucs,filters,exits,value]:=bfSep bfAppend iters + nbody:=if null filters then body else bfAND [:filters,body] + value:=if null value then "NIL" else car value + exits:= ["COND",[bfOR exits,["RETURN",value]], + ['(QUOTE T),nbody]] + loop := ["LOOP",exits,:sucs] + if vars then loop := + ["LET",[[v, i] for v in vars for i in inits], loop] + loop + +bfLp2(extrait,itl,body)== + EQCAR (itl,"ITERATORS")=>bfLp1(cons(extrait,CDR itl),body) + iters:=cdr itl + bfLpCross + ([["ITERATORS",extrait,:CDAR iters],:CDR iters],body) + +bfOpReduce(op,init,y,itl)== + g:=bfGenSymbol() + body:= + EQ(op,"AND")=> + bfMKPROGN [["SETQ",g,y], + ['COND, [['NOT,g],['RETURN,'NIL]]]] + EQ(op,"OR") => + bfMKPROGN [["SETQ",g,y], + ['COND, [g,['RETURN,g]]]] + ['SETQ,g,[op,g,y]] + if null init + then + g1:=bfGenSymbol() + init:=['CAR,g1] + y:=['CDR,g1] + extrait:= [[[g],[init],[],[],[],[g]]] + bfMKPROGN [['L%T,g1,y],bfLp2(extrait,itl,body)] + else + init:=car init + extrait:= [[[g],[init],[],[],[],[g]]] + bfLp2(extrait,itl,body) + +bfLoop1 body == bfLp (bfIterators nil,body) + +bfSegment1(lo)== ["SEGMENT",lo,nil] + +bfSegment2(lo,hi)== ["SEGMENT",lo,hi] + +bfForInBy(variable,collection,step)== + bfFor(variable,collection,step) + +bfForin(lhs,U)==bfFor(lhs,U,1) + +bfLocal(a,b)== + EQ(b,"FLUID")=> compFluid a + EQ(b,"fluid")=> compFluid a + EQ(b,"local") => compFluid a + -- $typings:=cons(["TYPE",b,a],$typings) + a + +bfTake(n,x)== + null x=>x + n=0 => nil + cons(car x,bfTake(n-1,cdr x)) + +bfDrop(n,x)== + null x or n=0 =>x + bfDrop(n-1,cdr x) + +bfDefSequence l == ['SEQ,: l] + +bfReturnNoName a == + ["RETURN",a] + +bfSUBLIS(p,e)== + ATOM e=>bfSUBLIS1(p,e) + EQCAR(e,"QUOTE")=>e + cons(bfSUBLIS(p,car e),bfSUBLIS(p,cdr e)) + ++++ Returns e/p, where e is an atom. We assume that the ++++ DEFs form a system admitting a fix point; otherwise we may ++++ loop forever. That can happen only if nullary goats ++++ are recursive -- which they are not supposed to be. ++++ We don't enforce that restriction though. +bfSUBLIS1(p,e)== + null p =>e + f:=CAR p + EQ(CAR f,e)=> bfSUBLIS(p, CDR f) + bfSUBLIS1(cdr p,e) + +defSheepAndGoats(x)== + EQCAR (x,"DEF") => + [def,op,args,body]:=x + argl:=if bfTupleP args + then cdr args + else [args] + if null argl + then + opassoc:=[[op,:body]] + [opassoc,[],[]] + else + op1:=INTERN CONCAT(PNAME $op,'",",PNAME op) + opassoc:=[[op,:op1]] + defstack:=[["DEF",op1,args,body]] + [opassoc,defstack,[]] + EQCAR (x,"SEQ") => defSheepAndGoatsList(cdr x) + [[],[],[x]] + +defSheepAndGoatsList(x)== + if null x + then [[],[],[]] + else + [opassoc,defs,nondefs] := defSheepAndGoats car x + [opassoc1,defs1,nondefs1] := defSheepAndGoatsList cdr x + [append(opassoc,opassoc1),append(defs,defs1), + append(nondefs,nondefs1)] +--% LET + +bfLetForm(lhs,rhs) == ['L%T,lhs,rhs] + +bfLET1(lhs,rhs) == + IDENTP lhs => bfLetForm(lhs,rhs) + lhs is ['FLUID,.] => bfLetForm(lhs,rhs) + IDENTP rhs and not bfCONTAINED(rhs,lhs) => + rhs1 := bfLET2(lhs,rhs) + EQCAR(rhs1,'L%T) => bfMKPROGN [rhs1,rhs] + EQCAR(rhs1,'PROGN) => APPEND(rhs1,[rhs]) + if IDENTP CAR rhs1 then rhs1 := CONS(rhs1,NIL) + bfMKPROGN [:rhs1,rhs] + CONSP(rhs) and EQCAR(rhs,'L%T) and IDENTP(name := CADR rhs) => + -- handle things like [a] := x := foo + l1 := bfLET1(name,CADDR rhs) + l2 := bfLET1(lhs,name) + EQCAR(l2,'PROGN) => bfMKPROGN [l1,:CDR l2] + if IDENTP CAR l2 then l2 := cons(l2,nil) + bfMKPROGN [l1,:l2,name] + g := INTERN CONCAT('"LETTMP#",STRINGIMAGE $letGenVarCounter) + $letGenVarCounter := $letGenVarCounter + 1 + rhs1 := ['L%T,g,rhs] + let1 := bfLET1(lhs,g) + EQCAR(let1,'PROGN) => bfMKPROGN [rhs1,:CDR let1] + if IDENTP CAR let1 then let1 := CONS(let1,NIL) + bfMKPROGN [rhs1,:let1,g] + +bfCONTAINED(x,y)== + EQ(x,y) => true + ATOM y=> false + bfCONTAINED(x,car y) or bfCONTAINED(x,cdr y) + +bfLET2(lhs,rhs) == + IDENTP lhs => bfLetForm(lhs,rhs) + NULL lhs => NIL + lhs is ['FLUID,.] => bfLetForm(lhs,rhs) + lhs is ['L%T,a,b] => + a := bfLET2(a,rhs) + null (b := bfLET2(b,rhs)) => a + ATOM b => [a,b] + CONSP CAR b => CONS(a,b) + [a,b] + lhs is ['CONS,var1,var2] => + var1 = "DOT" or (CONSP(var1) and EQCAR(var1,'QUOTE)) => + bfLET2(var2,addCARorCDR('CDR,rhs)) + l1 := bfLET2(var1,addCARorCDR('CAR,rhs)) + null var2 or EQ(var2,"DOT") =>l1 + if CONSP l1 and ATOM CAR l1 then l1 := cons(l1,nil) + IDENTP var2 => + [:l1,bfLetForm(var2,addCARorCDR('CDR,rhs))] + l2 := bfLET2(var2,addCARorCDR('CDR,rhs)) + if CONSP l2 and ATOM CAR l2 then l2 := cons(l2,nil) + APPEND(l1,l2) + lhs is ['APPEND,var1,var2] => + patrev := bfISReverse(var2,var1) + rev := ['REVERSE,rhs] + g := INTERN CONCAT('"LETTMP#", STRINGIMAGE $letGenVarCounter) + $letGenVarCounter := $letGenVarCounter + 1 + l2 := bfLET2(patrev,g) + if CONSP l2 and ATOM CAR l2 then l2 := cons(l2,nil) + var1 = "DOT" => [['L%T,g,rev],:l2] + last l2 is ['L%T, =var1, val1] => + [['L%T,g,rev],:REVERSE CDR REVERSE l2, + bfLetForm(var1,['NREVERSE,val1])] + [['L%T,g,rev],:l2,bfLetForm(var1,['NREVERSE,var1])] + lhs is ["EQUAL",var1] => + ['COND,[["EQUAL",var1,rhs],var1]] + -- The original expression may be one that involves literals as + -- sub-patterns, e.g. + -- ['SEQ, :l, ['exit, 1, x]] := item + -- We continue the processing as if that expression had been written + -- item is ['SEQ, :l, ['exit, 1, x]] + -- and generate appropriate codes. + -- -- gdr/2007-04-02. + isPred := + $inDefIS => bfIS1(rhs,lhs) + bfIS(rhs,lhs) + ['COND,[isPred,rhs]] + + +bfLET(lhs,rhs) == + $letGenVarCounter : local := 1 +-- $inbfLet : local := true + bfLET1(lhs,rhs) + +addCARorCDR(acc,expr) == + NULL CONSP expr => [acc,expr] + acc = 'CAR and EQCAR(expr,'REVERSE) => + ["CAR",["LAST",:CDR expr]] + -- cons('last,CDR expr) + funs := '(CAR CDR CAAR CDAR CADR CDDR CAAAR CADAR CAADR CADDR + CDAAR CDDAR CDADR CDDDR) + p := bfPosition(CAR expr,funs) + p = -1 => [acc,expr] + funsA := '(CAAR CADR CAAAR CADAR CAADR CADDR CAAAAR CAADAR CAAADR + CAADDR CADAAR CADDAR CADADR CADDDR) + funsR := '(CDAR CDDR CDAAR CDDAR CDADR CDDDR CDAAAR CDADAR CDAADR + CDADDR CDDAAR CDDDAR CDDADR CDDDDR) + if acc = 'CAR then CONS(funsA.p,CDR expr) + else CONS(funsR.p,CDR expr) + +bfPosition(x,l) == bfPosn(x,l,0) +bfPosn(x,l,n) == + null l => -1 + x=first l => n + bfPosn(x,rest l,n+1) + +--% IS + +bfISApplication(op,left,right)== + EQ(op ,"IS") => bfIS(left,right) + EQ(op ,"ISNT") => bfNOT bfIS(left,right) + [op ,left,right] + +bfIS(left,right)== + $isGenVarCounter:local :=1 + $inDefIS :local :=true + bfIS1(left,right) + +bfISReverse(x,a) == + x is ['CONS,:.] => + NULL CADDR x => ['CONS,CADR x, a] + y := bfISReverse(CADDR x, NIL) + RPLACA(CDDR y,['CONS,CADR x,a]) + y + bpSpecificErrorHere '"Error in bfISReverse" + bpTrap() + +bfIS1(lhs,rhs) == + NULL rhs => + ['NULL,lhs] + STRINGP rhs => + ['EQ,lhs,['QUOTE,INTERN rhs]] + NUMBERP rhs => + ["EQUAL",lhs,rhs] + ATOM rhs => + ['PROGN,bfLetForm(rhs,lhs),''T] + rhs is ['QUOTE,a] => + IDENTP a => ['EQ,lhs,rhs] + ["EQUAL",lhs,rhs] + rhs is ['L%T,c,d] => + l := + bfLET(c,lhs) +-- $inbfLet => bfLET1(c,lhs) +-- bfLET(c,lhs) + bfAND [bfIS1(lhs,d),bfMKPROGN [l,''T]] + rhs is ["EQUAL",a] => + ["EQUAL",lhs,a] + CONSP lhs => + g := INTERN CONCAT('"ISTMP#",STRINGIMAGE $isGenVarCounter) + $isGenVarCounter := $isGenVarCounter + 1 + bfMKPROGN [['L%T,g,lhs],bfIS1(g,rhs)] + rhs is ['CONS,a,b] => + a = "DOT" => + NULL b => + bfAND [['CONSP,lhs], + ['EQ,['CDR,lhs],'NIL]] + bfAND [['CONSP,lhs], + bfIS1(['CDR,lhs],b)] + NULL b => + bfAND [['CONSP,lhs], + ['EQ,['CDR,lhs],'NIL],_ + bfIS1(['CAR,lhs],a)] + b = "DOT" => + bfAND [['CONSP,lhs],bfIS1(['CAR,lhs],a)] + a1 := bfIS1(['CAR,lhs],a) + b1 := bfIS1(['CDR,lhs],b) + a1 is ['PROGN,c,''T] and b1 is ['PROGN,:cls] => + bfAND [['CONSP,lhs],bfMKPROGN [c,:cls]] + bfAND [['CONSP,lhs],a1,b1] + rhs is ['APPEND,a,b] => + patrev := bfISReverse(b,a) + g := INTERN CONCAT('"ISTMP#",STRINGIMAGE $isGenVarCounter) + $isGenVarCounter := $isGenVarCounter + 1 + rev := bfAND [['CONSP,lhs],['PROGN,['L%T,g,['REVERSE,lhs]],''T]] + l2 := bfIS1(g,patrev) + if CONSP l2 and ATOM CAR l2 then l2 := cons(l2,nil) + a = "DOT" => bfAND [rev,:l2] + bfAND [rev,:l2,['PROGN,bfLetForm(a,['NREVERSE,a]),''T]] + bpSpecificErrorHere '"bad IS code is generated" + bpTrap() + +bfApplication(bfop, bfarg) == + if bfTupleP bfarg + then cons(bfop,CDR bfarg) + else cons(bfop,[bfarg]) + + +++ Token renaming. New Boot and Old Boot differs in the set of +++ tokens they rename. When converting code written in Old Boot +++ to New Boot, it is helpful to have some noise about potential +++ divergence in semantics. So, when compiling with --boot=old, +++ we compute the renaming in both Old Boot and New Boot and compare +++ the results. If they differ, we prefer the old meaning, with some +++ warnings. Notice that the task is compounded by the fact the +++ tokens in both language do not always agreee. +++ However, to minimize the flood of false positive, we +++ keep a list of symbols which apparently differ in meanings, but +++ which have been verified to agree. +++ This is a valuable automated tool during the transition period. + +-- return the meaning of the x in Old Boot. +bfGetOldBootName x == + a := GET(x, "OLD-BOOT") => car a + x + +-- returns true if x has same meaning in both Old Boot and New Boot. +bfSameMeaning x == + GET(x, 'RENAME_-OK) + +-- returns the meaning of x in the appropriate Boot dialect. +bfReName x== + newName := + a := GET(x,"SHOERENAME") => car a + x + $translatingOldBoot and not bfSameMeaning x => + oldName := bfGetOldBootName x + if newName ^= oldName then + warn [PNAME x, '" as `", PNAME newName, _ + '"_' differs from Old Boot `", PNAME oldName, '"_'"] + oldName + newName + + +bfInfApplication(op,left,right)== + EQ(op,"EQUAL") => bfQ(left,right) + EQ(op,"/=") => bfNOT bfQ(left,right) + EQ(op,">") => bfLessp(right,left) + EQ(op,"<") => bfLessp(left,right) + EQ(op,"<=") => bfNOT bfLessp(right,left) + EQ(op,">=") => bfNOT bfLessp(left,right) + EQ(op,"OR") => bfOR [left,right] + EQ(op,"AND") => bfAND [left,right] + [op,left,right] + +bfNOT x== + x is ["NOT",a]=> a + x is ["NULL",a]=> a + ["NOT",x] + +bfFlatten(op, x) == + EQCAR(x,op) => CDR x + [x] + +bfOR l == + null l => NIL + null cdr l => CAR l + ["OR",:[:bfFlatten("OR",c) for c in l]] + +bfAND l == + null l=> 'T + null cdr l => CAR l + ["AND",:[:bfFlatten("AND",c) for c in l]] + + +defQuoteId x== EQCAR(x,"QUOTE") and IDENTP CADR x + +bfSmintable x== + INTEGERP x or CONSP x and + MEMQ(CAR x, '(SIZE LENGTH)) + +bfQ(l,r)== + if bfSmintable l or bfSmintable r + then ["EQL",l,r] + else if defQuoteId l or defQuoteId r + then ["EQ",l,r] + else + if null l + then ["NULL",r] + else if null r + then ["NULL",l] + else ["EQUAL",l,r] + +bfLessp(l,r)== + if r=0 + then ["MINUSP", l] + else ["<",l,r] + +bfMDef (defOp,op,args,body) == + argl:=if bfTupleP args then cdr args else [args] + [gargl,sgargl,nargl,largl]:=bfGargl argl + sb:=[cons(i,j) for i in nargl for j in sgargl] + body:= SUBLIS(sb,body) + sb2 := [["CONS",["QUOTE",i],j] for i in sgargl for j in largl] + body := ["SUBLIS",["LIST",:sb2],["QUOTE",body]] + lamex:= ["MLAMBDA",gargl,body] + def:= [op,lamex] + bfTuple + cons(shoeComp def,[:shoeComps bfDef1 d for d in $wheredefs]) + +bfGargl argl== + if null argl + then [[],[],[],[]] + else + [a,b,c,d]:=bfGargl cdr argl + if car argl="&REST" + then [cons(car argl,b),b,c, + cons(["CONS",["QUOTE","LIST"],car d],cdr d)] + else + f:=bfGenSymbol() + [cons(f,a),cons(f,b),cons(car argl,c),cons(f,d)] + +bfDef1 [defOp,op,args,body] == + argl:=if bfTupleP args then cdr args else [args] + [quotes,control,arglp,body]:=bfInsertLet (argl,body) + quotes=>shoeLAM(op,arglp,control,body) + [[op,["LAMBDA",arglp,body]]] + +shoeLAM (op,args,control,body)== + margs :=bfGenSymbol() + innerfunc:=INTERN(CONCAT(PNAME op,",LAM")) + [[innerfunc,["LAMBDA",args,body]], + [op,["MLAMBDA",["&REST",margs],["CONS",["QUOTE", innerfunc], + ["WRAP",margs, ["QUOTE", control]]]]]] + +bfDef(defOp,op,args,body) == + $bfClamming => + [.,op1,arg1,:body1]:=shoeComp first bfDef1 [defOp,op,args,body] + bfCompHash(op1,arg1,body1) + bfTuple + [:shoeComps bfDef1 d for d in cons([defOp,op,args,body],$wheredefs)] + +shoeComps x==[shoeComp def for def in x] +shoeComp x== + a:=shoeCompTran CADR x + if EQCAR(a,"LAMBDA") + then ["DEFUN",CAR x,CADR a,:CDDR a] + else ["DEFMACRO",CAR x,CADR a,:CDDR a] + +bfInsertLet(x,body)== + if null x + then [false,nil,x,body] + else + if x is ["&REST",a] + then if a is ["QUOTE",b] + then [true,"QUOTE",["&REST",b],body] + else [false,nil,x,body] + else + [b,norq,name1,body1]:= bfInsertLet1 (car x,body) + [b1,norq1,name2,body2]:= bfInsertLet (cdr x,body1) + [b or b1,cons(norq,norq1),cons(name1,name2),body2] + +bfInsertLet1(y,body)== + if y is ["L%T",l,r] + then [false,nil,l,bfMKPROGN [bfLET(r,l),body]] + else if IDENTP y + then [false,nil,y,body] + else + if y is ["BVQUOTE",b] + then [true,"QUOTE",b,body] + else + g:=bfGenSymbol() + ATOM y => [false,nil,g,body] + [false,nil,g,bfMKPROGN [bfLET(compFluidize y,g),body]] + +shoeCompTran x== + lamtype:=CAR x + args :=CADR x + body :=CDDR x + $fluidVars:local:=nil + $locVars:local:=nil + $dollarVars:local:=nil + shoeCompTran1 body + $locVars:=SETDIFFERENCE(SETDIFFERENCE($locVars, + $fluidVars),shoeATOMs args) + body:= + if $fluidVars or $locVars or $dollarVars or $typings + then + lvars:=append($fluidVars,$locVars) + $fluidVars:=UNION($fluidVars,$dollarVars) + if null $fluidVars + then + null $typings=> shoePROG(lvars,body) + shoePROG(lvars,[["DECLARE",:$typings],:body]) + else + fvars:=["DECLARE",["SPECIAL",:$fluidVars]] + null $typings => shoePROG(lvars,[fvars,:body]) + shoePROG(lvars,[fvars,["DECLARE",:$typings],:body]) + else shoePROG([], body) + fl:=shoeFluids args + body:=if fl + then + fvs:=["DECLARE",["SPECIAL",:fl]] + cons(fvs,body) + else body + [lamtype,args, :body] + +shoePROG(v,b)== + null b => [["PROG", v]] + [:blist,blast] := b + [["PROG",v,:blist,["RETURN", blast]]] + +shoeFluids x== + if null x + then nil + else if IDENTP x and bfBeginsDollar x + then [x] + else + if EQCAR(x,"QUOTE") + then [] + else + if ATOM x + then nil + else append(shoeFluids car x,shoeFluids cdr x) +shoeATOMs x== + if null x + then nil + else if ATOM x + then [x] + else append(shoeATOMs car x,shoeATOMs cdr x) + +shoeCompTran1 x== + ATOM x=> + IDENTP x and bfBeginsDollar x=> + $dollarVars:= + MEMQ(x,$dollarVars)=>$dollarVars + cons(x,$dollarVars) + nil + U:=car x + EQ(U,"QUOTE")=>nil + x is ["L%T",l,r]=> + RPLACA (x,"SETQ") + shoeCompTran1 r + IDENTP l => + not bfBeginsDollar l=> + $locVars:= + MEMQ(l,$locVars)=>$locVars + cons(l,$locVars) + $dollarVars:= + MEMQ(l,$dollarVars)=>$dollarVars + cons(l,$dollarVars) + EQCAR(l,"FLUID")=> + $fluidVars:= + MEMQ(CADR l,$fluidVars)=>$fluidVars + cons(CADR l,$fluidVars) + RPLACA (CDR x,CADR l) + MEMQ(U,'(PROG LAMBDA))=> + newbindings:=nil + for y in CADR x repeat + not MEMQ(y,$locVars)=> + $locVars:=cons(y,$locVars) + newbindings:=cons(y,newbindings) + res:=shoeCompTran1 CDDR x + $locVars:=[y for y in $locVars | not MEMQ(y,newbindings)] + shoeCompTran1 car x + shoeCompTran1 cdr x + +bfTagged(a,b)== + IDENTP a => + EQ(b,"FLUID") => bfLET(compFluid a,NIL) + EQ(b,"fluid") => bfLET(compFluid a,NIL) + EQ(b,"local") => bfLET(compFluid a,NIL) + $typings:=cons(["TYPE",b,a],$typings) + a + ["THE",b,a] + +bfAssign(l,r)== + if bfTupleP l then bfSetelt(CADR l,CDDR l ,r) else bfLET(l,r) + +bfSetelt(e,l,r)== + if null cdr l + then defSETELT(e,car l,r) + else bfSetelt(bfElt(e,car l),cdr l,r) + +bfElt(expr,sel)== + y:=SYMBOLP sel and GET(sel,"SHOESELFUNCTION") + y=> + INTEGERP y => ["ELT",expr,y] + [y,expr] + ["ELT",expr,sel] + +defSETELT(var,sel,expr)== + y:=SYMBOLP sel and GET(sel,"SHOESELFUNCTION") + y=> + INTEGERP y => ["SETF",["ELT",var,y],expr] + ["SETF",[y,var],expr] + ["SETF",["ELT",var,sel],expr] + +bfIfThenOnly(a,b)== + b1:=if EQCAR (b,"PROGN") then CDR b else [b] + ["COND",[a,:b1]] + +bfIf(a,b,c)== + b1:=if EQCAR (b,"PROGN") then CDR b else [b] + EQCAR (c,"COND") => ["COND",[a,:b1],:CDR c] + c1:=if EQCAR (c,"PROGN") then CDR c else [c] + ["COND",[a,:b1],['(QUOTE T),:c1]] + +bfExit(a,b)== ["COND",[a,["IDENTITY",b]]] + +bfMKPROGN l== + a:=[:bfFlattenSeq c for c in tails l] + null a=> nil + null CDR a=> CAR a + ["PROGN",:a] + +bfFlattenSeq x == + null x=>NIL + f:=CAR x + ATOM f =>if CDR x then nil else [f] + EQCAR(f,"PROGN") => + CDR x=> [i for i in CDR f| not ATOM i] + CDR f + [f] + +bfSequence l == + null l=> NIL + transform:= [[a,b] for x in l while + x is ["COND",[a,["IDENTITY",b]]]] + no:=#transform + before:= bfTake(no,l) + aft := bfDrop(no,l) + null before => + null rest l => + f:=first l + if EQCAR(f,"PROGN") + then bfSequence CDR f + else f + bfMKPROGN [first l,bfSequence rest l] + null aft => ["COND",:transform] + ["COND",:transform,['(QUOTE T),bfSequence aft]] + +bfWhere (context,expr)== + [opassoc,defs,nondefs] := defSheepAndGoats context + a:=[[def,op,args,bfSUBLIS(opassoc,body)] + for d in defs |d is [def,op,args,body]] + $wheredefs:=append(a,$wheredefs) + bfMKPROGN bfSUBLIS(opassoc,NCONC(nondefs,[expr])) + +--shoeReadLispString(s,n)== +-- n>= # s => nil +-- [exp,ind]:=shoeReadLisp(s,n) +-- null exp => nil +-- cons(exp,shoeReadLispString(s,ind)) + +bfReadLisp string==bfTuple shoeReadLispString (string,0) + +bfCompHash(op,argl,body) == + auxfn:= INTERN CONCAT (PNAME op,'";") + computeFunction:= ["DEFUN",auxfn,argl,:body] + bfTuple [computeFunction,:bfMain(auxfn,op)] + +shoeCompileTimeEvaluation x == + ["EVAL-WHEN", [KEYWORD::COMPILE_-TOPLEVEL], x] + +shoeEVALANDFILEACTQ x== + ["EVAL-WHEN", [KEYWORD::EXECUTE, KEYWORD::LOAD_-TOPLEVEL], x] + +bfMain(auxfn,op)== + g1:= bfGenSymbol() + arg:=["&REST",g1] + computeValue := ['APPLY,["FUNCTION",auxfn],g1] + cacheName:= INTERN CONCAT (PNAME op,'";AL") + g2:= bfGenSymbol() + getCode:= ['GETHASH,g1,cacheName] + secondPredPair:= [['SETQ,g2,getCode],g2] + putCode:= ['SETF ,getCode,computeValue] + thirdPredPair:= ['(QUOTE T),putCode] + codeBody:= ['PROG,[g2], + ['RETURN,['COND,secondPredPair,thirdPredPair]]] + mainFunction:= ["DEFUN",op,arg,codeBody] + + cacheType:= 'hash_-table + cacheResetCode:= ['SETQ,cacheName,['MAKE_-HASHTABLE, + ["QUOTE","UEQUAL"]]] + cacheCountCode:= ['hashCount,cacheName] + cacheVector:= + [op,cacheName,cacheType,cacheResetCode,cacheCountCode] + [mainFunction, + shoeEVALANDFILEACTQ + ["SETF",["GET", + ["QUOTE", op],["QUOTE",'cacheInfo]],["QUOTE", cacheVector]], + shoeEVALANDFILEACTQ cacheResetCode ] + +bfNameOnly x== + if x="t" + then ["T"] + else [x] + +bfNameArgs (x,y)== + y:=if EQCAR(y,"TUPLE") then CDR y else [y] + cons(x,y) + +bfStruct(name,arglist)== + bfTuple [bfCreateDef i for i in arglist] + +bfCreateDef x== + if null cdr x + then + f:=car x + ["SETQ",f,["LIST",["QUOTE",f]]] + else + a:=[bfGenSymbol() for i in cdr x] + ["DEFUN",car x,a,["CONS",["QUOTE",car x],["LIST",:a]]] + +bfCaseItem(x,y)==[x,y] + +bfCase(x,y)== + g:=bfGenSymbol() + g1:=bfGenSymbol() + a:=bfLET(g,x) + b:=bfLET(g1,["CDR",g]) + c:=bfCaseItems (g1,y) + bfMKPROGN [a,b,["CASE",["CAR", g],:c]] + +bfCaseItems(g,x)== [bfCI(g,i,j) for [i,j] in x] + +bfCI(g,x,y)== + a:=cdr x + if null a + then [car x,y] + else + b:=[[i,bfCARCDR(j,g)] for i in a for j in 0..] + [car x,["LET",b,y]] + +bfCARCDR (n,g)==[INTERN CONCAT ('"CA",bfDs n,'"R"),g] + +bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) + diff --git a/src/boot/includer.boot b/src/boot/includer.boot new file mode 100644 index 00000000..2f81c55a --- /dev/null +++ b/src/boot/includer.boot @@ -0,0 +1,390 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- All rights reserved. +-- Copyright (C) 2007-2008, Gabriel Dos Reis. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + +-- +-- Abstract: +-- This file defines the includer (or preprocessor) of Boot programs. +-- + +module '"boot-includer" +import '"tokens" + +)package "BOOTTRAN" +-- BOOT INCLUDER + +-- Line syntax is +-- +-- Include ::= (SimpleLine | If )* | ( )fin | empty) +-- +-- SimpleLine::= +-- PlainLine | includes the line +-- )say line | outputs line to console +-- )eval line | evaluates the boot line +-- nothing included +-- )line line | line is reproduced as is in lisp output +-- )lisp line | line is read by lisp READ +-- )package line | produces (IN-PACKAGE line) in lisp +-- output +-- )include filename | includes the file as boot code +-- )includelisp filename | includes the file as lisp code +-- read by lisp READ +-- )includelines filename | includes the file as is +-- in lisp output +-- +-- If ::= )if SimpleLine* ElseLines )endif +-- +-- ElseLines ::= )else SimpleLine* | )elseif SimpleLine* ElseLines | empty + +-- returns a printable representation of X, when it is a symbol +-- or a character, as string. Otherwise, returns nil. +PNAME x == + SYMBOLP x => SYMBOL_-NAME x + CHARACTERP x => STRING x + nil + +-- converts X, a 1-length string, to a character. +char x == + CHAR(PNAME x, 0) + +EQCAR(x,y)== CONSP x and EQ(CAR x,y) + +-- returns the string representation of object X. +STRINGIMAGE x == + WRITE_-TO_-STRING x + +-- close STREAM. +shoeCLOSE stream == + CLOSE stream + +-- error out if file is not found. +shoeNotFound fn == + coreError [fn, '" not found"] + nil + + +shoeReadLispString(s,n) == + l:=# s + n >= l => nil + READ_-FROM_-STRING CONCAT ( "(", SUBSTRING(s,n,l-n) ,")") + +-- read a line from stream +shoeReadLine stream == + READ_-LINE(stream, nil, nil) + +-- write LINE to standard terminal I/O. +shoeConsole line == + WRITE_-LINE(line, _*TERMINAL_-IO_*) + +shoeSpaces n == MAKE_-FULL_-CVEC(n, '".") + +SoftShoeError(posn,key)== + coreError ['"in line ", STRINGIMAGE lineNo posn] + shoeConsole lineString posn + shoeConsole CONCAT(shoeSpaces lineCharacter posn,'"|") + shoeConsole key + +bpSpecificErrorAtToken(tok, key) == + a:=shoeTokPosn tok + SoftShoeError(a,key) + +bpSpecificErrorHere(key) == bpSpecificErrorAtToken($stok, key) + +bpGeneralErrorHere() == bpSpecificErrorHere('"syntax error") + +bpIgnoredFromTo(pos1, pos2) == + shoeConsole CONCAT('"ignored from line ", STRINGIMAGE lineNo pos1) + shoeConsole lineString pos1 + shoeConsole CONCAT(shoeSpaces lineCharacter pos1,'"|") + shoeConsole CONCAT('"ignored through line ", STRINGIMAGE lineNo pos2) + shoeConsole lineString pos2 + shoeConsole CONCAT(shoeSpaces lineCharacter pos2,'"|") + +-- Line inclusion support. + +lineNo p==CDAAR p +lineString p==CAAAR p +lineCharacter p==CDR p + +shoePackageStartsAt (lines,sz,name,stream)== + bStreamNull stream => [[],['nullstream]] + a:=CAAR stream + if #a >= 8 and SUBSTRING(a,0,8)='")package" + then shoePackageStartsAt(cons(CAAR stream,lines),sz,name,CDR stream) + else + if #a<sz + then shoePackageStartsAt(lines, sz,name,CDR stream) + else if SUBSTRING(a,0,sz)=name and (#a>sz and not shoeIdChar(a.sz)) + then [lines,stream] + else shoePackageStartsAt(lines,sz,name,CDR stream) + +shoeFindLines(fn,name,a)== + if null a + then + shoeNotFound fn + [] + else + [lines,b]:=shoePackageStartsAt([],#name,name, shoeInclude + bAddLineNumber(bRgen a,bIgen 0)) + b:=shoeTransform2 b + if bStreamNull b + then + shoeConsole CONCAT (name,'" not found in ",fn) + [] + else + if null lines + then shoeConsole '")package not found" + append(reverse lines,car b) + +-- Lazy inclusion support. + +$bStreamNil:=["nullstream"] + +bStreamNull x== + null x or EQCAR (x,"nullstream") => true + while EQCAR(x,"nonnullstream") repeat + st:=APPLY(CADR x,CDDR x) + RPLACA(x,CAR st) + RPLACD(x,CDR st) + EQCAR(x,"nullstream") + +bMap(f,x)==bDelay(function bMap1, [f,x]) + +bMap1(:z)== + [f,x]:=z + if bStreamNull x + then $bStreamNil + else cons(FUNCALL(f,car x),bMap(f,cdr x)) + +shoeFileMap(f, fn)== + a:=shoeInputFile fn + null a => + shoeConsole CONCAT(fn,'" NOT FOUND") + $bStreamNil + shoeConsole CONCAT('"READING ",fn) + shoeInclude bAddLineNumber(bMap(f,bRgen a),bIgen 0) + + +bDelay(f,x)==cons("nonnullstream",[f,:x]) + +bAppend(x,y)==bDelay(function bAppend1,[x,y]) + +bAppend1(:z)== + if bStreamNull car z + then if bStreamNull CADR z + then ["nullstream"] + else CADR z + else cons(CAAR z,bAppend(CDAR z,CADR z)) + +bNext(f,s)==bDelay(function bNext1,[f,s]) + +bNext1(f,s)== + bStreamNull s=> ["nullstream"] + h:= APPLY(f, [s]) + bAppend(car h,bNext(f,cdr h)) + +bRgen s==bDelay(function bRgen1,[s]) + +bRgen1(:s) == + a:=shoeReadLine car s + if shoePLACEP a + then +-- shoeCLOSE car s + ["nullstream"] + else cons(a,bRgen car s) + +bIgen n==bDelay(function bIgen1,[n]) + +bIgen1(:n)== + n:=car n+1 + cons(n,bIgen n) + +bAddLineNumber(f1,f2)==bDelay(function bAddLineNumber1,[f1,f2]) + +bAddLineNumber1(:f)== + [f1,f2] := f + bStreamNull f1 => ["nullstream"] + bStreamNull f2 => ["nullstream"] + cons(cons(CAR f1,CAR f2),bAddLineNumber(CDR f1,CDR f2)) + + + +shoeFileInput fn==shoeFileMap(function IDENTITY,fn) + +shoePrefixLisp x== CONCAT('")lisp",x) +shoeLispFileInput fn== shoeFileMap(function shoePrefixLisp,fn) + +shoePrefixLine x== CONCAT('")line",x) +shoeLineFileInput fn== shoeFileMap(function shoePrefixLine,fn) + +shoePrefix?(prefix,whole) == + #prefix > #whole => false + good:=true + for i in 0..#prefix-1 for j in 0.. while good repeat + good:= prefix.i = whole.j + if good then SUBSTRING(whole,#prefix,nil) else good + +shoePlainLine?(s) == + #s = 0 => true + s.0 ^= char ")" + +shoeSay? s == shoePrefix?('")say", s) +shoeEval? s == shoePrefix?('")eval", s) +shoeInclude? s == shoePrefix?('")include", s) +shoeFin? s == shoePrefix?('")fin", s) +shoeIf? s == shoePrefix?('")if", s) +shoeEndIf? s == shoePrefix?('")endif", s) +shoeElse? s == shoePrefix?('")else", s) +shoeElseIf? s == shoePrefix?('")elseif", s) +shoePackage? s == shoePrefix?('")package", s) +shoeLisp? s == shoePrefix?('")lisp", s) +shoeIncludeLisp? s == shoePrefix?('")includelisp" ,s) +shoeLine? s == shoePrefix?('")line", s) +shoeIncludeLines? s == shoePrefix?('")includelines",s) +shoeIncludeFunction? s == shoePrefix?('")includefunction",s) + +shoeBiteOff x== + n:=STRPOSL('" ",x,0,true) + null n => false + n1:=STRPOSL ('" ",x,n,nil) + null n1 => [SUBSTRING(x,n,nil),'""] + [SUBSTRING(x,n,n1-n),SUBSTRING(x,n1,nil)] + +shoeFileName x== + a:=shoeBiteOff x + null a => '"" + c:=shoeBiteOff CADR a + null c => CAR a + CONCAT(CAR a,'".",CAR c) + +shoeFnFileName x== + a:=shoeBiteOff x + null a => ['"",'""] + c:=shoeFileName CADR a + null c => [CAR a,'""] + [CAR a, c] + +shoeFunctionFileInput [fun,fn]== + shoeOpenInputFile (a,fn, + shoeInclude bAddLineNumber( shoeFindLines(fn,fun,a),bIgen 0)) + +shoeInclude s== bDelay(function shoeInclude1,[s]) +shoeInclude1 s== + bStreamNull s=> s + [h,:t] :=s + string :=CAR h + command :=shoeFin? string => $bStreamNil + command :=shoeIf? string => shoeThen([true],[STTOMC command],t) + bAppend(shoeSimpleLine h,shoeInclude t) + +shoeSimpleLine(h) == + string :=CAR h + shoePlainLine? string=> [h] + command:=shoeLisp? string => [h] + command:=shoeIncludeLisp? string => + shoeLispFileInput shoeFileName command + command:=shoeIncludeFunction? string => + shoeFunctionFileInput shoeFnFileName command + command:=shoeLine? string => [h] + command:=shoeIncludeLines? string => + shoeLineFileInput shoeFileName command + command:=shoeInclude? string => shoeFileInput shoeFileName command + command:=shoePackage? string => [h] + command:=shoeSay? string => + shoeConsole command + nil + command:=shoeEval? string => + STTOMC command + nil + shoeLineSyntaxError(h) + nil + +shoeThen(keep,b,s)== bDelay(function shoeThen1,[keep,b,s]) +shoeThen1(keep,b,s)== + bPremStreamNull s=> s + [h,:t] :=s + string :=CAR h + command :=shoeFin? string => bPremStreamNil(h) + keep1:= car keep + b1 := car b + command :=shoeIf? string => + keep1 and b1=> shoeThen(cons(true,keep),cons(STTOMC command,b),t) + shoeThen(cons(false,keep),cons(false,b),t) + command :=shoeElseIf? string=> + keep1 and not b1=> + shoeThen(cons(true,rest keep),cons(STTOMC command,rest b),t) + shoeThen(cons(false,rest keep),cons(false,rest b),t) + command :=shoeElse? string => + keep1 and not b1=>shoeElse(cons(true,rest keep),cons(true,rest b),t) + shoeElse(cons(false,rest keep),cons(false,rest b),t) + command :=shoeEndIf? string=> + null cdr b=> shoeInclude t + shoeThen(rest keep,rest b,t) + keep1 and b1 => bAppend(shoeSimpleLine h,shoeThen(keep,b,t)) + shoeThen(keep,b,t) + +shoeElse(keep,b,s)== bDelay(function shoeElse1,[keep,b,s]) +shoeElse1(keep,b,s)== + bPremStreamNull s=> s + [h,:t] :=s + string :=CAR h + command :=shoeFin? string => bPremStreamNil(h) + b1:=car b + keep1:=car keep + command :=shoeIf? string=> + keep1 and b1=> shoeThen(cons(true,keep),cons(STTOMC command,b),t) + shoeThen(cons(false,keep),cons(false,b),t) + command :=shoeEndIf? string => + null cdr b=> shoeInclude t + shoeThen(rest keep,rest b,t) + keep1 and b1 => bAppend(shoeSimpleLine h,shoeElse(keep,b,t)) + shoeElse(keep,b,t) + +shoeLineSyntaxError(h)== + shoeConsole CONCAT('"INCLUSION SYNTAX ERROR IN LINE ", + STRINGIMAGE CDR h) + shoeConsole car h + shoeConsole '"LINE IGNORED" + +bPremStreamNil(h)== + shoeConsole CONCAT('"UNEXPECTED )fin IN LINE ",STRINGIMAGE CDR h) + shoeConsole car h + shoeConsole '"REST OF FILE IGNORED" + $bStreamNil + +bPremStreamNull(s)== + if bStreamNull s + then + shoeConsole '"FILE TERMINATED BEFORE )endif" + true + else false diff --git a/src/boot/includer.boot.pamphlet b/src/boot/includer.boot.pamphlet deleted file mode 100644 index 9775aeb1..00000000 --- a/src/boot/includer.boot.pamphlet +++ /dev/null @@ -1,1226 +0,0 @@ -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/includer.boot} Pamphlet} -\author{The Axiom Team} - -\begin{document} -\maketitle - -\begin{abstract} -\end{abstract} - -\eject -\tableofcontents -\eject - -\section{License} - -<<license>>= --- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are --- met: --- --- - Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- - Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in --- the documentation and/or other materials provided with the --- distribution. --- --- - Neither the name of The Numerical ALgorithms Group Ltd. nor the --- names of its contributors may be used to endorse or promote products --- derived from this software without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -@ - -\section{Call graphs} - -The followng sections give summarize symbols referenced by each -function defined in this pamphlet. - -\subsection{[[shoeFileMap]]} -\begin{itemize} -\item \Code{shoeInputFile} --- \File{initial-env.lisp} -\item \Code{\$bStreamNil} --- this file -\item \Code{shoeConsole} --- \File{initial-env.lisp} -\item \Code{CONCAT} --- \File{initial-env.lisp} -\item \Code{shoeInclude} --- this file -\item \Code{bAddLineNumber} --- \File{ptyout.boot} -\item \Code{bMap} --- \File{pytout.boot} -\item \Code{bRgen} --- \File{pytout.boot} -\item \Code{bIgen} --- \File{pytout.boot} -\end{itemize} - -\subsection{[[shoeFileInput]]} -\begin{itemize} -\item \Code{shoeFileMap} --- this file -\end{itemize} - -\subsection{[[shoePrefixLisp]]} -\begin{itemize} -\item \Code{CONCAT} --- \File{npextras.lisp} -\end{itemize} - -\subsection{[[shoeLispFileInput]]} -\begin{itemize} -\item \Code{shoeFileMap} --- this file -\item \Code{shoePrefixLisp} --- this file -\end{itemize} - -\subsection{[[shoePrefixLine]]} -\begin{itemize} -\item \Code{CONCAT} --- \File{initial-env.lisp} -\end{itemize} - -\subsection{[[shoeLineFileInput]]} -\begin{itemize} -\item \Code{shoeFileMap} -- this file -\item \Code{shoePrefixLine} -- this file -\end{itemize} - - -\subsection{[[shoePrefix?]]} -\begin{itemize} -\item \Code{SUBSTRING} --- \File{initial-env.lisp} -\end{itemize} - -\subsection{[[shoePlainLine?]]} -\begin{itemize} -\item \Code{char} -\end{itemize} - -\subsection{[[shoeSay?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeEval?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeInclude?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeFin?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeIf?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeEndIf?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeElse?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeElseIf?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoePackage?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeLisp?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeIncludeLisp?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeLine?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeIncludeLines?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeIncludeFunction?]]} -\begin{itemize} -\item \Code{shoePrefix?} -\end{itemize} - -\subsection{[[shoeBiteOff]]} -\begin{itemize} -\item \Code{STRPOSL} --- \File{initial-env.lisp} -\item \Code{SUBSTRING} --- \File{initial-env.lisp} -\end{itemize} - -\subsection{[[shoeFileName]]} -\begin{itemize} -\item \Code{shoeBiteOff} --- this file -\item \Code{CONCAT} --- \File{initial-env.lisp} -\end{itemize} - -\subsection{[[shoeFnFileName]]} -\begin{itemize} -\item \Code{shoeBiteOff} --- this file -\item \Code{CONCAT} --- \File{initial-env.lisp} -\end{itemize} - -\subsection{[[shoeFunctionFileInput]]} -\begin{itemize} -\item \Code{shoeOpenInputFile} --- \File{initial-env.lisp} -\item \Code{shoeInclude} --- this file -\item \Code{bAddLineNumber} --- \File{ptyout.boot} -\item \Code{shoeFindLines} --- \File{ptyout.boot} -\item \Code{bIgen} --- \File{ptyout.boot} -\end{itemize} - -\subsection{[[shoeInclude]]} -\begin{itemize} -\item \Code{bDelay} --- \File{ptyout.boot} -\item \Code{shoeInclude1} --- this file -\end{itemize} - -\subsection{[[shoeInclude1]]} -\begin{itemize} -\item \Code{bStreamNull} --- \File{ptyout.boot} -\item \Code{shoeFin?} --- this file -\item \Code{\$bStreamNil} --- tis file -\item \Code{shoeIf?} --- this file -\item \Code{shoeThen} --- this file -\item \Code{STTOMC} --- this file -\item \Code{bAppend} --- \File{ptyout.boot} -\item \Code{shoeSimpleLine} --- this file -\item \Code{shoeInclude} --- this file -\end{itemize} - -\subsection{[[shoeSimpleLine]]} -\begin{itemize} -\item \Code{shoePlainLine?} --- this file -\item \Code{shoeLisp?} --- this file -\item \Code{shoeIncludeLisp?} --- this file -\item \Code{shoeLispFileInput} --- this file -\item \Code{shoeFileName} --- this file -\item \Code{shoeIncludeFunction?} --- this file -\item \Code{shoeFunctionFileInput} --- this file -\item \Code{shoeFnFileName} --- this file -\item \Code{shoeLine?} --- this file -\item \Code{shoeIncludeLines?} --- this file -\item \Code{shoeInclude?} --- this file -\item \Code{shoeFileInput} --- this file -\item \Code{shoePackage?} --- this file -\item \Code{shoeSay?} --- this file -\item \Code{shoeConsole} --- this file -\item \Code{shoeEval?} --- this file -\item \Code{STTOMC} --- \File{ptyout.boot} -\item \Code{shoeLineSyntaxError} --- this file -\end{itemize} - -\subsection{[[shoeThen]]} -\begin{itemize} -\item \Code{bDelay} --- \File{ptyout.boot} -\item \Code{shoeThen1} --- this file -\end{itemize} - -\subsection{[[shoeThen1]]} -\begin{itemize} -\item \Code{bPremStreamNull} --- this file -\item \Code{shoeFin?} --- this file -\item \Code{bPremStreamNil} --- this file -\item \Code{shoeIf?} --- this file -\item \Code{shoeThen} --- this file -\item \Code{STTOMC} --- \File{ptyout.boot} -\item \Code{shoeThen} --- this file -\item \Code{shoeElseIf?} --- this file -\item \Code{shoeElse?} --- this file -\item \Code{shoeElse} --- this file -\item \Code{shoeEndIf?} --- this file -\item \Code{shoeInclude} --- this file -\item \Code{bAppend} --- \File{ptyout.boot} -\item \Code{shoeSimpleLine} --- this file -\end{itemize} - -\subsection{[[shoeElse]]} -\begin{itemize} -\item \Code{bDelay} --- \File{ptyout.boot} -\item \Code{shoeElse1} --- this file -\item \Code{bPremStreamNull} --- this file -\item \Code{shoeFin?} --- this file -\item \Code{bPremStreamNil} --- this file -\item \Code{shoeIf?} --- this file -\item \Code{shoeThen} --- this file -\item \Code{STTOMC} --- \File{ptyout.boot} -\item \Code{shoeEndIf?} --- this file -\item \Code{bAppend} --- \File{ptyout.boot} -\item \Code{shoeSimpleLine} --- this file -\item \Code{shoeElse} --- this file -\end{itemize} - -\subsection{[[shoeLineSyntaxError]]} -\begin{itemize} -\item \Code{shoeConsole} --- \File{ptyout.boot} -\item \Code{CONCAT} --- \File{initial-env.lisp} -\item \Code{STRINGIMAGE} --- \File{initial-env.lisp} -\end{itemize} - -\subsection{[[bPremStreamNil]]} -\begin{itemize} -\item \Code{shoeConsole} --- \File{initial-env.lisp} -\item \Code{CONCAT} --- \File{initial-env.lisp} -\item \Code{STRINGIMAGE} --- \File{initial-env.lisp} -\item \Code{\$bStreamNil} --- this file -\end{itemize} - -\subsection{[[bPremStreamNull]]} -\begin{itemize} -\item \Code{bStreamNull} --- \File{ptyout.boot} -\item \Code{shoeConsole} --- \File{initial-env.lisp} -\end{itemize} - - -\section{The Boot code} - -<<*>>= -<<license>> - -module '"boot-includer" -import '"tokens" - -)package "BOOTTRAN" --- BOOT INCLUDER - --- Line syntax is --- --- Include ::= (SimpleLine | If )* | ( )fin | empty) --- --- SimpleLine::= --- PlainLine | includes the line --- )say line | outputs line to console --- )eval line | evaluates the boot line --- nothing included --- )line line | line is reproduced as is in lisp output --- )lisp line | line is read by lisp READ --- )package line | produces (IN-PACKAGE line) in lisp --- output --- )include filename | includes the file as boot code --- )includelisp filename | includes the file as lisp code --- read by lisp READ --- )includelines filename | includes the file as is --- in lisp output --- --- If ::= )if SimpleLine* ElseLines )endif --- --- ElseLines ::= )else SimpleLine* | )elseif SimpleLine* ElseLines | empty - --- returns a printable representation of X, when it is a symbol --- or a character, as string. Otherwise, returns nil. -PNAME x == - SYMBOLP x => SYMBOL_-NAME x - CHARACTERP x => STRING x - nil - --- converts X, a 1-length string, to a character. -char x == - CHAR(PNAME x, 0) - -EQCAR(x,y)== CONSP x and EQ(CAR x,y) - --- returns the string representation of object X. -STRINGIMAGE x == - WRITE_-TO_-STRING x - --- close STREAM. -shoeCLOSE stream == - CLOSE stream - --- error out if file is not found. -shoeNotFound fn == - coreError [fn, '" not found"] - nil - - -shoeReadLispString(s,n) == - l:=# s - n >= l => nil - READ_-FROM_-STRING CONCAT ( "(", SUBSTRING(s,n,l-n) ,")") - --- read a line from stream -shoeReadLine stream == - READ_-LINE(stream, nil, nil) - --- write LINE to standard terminal I/O. -shoeConsole line == - WRITE_-LINE(line, _*TERMINAL_-IO_*) - -shoeSpaces n == MAKE_-FULL_-CVEC(n, '".") - -SoftShoeError(posn,key)== - coreError ['"in line ", STRINGIMAGE lineNo posn] - shoeConsole lineString posn - shoeConsole CONCAT(shoeSpaces lineCharacter posn,'"|") - shoeConsole key - -bpSpecificErrorAtToken(tok, key) == - a:=shoeTokPosn tok - SoftShoeError(a,key) - -bpSpecificErrorHere(key) == bpSpecificErrorAtToken($stok, key) - -bpGeneralErrorHere() == bpSpecificErrorHere('"syntax error") - -bpIgnoredFromTo(pos1, pos2) == - shoeConsole CONCAT('"ignored from line ", STRINGIMAGE lineNo pos1) - shoeConsole lineString pos1 - shoeConsole CONCAT(shoeSpaces lineCharacter pos1,'"|") - shoeConsole CONCAT('"ignored through line ", STRINGIMAGE lineNo pos2) - shoeConsole lineString pos2 - shoeConsole CONCAT(shoeSpaces lineCharacter pos2,'"|") - --- Line inclusion support. - -lineNo p==CDAAR p -lineString p==CAAAR p -lineCharacter p==CDR p - -shoePackageStartsAt (lines,sz,name,stream)== - bStreamNull stream => [[],['nullstream]] - a:=CAAR stream - if #a >= 8 and SUBSTRING(a,0,8)='")package" - then shoePackageStartsAt(cons(CAAR stream,lines),sz,name,CDR stream) - else - if #a<sz - then shoePackageStartsAt(lines, sz,name,CDR stream) - else if SUBSTRING(a,0,sz)=name and (#a>sz and not shoeIdChar(a.sz)) - then [lines,stream] - else shoePackageStartsAt(lines,sz,name,CDR stream) - -shoeFindLines(fn,name,a)== - if null a - then - shoeNotFound fn - [] - else - [lines,b]:=shoePackageStartsAt([],#name,name, shoeInclude - bAddLineNumber(bRgen a,bIgen 0)) - b:=shoeTransform2 b - if bStreamNull b - then - shoeConsole CONCAT (name,'" not found in ",fn) - [] - else - if null lines - then shoeConsole '")package not found" - append(reverse lines,car b) - --- Lazy inclusion support. - -$bStreamNil:=["nullstream"] - -bStreamNull x== - null x or EQCAR (x,"nullstream") => true - while EQCAR(x,"nonnullstream") repeat - st:=APPLY(CADR x,CDDR x) - RPLACA(x,CAR st) - RPLACD(x,CDR st) - EQCAR(x,"nullstream") - -bMap(f,x)==bDelay(function bMap1, [f,x]) - -bMap1(:z)== - [f,x]:=z - if bStreamNull x - then $bStreamNil - else cons(FUNCALL(f,car x),bMap(f,cdr x)) - -shoeFileMap(f, fn)== - a:=shoeInputFile fn - null a => - shoeConsole CONCAT(fn,'" NOT FOUND") - $bStreamNil - shoeConsole CONCAT('"READING ",fn) - shoeInclude bAddLineNumber(bMap(f,bRgen a),bIgen 0) - - -bDelay(f,x)==cons("nonnullstream",[f,:x]) - -bAppend(x,y)==bDelay(function bAppend1,[x,y]) - -bAppend1(:z)== - if bStreamNull car z - then if bStreamNull CADR z - then ["nullstream"] - else CADR z - else cons(CAAR z,bAppend(CDAR z,CADR z)) - -bNext(f,s)==bDelay(function bNext1,[f,s]) - -bNext1(f,s)== - bStreamNull s=> ["nullstream"] - h:= APPLY(f, [s]) - bAppend(car h,bNext(f,cdr h)) - -bRgen s==bDelay(function bRgen1,[s]) - -bRgen1(:s) == - a:=shoeReadLine car s - if shoePLACEP a - then --- shoeCLOSE car s - ["nullstream"] - else cons(a,bRgen car s) - -bIgen n==bDelay(function bIgen1,[n]) - -bIgen1(:n)== - n:=car n+1 - cons(n,bIgen n) - -bAddLineNumber(f1,f2)==bDelay(function bAddLineNumber1,[f1,f2]) - -bAddLineNumber1(:f)== - [f1,f2] := f - bStreamNull f1 => ["nullstream"] - bStreamNull f2 => ["nullstream"] - cons(cons(CAR f1,CAR f2),bAddLineNumber(CDR f1,CDR f2)) - - - -shoeFileInput fn==shoeFileMap(function IDENTITY,fn) - -shoePrefixLisp x== CONCAT('")lisp",x) -shoeLispFileInput fn== shoeFileMap(function shoePrefixLisp,fn) - -shoePrefixLine x== CONCAT('")line",x) -shoeLineFileInput fn== shoeFileMap(function shoePrefixLine,fn) - -shoePrefix?(prefix,whole) == - #prefix > #whole => false - good:=true - for i in 0..#prefix-1 for j in 0.. while good repeat - good:= prefix.i = whole.j - if good then SUBSTRING(whole,#prefix,nil) else good - -shoePlainLine?(s) == - #s = 0 => true - s.0 ^= char ")" - -shoeSay? s == shoePrefix?('")say", s) -shoeEval? s == shoePrefix?('")eval", s) -shoeInclude? s == shoePrefix?('")include", s) -shoeFin? s == shoePrefix?('")fin", s) -shoeIf? s == shoePrefix?('")if", s) -shoeEndIf? s == shoePrefix?('")endif", s) -shoeElse? s == shoePrefix?('")else", s) -shoeElseIf? s == shoePrefix?('")elseif", s) -shoePackage? s == shoePrefix?('")package", s) -shoeLisp? s == shoePrefix?('")lisp", s) -shoeIncludeLisp? s == shoePrefix?('")includelisp" ,s) -shoeLine? s == shoePrefix?('")line", s) -shoeIncludeLines? s == shoePrefix?('")includelines",s) -shoeIncludeFunction? s == shoePrefix?('")includefunction",s) - -shoeBiteOff x== - n:=STRPOSL('" ",x,0,true) - null n => false - n1:=STRPOSL ('" ",x,n,nil) - null n1 => [SUBSTRING(x,n,nil),'""] - [SUBSTRING(x,n,n1-n),SUBSTRING(x,n1,nil)] - -shoeFileName x== - a:=shoeBiteOff x - null a => '"" - c:=shoeBiteOff CADR a - null c => CAR a - CONCAT(CAR a,'".",CAR c) - -shoeFnFileName x== - a:=shoeBiteOff x - null a => ['"",'""] - c:=shoeFileName CADR a - null c => [CAR a,'""] - [CAR a, c] - -shoeFunctionFileInput [fun,fn]== - shoeOpenInputFile (a,fn, - shoeInclude bAddLineNumber( shoeFindLines(fn,fun,a),bIgen 0)) - -shoeInclude s== bDelay(function shoeInclude1,[s]) -shoeInclude1 s== - bStreamNull s=> s - [h,:t] :=s - string :=CAR h - command :=shoeFin? string => $bStreamNil - command :=shoeIf? string => shoeThen([true],[STTOMC command],t) - bAppend(shoeSimpleLine h,shoeInclude t) - -shoeSimpleLine(h) == - string :=CAR h - shoePlainLine? string=> [h] - command:=shoeLisp? string => [h] - command:=shoeIncludeLisp? string => - shoeLispFileInput shoeFileName command - command:=shoeIncludeFunction? string => - shoeFunctionFileInput shoeFnFileName command - command:=shoeLine? string => [h] - command:=shoeIncludeLines? string => - shoeLineFileInput shoeFileName command - command:=shoeInclude? string => shoeFileInput shoeFileName command - command:=shoePackage? string => [h] - command:=shoeSay? string => - shoeConsole command - nil - command:=shoeEval? string => - STTOMC command - nil - shoeLineSyntaxError(h) - nil - -shoeThen(keep,b,s)== bDelay(function shoeThen1,[keep,b,s]) -shoeThen1(keep,b,s)== - bPremStreamNull s=> s - [h,:t] :=s - string :=CAR h - command :=shoeFin? string => bPremStreamNil(h) - keep1:= car keep - b1 := car b - command :=shoeIf? string => - keep1 and b1=> shoeThen(cons(true,keep),cons(STTOMC command,b),t) - shoeThen(cons(false,keep),cons(false,b),t) - command :=shoeElseIf? string=> - keep1 and not b1=> - shoeThen(cons(true,rest keep),cons(STTOMC command,rest b),t) - shoeThen(cons(false,rest keep),cons(false,rest b),t) - command :=shoeElse? string => - keep1 and not b1=>shoeElse(cons(true,rest keep),cons(true,rest b),t) - shoeElse(cons(false,rest keep),cons(false,rest b),t) - command :=shoeEndIf? string=> - null cdr b=> shoeInclude t - shoeThen(rest keep,rest b,t) - keep1 and b1 => bAppend(shoeSimpleLine h,shoeThen(keep,b,t)) - shoeThen(keep,b,t) - -shoeElse(keep,b,s)== bDelay(function shoeElse1,[keep,b,s]) -shoeElse1(keep,b,s)== - bPremStreamNull s=> s - [h,:t] :=s - string :=CAR h - command :=shoeFin? string => bPremStreamNil(h) - b1:=car b - keep1:=car keep - command :=shoeIf? string=> - keep1 and b1=> shoeThen(cons(true,keep),cons(STTOMC command,b),t) - shoeThen(cons(false,keep),cons(false,b),t) - command :=shoeEndIf? string => - null cdr b=> shoeInclude t - shoeThen(rest keep,rest b,t) - keep1 and b1 => bAppend(shoeSimpleLine h,shoeElse(keep,b,t)) - shoeElse(keep,b,t) - -shoeLineSyntaxError(h)== - shoeConsole CONCAT('"INCLUSION SYNTAX ERROR IN LINE ", - STRINGIMAGE CDR h) - shoeConsole car h - shoeConsole '"LINE IGNORED" - -bPremStreamNil(h)== - shoeConsole CONCAT('"UNEXPECTED )fin IN LINE ",STRINGIMAGE CDR h) - shoeConsole car h - shoeConsole '"REST OF FILE IGNORED" - $bStreamNil - -bPremStreamNull(s)== - if bStreamNull s - then - shoeConsole '"FILE TERMINATED BEFORE )endif" - true - else false -@ - - -\section{Translated Lisp code} - -<<includer.clisp>>= -(EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-includer")) - -(IMPORT-MODULE "tokens") - -(IN-PACKAGE "BOOTTRAN") - -(DEFUN PNAME (|x|) - (PROG () - (RETURN - (COND - ((SYMBOLP |x|) (SYMBOL-NAME |x|)) - ((CHARACTERP |x|) (STRING |x|)) - ('T NIL))))) - -(DEFUN |char| (|x|) (PROG () (RETURN (CHAR (PNAME |x|) 0)))) - -(DEFUN EQCAR (|x| |y|) - (PROG () (RETURN (AND (CONSP |x|) (EQ (CAR |x|) |y|))))) - -(DEFUN STRINGIMAGE (|x|) (PROG () (RETURN (WRITE-TO-STRING |x|)))) - -(DEFUN |shoeCLOSE| (|stream|) (PROG () (RETURN (CLOSE |stream|)))) - -(DEFUN |shoeNotFound| (|fn|) - (PROG () - (RETURN (PROGN (|coreError| (LIST |fn| " not found")) NIL)))) - -(DEFUN |shoeReadLispString| (|s| |n|) - (PROG (|l|) - (RETURN - (PROGN - (SETQ |l| (LENGTH |s|)) - (COND - ((NOT (< |n| |l|)) NIL) - ('T - (READ-FROM-STRING - (CONCAT '|(| (SUBSTRING |s| |n| (- |l| |n|)) '|)|)))))))) - -(DEFUN |shoeReadLine| (|stream|) - (PROG () (RETURN (READ-LINE |stream| NIL NIL)))) - -(DEFUN |shoeConsole| (|line|) - (PROG () (RETURN (WRITE-LINE |line| *TERMINAL-IO*)))) - -(DEFUN |shoeSpaces| (|n|) (PROG () (RETURN (MAKE-FULL-CVEC |n| ".")))) - -(DEFUN |SoftShoeError| (|posn| |key|) - (PROG () - (RETURN - (PROGN - (|coreError| (LIST "in line " (STRINGIMAGE (|lineNo| |posn|)))) - (|shoeConsole| (|lineString| |posn|)) - (|shoeConsole| - (CONCAT (|shoeSpaces| (|lineCharacter| |posn|)) "|")) - (|shoeConsole| |key|))))) - -(DEFUN |bpSpecificErrorAtToken| (|tok| |key|) - (PROG (|a|) - (RETURN - (PROGN - (SETQ |a| (|shoeTokPosn| |tok|)) - (|SoftShoeError| |a| |key|))))) - -(DEFUN |bpSpecificErrorHere| (|key|) - (PROG () - (DECLARE (SPECIAL |$stok|)) - (RETURN (|bpSpecificErrorAtToken| |$stok| |key|)))) - -(DEFUN |bpGeneralErrorHere| () - (PROG () (RETURN (|bpSpecificErrorHere| "syntax error")))) - -(DEFUN |bpIgnoredFromTo| (|pos1| |pos2|) - (PROG () - (RETURN - (PROGN - (|shoeConsole| - (CONCAT "ignored from line " - (STRINGIMAGE (|lineNo| |pos1|)))) - (|shoeConsole| (|lineString| |pos1|)) - (|shoeConsole| - (CONCAT (|shoeSpaces| (|lineCharacter| |pos1|)) "|")) - (|shoeConsole| - (CONCAT "ignored through line " - (STRINGIMAGE (|lineNo| |pos2|)))) - (|shoeConsole| (|lineString| |pos2|)) - (|shoeConsole| - (CONCAT (|shoeSpaces| (|lineCharacter| |pos2|)) "|")))))) - -(DEFUN |lineNo| (|p|) (PROG () (RETURN (CDAAR |p|)))) - -(DEFUN |lineString| (|p|) (PROG () (RETURN (CAAAR |p|)))) - -(DEFUN |lineCharacter| (|p|) (PROG () (RETURN (CDR |p|)))) - -(DEFUN |shoePackageStartsAt| (|lines| |sz| |name| |stream|) - (PROG (|a|) - (RETURN - (COND - ((|bStreamNull| |stream|) (LIST NIL (LIST '|nullstream|))) - ('T - (PROGN - (SETQ |a| (CAAR |stream|)) - (COND - ((AND (NOT (< (LENGTH |a|) 8)) - (EQUAL (SUBSTRING |a| 0 8) ")package")) - (|shoePackageStartsAt| (CONS (CAAR |stream|) |lines|) - |sz| |name| (CDR |stream|))) - ((< (LENGTH |a|) |sz|) - (|shoePackageStartsAt| |lines| |sz| |name| - (CDR |stream|))) - ((AND (EQUAL (SUBSTRING |a| 0 |sz|) |name|) - (< |sz| (LENGTH |a|)) - (NULL (|shoeIdChar| (ELT |a| |sz|)))) - (LIST |lines| |stream|)) - ('T - (|shoePackageStartsAt| |lines| |sz| |name| - (CDR |stream|)))))))))) - -(DEFUN |shoeFindLines| (|fn| |name| |a|) - (PROG (|b| |lines| |LETTMP#1|) - (RETURN - (COND - ((NULL |a|) (|shoeNotFound| |fn|) NIL) - (#0='T - (SETQ |LETTMP#1| - (|shoePackageStartsAt| NIL (LENGTH |name|) |name| - (|shoeInclude| - (|bAddLineNumber| (|bRgen| |a|) (|bIgen| 0))))) - (SETQ |lines| (CAR |LETTMP#1|)) (SETQ |b| (CADR |LETTMP#1|)) - (SETQ |b| (|shoeTransform2| |b|)) - (COND - ((|bStreamNull| |b|) - (|shoeConsole| (CONCAT |name| " not found in " |fn|)) NIL) - (#0# - (COND - ((NULL |lines|) (|shoeConsole| ")package not found"))) - (APPEND (REVERSE |lines|) (CAR |b|))))))))) - -(DEFPARAMETER |$bStreamNil| (LIST '|nullstream|)) - -(DEFUN |bStreamNull| (|x|) - (PROG (|st|) - (RETURN - (COND - ((OR (NULL |x|) (EQCAR |x| '|nullstream|)) T) - ('T - (PROGN - (LOOP - (COND - ((NOT (EQCAR |x| '|nonnullstream|)) (RETURN NIL)) - ('T - (PROGN - (SETQ |st| (APPLY (CADR |x|) (CDDR |x|))) - (RPLACA |x| (CAR |st|)) - (RPLACD |x| (CDR |st|)))))) - (EQCAR |x| '|nullstream|))))))) - -(DEFUN |bMap| (|f| |x|) - (PROG () (RETURN (|bDelay| #'|bMap1| (LIST |f| |x|))))) - -(DEFUN |bMap1| (&REST |z|) - (PROG (|x| |f|) - (DECLARE (SPECIAL |$bStreamNil|)) - (RETURN - (PROGN - (SETQ |f| (CAR |z|)) - (SETQ |x| (CADR |z|)) - (COND - ((|bStreamNull| |x|) |$bStreamNil|) - ('T (CONS (FUNCALL |f| (CAR |x|)) (|bMap| |f| (CDR |x|))))))))) - -(DEFUN |shoeFileMap| (|f| |fn|) - (PROG (|a|) - (DECLARE (SPECIAL |$bStreamNil|)) - (RETURN - (PROGN - (SETQ |a| (|shoeInputFile| |fn|)) - (COND - ((NULL |a|) - (PROGN - (|shoeConsole| (CONCAT |fn| " NOT FOUND")) - |$bStreamNil|)) - ('T - (PROGN - (|shoeConsole| (CONCAT "READING " |fn|)) - (|shoeInclude| - (|bAddLineNumber| (|bMap| |f| (|bRgen| |a|)) - (|bIgen| 0)))))))))) - -(DEFUN |bDelay| (|f| |x|) - (PROG () (RETURN (CONS '|nonnullstream| (CONS |f| |x|))))) - -(DEFUN |bAppend| (|x| |y|) - (PROG () (RETURN (|bDelay| #'|bAppend1| (LIST |x| |y|))))) - -(DEFUN |bAppend1| (&REST |z|) - (PROG () - (RETURN - (COND - ((|bStreamNull| (CAR |z|)) - (COND - ((|bStreamNull| (CADR |z|)) (LIST '|nullstream|)) - (#0='T (CADR |z|)))) - (#0# (CONS (CAAR |z|) (|bAppend| (CDAR |z|) (CADR |z|)))))))) - -(DEFUN |bNext| (|f| |s|) - (PROG () (RETURN (|bDelay| #'|bNext1| (LIST |f| |s|))))) - -(DEFUN |bNext1| (|f| |s|) - (PROG (|h|) - (RETURN - (COND - ((|bStreamNull| |s|) (LIST '|nullstream|)) - ('T - (PROGN - (SETQ |h| (APPLY |f| (LIST |s|))) - (|bAppend| (CAR |h|) (|bNext| |f| (CDR |h|))))))))) - -(DEFUN |bRgen| (|s|) - (PROG () (RETURN (|bDelay| #'|bRgen1| (LIST |s|))))) - -(DEFUN |bRgen1| (&REST |s|) - (PROG (|a|) - (RETURN - (PROGN - (SETQ |a| (|shoeReadLine| (CAR |s|))) - (COND - ((|shoePLACEP| |a|) (LIST '|nullstream|)) - ('T (CONS |a| (|bRgen| (CAR |s|))))))))) - -(DEFUN |bIgen| (|n|) - (PROG () (RETURN (|bDelay| #'|bIgen1| (LIST |n|))))) - -(DEFUN |bIgen1| (&REST |n|) - (PROG () - (RETURN - (PROGN (SETQ |n| (+ (CAR |n|) 1)) (CONS |n| (|bIgen| |n|)))))) - -(DEFUN |bAddLineNumber| (|f1| |f2|) - (PROG () (RETURN (|bDelay| #'|bAddLineNumber1| (LIST |f1| |f2|))))) - -(DEFUN |bAddLineNumber1| (&REST |f|) - (PROG (|f2| |f1|) - (RETURN - (PROGN - (SETQ |f1| (CAR |f|)) - (SETQ |f2| (CADR |f|)) - (COND - ((|bStreamNull| |f1|) (LIST '|nullstream|)) - ((|bStreamNull| |f2|) (LIST '|nullstream|)) - ('T - (CONS (CONS (CAR |f1|) (CAR |f2|)) - (|bAddLineNumber| (CDR |f1|) (CDR |f2|))))))))) - -(DEFUN |shoeFileInput| (|fn|) - (PROG () (RETURN (|shoeFileMap| #'IDENTITY |fn|)))) - -(DEFUN |shoePrefixLisp| (|x|) (PROG () (RETURN (CONCAT ")lisp" |x|)))) - -(DEFUN |shoeLispFileInput| (|fn|) - (PROG () (RETURN (|shoeFileMap| #'|shoePrefixLisp| |fn|)))) - -(DEFUN |shoePrefixLine| (|x|) (PROG () (RETURN (CONCAT ")line" |x|)))) - -(DEFUN |shoeLineFileInput| (|fn|) - (PROG () (RETURN (|shoeFileMap| #'|shoePrefixLine| |fn|)))) - -(DEFUN |shoePrefix?| (|prefix| |whole|) - (PROG (|good|) - (RETURN - (COND - ((< (LENGTH |whole|) (LENGTH |prefix|)) NIL) - ('T - (PROGN - (SETQ |good| T) - (LET ((|bfVar#1| (- (LENGTH |prefix|) 1)) (|i| 0) (|j| 0)) - (LOOP - (COND - ((OR (> |i| |bfVar#1|) (NOT |good|)) (RETURN NIL)) - ('T - (SETQ |good| - (EQUAL (ELT |prefix| |i|) (ELT |whole| |j|))))) - (SETQ |i| (+ |i| 1)) - (SETQ |j| (+ |j| 1)))) - (COND - (|good| (SUBSTRING |whole| (LENGTH |prefix|) NIL)) - ('T |good|)))))))) - -(DEFUN |shoePlainLine?| (|s|) - (PROG () - (RETURN - (COND - ((EQL (LENGTH |s|) 0) T) - ('T (NOT (EQUAL (ELT |s| 0) (|char| '|)|)))))))) - -(DEFUN |shoeSay?| (|s|) (PROG () (RETURN (|shoePrefix?| ")say" |s|)))) - -(DEFUN |shoeEval?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")eval" |s|)))) - -(DEFUN |shoeInclude?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")include" |s|)))) - -(DEFUN |shoeFin?| (|s|) (PROG () (RETURN (|shoePrefix?| ")fin" |s|)))) - -(DEFUN |shoeIf?| (|s|) (PROG () (RETURN (|shoePrefix?| ")if" |s|)))) - -(DEFUN |shoeEndIf?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")endif" |s|)))) - -(DEFUN |shoeElse?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")else" |s|)))) - -(DEFUN |shoeElseIf?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")elseif" |s|)))) - -(DEFUN |shoePackage?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")package" |s|)))) - -(DEFUN |shoeLisp?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")lisp" |s|)))) - -(DEFUN |shoeIncludeLisp?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")includelisp" |s|)))) - -(DEFUN |shoeLine?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")line" |s|)))) - -(DEFUN |shoeIncludeLines?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")includelines" |s|)))) - -(DEFUN |shoeIncludeFunction?| (|s|) - (PROG () (RETURN (|shoePrefix?| ")includefunction" |s|)))) - -(DEFUN |shoeBiteOff| (|x|) - (PROG (|n1| |n|) - (RETURN - (PROGN - (SETQ |n| (STRPOSL " " |x| 0 T)) - (COND - ((NULL |n|) NIL) - (#0='T - (PROGN - (SETQ |n1| (STRPOSL " " |x| |n| NIL)) - (COND - ((NULL |n1|) (LIST (SUBSTRING |x| |n| NIL) "")) - (#0# - (LIST (SUBSTRING |x| |n| (- |n1| |n|)) - (SUBSTRING |x| |n1| NIL))))))))))) - -(DEFUN |shoeFileName| (|x|) - (PROG (|c| |a|) - (RETURN - (PROGN - (SETQ |a| (|shoeBiteOff| |x|)) - (COND - ((NULL |a|) "") - (#0='T - (PROGN - (SETQ |c| (|shoeBiteOff| (CADR |a|))) - (COND - ((NULL |c|) (CAR |a|)) - (#0# (CONCAT (CAR |a|) "." (CAR |c|))))))))))) - -(DEFUN |shoeFnFileName| (|x|) - (PROG (|c| |a|) - (RETURN - (PROGN - (SETQ |a| (|shoeBiteOff| |x|)) - (COND - ((NULL |a|) (LIST "" "")) - (#0='T - (PROGN - (SETQ |c| (|shoeFileName| (CADR |a|))) - (COND - ((NULL |c|) (LIST (CAR |a|) "")) - (#0# (LIST (CAR |a|) |c|)))))))))) - -(DEFUN |shoeFunctionFileInput| (|bfVar#2|) - (PROG (|fn| |fun|) - (RETURN - (PROGN - (SETQ |fun| (CAR |bfVar#2|)) - (SETQ |fn| (CADR |bfVar#2|)) - (|shoeOpenInputFile| |a| |fn| - (|shoeInclude| - (|bAddLineNumber| (|shoeFindLines| |fn| |fun| |a|) - (|bIgen| 0)))))))) - -(DEFUN |shoeInclude| (|s|) - (PROG () (RETURN (|bDelay| #'|shoeInclude1| (LIST |s|))))) - -(DEFUN |shoeInclude1| (|s|) - (PROG (|command| |string| |t| |h|) - (DECLARE (SPECIAL |$bStreamNil|)) - (RETURN - (COND - ((|bStreamNull| |s|) |s|) - (#0='T - (PROGN - (SETQ |h| (CAR |s|)) - (SETQ |t| (CDR |s|)) - (SETQ |string| (CAR |h|)) - (COND - ((SETQ |command| (|shoeFin?| |string|)) |$bStreamNil|) - ((SETQ |command| (|shoeIf?| |string|)) - (|shoeThen| (LIST T) (LIST (STTOMC |command|)) |t|)) - (#0# - (|bAppend| (|shoeSimpleLine| |h|) (|shoeInclude| |t|)))))))))) - -(DEFUN |shoeSimpleLine| (|h|) - (PROG (|command| |string|) - (RETURN - (PROGN - (SETQ |string| (CAR |h|)) - (COND - ((|shoePlainLine?| |string|) (LIST |h|)) - ((SETQ |command| (|shoeLisp?| |string|)) (LIST |h|)) - ((SETQ |command| (|shoeIncludeLisp?| |string|)) - (|shoeLispFileInput| (|shoeFileName| |command|))) - ((SETQ |command| (|shoeIncludeFunction?| |string|)) - (|shoeFunctionFileInput| (|shoeFnFileName| |command|))) - ((SETQ |command| (|shoeLine?| |string|)) (LIST |h|)) - ((SETQ |command| (|shoeIncludeLines?| |string|)) - (|shoeLineFileInput| (|shoeFileName| |command|))) - ((SETQ |command| (|shoeInclude?| |string|)) - (|shoeFileInput| (|shoeFileName| |command|))) - ((SETQ |command| (|shoePackage?| |string|)) (LIST |h|)) - ((SETQ |command| (|shoeSay?| |string|)) - (PROGN (|shoeConsole| |command|) NIL)) - ((SETQ |command| (|shoeEval?| |string|)) - (PROGN (STTOMC |command|) NIL)) - ('T (PROGN (|shoeLineSyntaxError| |h|) NIL))))))) - -(DEFUN |shoeThen| (|keep| |b| |s|) - (PROG () (RETURN (|bDelay| #'|shoeThen1| (LIST |keep| |b| |s|))))) - -(DEFUN |shoeThen1| (|keep| |b| |s|) - (PROG (|b1| |keep1| |command| |string| |t| |h|) - (RETURN - (COND - ((|bPremStreamNull| |s|) |s|) - (#0='T - (PROGN - (SETQ |h| (CAR |s|)) - (SETQ |t| (CDR |s|)) - (SETQ |string| (CAR |h|)) - (COND - ((SETQ |command| (|shoeFin?| |string|)) - (|bPremStreamNil| |h|)) - (#0# - (PROGN - (SETQ |keep1| (CAR |keep|)) - (SETQ |b1| (CAR |b|)) - (COND - ((SETQ |command| (|shoeIf?| |string|)) - (COND - ((AND |keep1| |b1|) - (|shoeThen| (CONS T |keep|) - (CONS (STTOMC |command|) |b|) |t|)) - (#0# - (|shoeThen| (CONS NIL |keep|) (CONS NIL |b|) |t|)))) - ((SETQ |command| (|shoeElseIf?| |string|)) - (COND - ((AND |keep1| (NULL |b1|)) - (|shoeThen| (CONS T (CDR |keep|)) - (CONS (STTOMC |command|) (CDR |b|)) |t|)) - (#0# - (|shoeThen| (CONS NIL (CDR |keep|)) - (CONS NIL (CDR |b|)) |t|)))) - ((SETQ |command| (|shoeElse?| |string|)) - (COND - ((AND |keep1| (NULL |b1|)) - (|shoeElse| (CONS T (CDR |keep|)) - (CONS T (CDR |b|)) |t|)) - (#0# - (|shoeElse| (CONS NIL (CDR |keep|)) - (CONS NIL (CDR |b|)) |t|)))) - ((SETQ |command| (|shoeEndIf?| |string|)) - (COND - ((NULL (CDR |b|)) (|shoeInclude| |t|)) - (#0# (|shoeThen| (CDR |keep|) (CDR |b|) |t|)))) - ((AND |keep1| |b1|) - (|bAppend| (|shoeSimpleLine| |h|) - (|shoeThen| |keep| |b| |t|))) - (#0# (|shoeThen| |keep| |b| |t|)))))))))))) - -(DEFUN |shoeElse| (|keep| |b| |s|) - (PROG () (RETURN (|bDelay| #'|shoeElse1| (LIST |keep| |b| |s|))))) - -(DEFUN |shoeElse1| (|keep| |b| |s|) - (PROG (|keep1| |b1| |command| |string| |t| |h|) - (RETURN - (COND - ((|bPremStreamNull| |s|) |s|) - (#0='T - (PROGN - (SETQ |h| (CAR |s|)) - (SETQ |t| (CDR |s|)) - (SETQ |string| (CAR |h|)) - (COND - ((SETQ |command| (|shoeFin?| |string|)) - (|bPremStreamNil| |h|)) - (#0# - (PROGN - (SETQ |b1| (CAR |b|)) - (SETQ |keep1| (CAR |keep|)) - (COND - ((SETQ |command| (|shoeIf?| |string|)) - (COND - ((AND |keep1| |b1|) - (|shoeThen| (CONS T |keep|) - (CONS (STTOMC |command|) |b|) |t|)) - (#0# - (|shoeThen| (CONS NIL |keep|) (CONS NIL |b|) |t|)))) - ((SETQ |command| (|shoeEndIf?| |string|)) - (COND - ((NULL (CDR |b|)) (|shoeInclude| |t|)) - (#0# (|shoeThen| (CDR |keep|) (CDR |b|) |t|)))) - ((AND |keep1| |b1|) - (|bAppend| (|shoeSimpleLine| |h|) - (|shoeElse| |keep| |b| |t|))) - (#0# (|shoeElse| |keep| |b| |t|)))))))))))) - -(DEFUN |shoeLineSyntaxError| (|h|) - (PROG () - (RETURN - (PROGN - (|shoeConsole| - (CONCAT "INCLUSION SYNTAX ERROR IN LINE " - (STRINGIMAGE (CDR |h|)))) - (|shoeConsole| (CAR |h|)) - (|shoeConsole| "LINE IGNORED"))))) - -(DEFUN |bPremStreamNil| (|h|) - (PROG () - (DECLARE (SPECIAL |$bStreamNil|)) - (RETURN - (PROGN - (|shoeConsole| - (CONCAT "UNEXPECTED )fin IN LINE " (STRINGIMAGE (CDR |h|)))) - (|shoeConsole| (CAR |h|)) - (|shoeConsole| "REST OF FILE IGNORED") - |$bStreamNil|)))) - -(DEFUN |bPremStreamNull| (|s|) - (PROG () - (RETURN - (COND - ((|bStreamNull| |s|) - (|shoeConsole| "FILE TERMINATED BEFORE )endif") T) - ('T NIL))))) - -@ - - -\end{document} diff --git a/src/boot/initial-env.lisp.pamphlet b/src/boot/initial-env.lisp index d3242458..d256e7c4 100644 --- a/src/boot/initial-env.lisp.pamphlet +++ b/src/boot/initial-env.lisp @@ -1,29 +1,7 @@ -%% Oh Emacs, this is a -*- Lisp -*- file despite apperance. -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/initial-env.lisp} Pamphlet} -\author{Gabriel Dos~Reis \and Timothy Daly} - -\begin{document} -\maketitle - -\begin{abstract} - This pamphlet defines the base initial environment for building - a Boot translator image. It essentially etablishes a namespace - (package \Code{Boot}) for the Boot translator, and defines - some macros that need to be present during translation of Boot - source files. -\end{abstract} - -\tableofcontents -\eject - -\section{License} - -<<license>>= ;; Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. ;; All rights reserved. +;; Copyright (C) 2007-2008, Gabriel Dos Reis. +;; All rights reserved. ;; ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions are @@ -52,60 +30,23 @@ ;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;; -@ -\section{The \code{BOOTTRAN} package} +;; +;; Abstract: +;; This file defines the base initial environment for building +;; a Boot translator image. It essentially etablishes a namespace +;; (package BOOTTRAN) for the Boot translator, and defines +;; some macros that need to be present during translation of Boot +;; source files. +;; -All Boot translator functions are defined in the package -\code{BOOTTRAN}. It is expected that the translator interfaces -with the rest of the system only through the functions explicitly exported -by \code{BOOTTRAN}: -<<boot-translator>>= (defpackage "BOOTTRAN" (:use "AxiomCore") #+:common-lisp (:use "COMMON-LISP") #-:common-lisp (:use "LISP")) -@ - -\section{I/O macros} - -The Boot translator source codes make uses of some -higher order functions. For various reasons, including efficiency, -they are defined as Lisp macros and must therefore be available in each -source file that uses them. - -\subsection{[[shoeInputFile]]} - -<<with-input-file>>= -(defmacro |shoeOpenInputFile| - (stream fn prog) - `(with-open-file (,stream ,fn :direction :input - :if-does-not-exist nil) ,prog)) -@ - -This macro creates a input stream object from a file name [[fn]], and -processes it with [[prog]]. If the file name designates a non-existent -file, the standard input is used instead. - -\subsection{[[shoeOpenOutputFile]]} -<<with-output-file>>= -(defmacro |shoeOpenOutputFile| - (stream fn prog) - `(with-open-file (,stream ,fn :direction :output - :if-exists :supersede) ,prog)) -@ - -This macro creates an output stream object from a file name [[fn]], and -processes it with [[prog]]. The output file is overwritten if it exists. - -\section{Putting it together} - -<<*>>= -<<license>> - -<<boot-translator>> (in-package "BOOTTRAN") @@ -113,12 +54,22 @@ processes it with [[prog]]. The output file is overwritten if it exists. #+:ieee-floating-point (defparameter $ieee t) #-:ieee-floating-point (defparameter $ieee nil) -(defmacro memq (a b) `(member ,a ,b :test #'eq)) +(defmacro memq (a b) + `(member ,a ,b :test #'eq)) + (defvar *lisp-bin-filetype* "o") + (defvar *lisp-source-filetype* "lisp") -(defun setdifference (x y) (set-difference x y)) -(defun make-cvec (sint) (make-string sint)) -(defun MAKE-VEC (n) (make-array n)) + +(defun setdifference (x y) + (set-difference x y)) + +(defun make-cvec (sint) + (make-string sint)) + +(defun MAKE-VEC (n) + (make-array n)) + (defun concat (&rest l) (progn (setq l (mapcar #'string l)) @@ -127,16 +78,22 @@ processes it with [[prog]]. The output file is overwritten if it exists. (defun |shoeInputFile| (filespec ) (open filespec :direction :input :if-does-not-exist nil)) -<<with-input-file>> +(defmacro |shoeOpenInputFile| + (stream fn prog) + `(with-open-file (,stream ,fn :direction :input + :if-does-not-exist nil) ,prog)) -<<with-output-file>> +(defmacro |shoeOpenOutputFile| + (stream fn prog) + `(with-open-file (,stream ,fn :direction :output + :if-exists :supersede) ,prog)) (defun shoeprettyprin1 (x &optional (stream *standard-output*)) (let ((*print-pretty* t) - (*print-array* t) - (*print-circle* t) - (*print-level* nil) - (*print-length* nil)) + (*print-array* t) + (*print-circle* t) + (*print-level* nil) + (*print-length* nil)) (prin1 x stream))) (defun reallyprettyprint (x &optional (stream *terminal-io*)) @@ -144,14 +101,15 @@ processes it with [[prog]]. The output file is overwritten if it exists. (defun shoeprettyprin0 (x &optional (stream *standard-output*)) (let ((*print-pretty* nil) - (*print-array* t) - (*print-circle* t) - (*print-level* nil) - (*print-length* nil)) + (*print-array* t) + (*print-circle* t) + (*print-level* nil) + (*print-length* nil)) (prin1 x stream))) (defun shoenotprettyprint (x &optional (stream *terminal-io*)) - (shoeprettyprin0 x stream) (terpri stream)) + (shoeprettyprin0 x stream) + (terpri stream)) (defun make-full-cvec (sint &optional (char #\space)) (make-string sint :initial-element (character char))) @@ -160,22 +118,23 @@ processes it with [[prog]]. The output file is overwritten if it exists. (eq item nil)) (defun substring (cvec start length) - (if length (subseq cvec start (+ start length)) + (if length + (subseq cvec start (+ start length)) (subseq cvec start))) (defun MAKE-HASHTABLE (id1) (let ((test (case id1 - ((EQ ID) #'eq) - (CVEC #'equal) - ((UEQUAL EQUAL) #'equal) - (otherwise (error "bad arg to make-hashtable"))))) + ((EQ ID) #'eq) + (CVEC #'equal) + ((UEQUAL EQUAL) #'equal) + (otherwise (error "bad arg to make-hashtable"))))) (make-hash-table :test test))) (defun HKEYS (table) (let (keys) (maphash #'(lambda (key val) - (declare (ignore val)) - (push key keys)) table) + (declare (ignore val)) + (push key keys)) table) keys)) @@ -198,25 +157,32 @@ processes it with [[prog]]. The output file is overwritten if it exists. (defun strpos (what in start dontcare) (setq what (string what) in (string in)) - (if dontcare (progn (setq dontcare (character dontcare)) - (search what in :start2 start - :test #'(lambda (x y) (or (eql x dontcare) - (eql x y))))) + (if dontcare + (progn + (setq dontcare (character dontcare)) + (search what in :start2 start + :test #'(lambda (x y) (or (eql x dontcare) + (eql x y))))) (search what in :start2 start))) (defun strposl (table cvec sint item) (setq cvec (string cvec)) (if (not item) - (position table cvec :test #'(lambda (x y) (position y x)) :start sint) - (position table cvec :test-not #'(lambda (x y) (position y x)) - :start sint ))) + (position table cvec + :test #'(lambda (x y) (position y x)) + :start sint) + (position table cvec + :test-not #'(lambda (x y) (position y x)) + :start sint))) (defun VEC-SETELT (vec ind val) (setf (elt vec ind) val)) (defun bvec-make-full (n x) - (make-array (list n) :element-type 'bit :initial-element x)) + (make-array (list n) + :element-type 'bit + :initial-element x)) (defun make-bvec (n) (bvec-make-full n 0)) @@ -226,8 +192,8 @@ processes it with [[prog]]. The output file is overwritten if it exists. (defun size (l) (cond ((vectorp l) (length l)) - ((consp l) (list-length l)) - (t 0))) + ((consp l) (list-length l)) + (t 0))) (defun identp (a) (and (symbolp a) a)) @@ -237,7 +203,3 @@ processes it with [[prog]]. The output file is overwritten if it exists. (defun |last| (x) (car (last x))) -@ - - -\end{document} diff --git a/src/boot/parser.boot b/src/boot/parser.boot new file mode 100644 index 00000000..9908a68a --- /dev/null +++ b/src/boot/parser.boot @@ -0,0 +1,1041 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- All rights reserved. +-- Copyright (C) 2007-2008, Gabriel Dos Reis. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + +-- +-- Abstract: +-- This file defines the Boot grammar and parser. The parser +-- is hand-written based on `parser combinators' technology. +-- + + +module '"boot-parser" +import '"includer" +import '"scanner" +import '"ast" + +)package "BOOTTRAN" + + +++ true when the current function definition has its parameters +++ written round parenthesis. +$sawParenthesizedHead := false + +++ true if the current function definition has a return statement. +$bodyHasReturn := false + + +bpFirstToken()== + $stok:= + if null $inputStream + then shoeTokConstruct("ERROR","NOMORE",shoeTokPosn $stok) + else CAR $inputStream + $ttok:=shoeTokPart $stok + true + +bpFirstTok()== + $stok:= + if null $inputStream + then shoeTokConstruct("ERROR","NOMORE",shoeTokPosn $stok) + else CAR $inputStream + $ttok:=shoeTokPart $stok + $bpParenCount>0 and EQCAR($stok,"KEY") => + EQ($ttok,"SETTAB")=> + $bpCount:=$bpCount+1 + bpNext() + EQ($ttok,"BACKTAB")=> + $bpCount:=$bpCount-1 + bpNext() + EQ($ttok,"BACKSET")=> + bpNext() + true + true + +bpNext() == + $inputStream := CDR($inputStream) + bpFirstTok() + +bpNextToken() == + $inputStream := CDR($inputStream) + bpFirstToken() + +bpState()== [$inputStream,$stack,$bpParenCount,$bpCount] +--cons($inputStream,$stack) + +bpRestore(x)== + $inputStream:=CAR x + bpFirstToken() + $stack:=CADR x + $bpParenCount:=CADDR x + $bpCount:=CADDDR x + true + +bpPush x==$stack:=CONS(x,$stack) + +bpPushId()== + $stack:=CONS(bfReName $ttok,$stack) + +bpPop1()== + a:=CAR $stack + $stack:=CDR $stack + a + +bpPop2()== + a:=CADR $stack + RPLACD($stack,CDDR $stack) + a + +bpPop3()== + a:=CADDR $stack + RPLACD(CDR $stack,CDDDR $stack) + a + +bpIndentParenthesized f== + $bpCount:local:=0 + a:=$stok + if bpEqPeek "OPAREN" + then + $bpParenCount:=$bpParenCount+1 + bpNext() + if APPLY(f,nil) and bpFirstTok() and + (bpEqPeek "CPAREN" or bpParenTrap(a)) + then + $bpParenCount:=$bpParenCount-1 + bpNextToken() + $bpCount=0 => true + $inputStream:=append( bpAddTokens $bpCount,$inputStream) + bpFirstToken() + $bpParenCount=0 => + bpCancel() + true + true + else if bpEqPeek "CPAREN" + then + bpPush bfTuple [] + $bpParenCount:=$bpParenCount-1 + bpNextToken() + true + else bpParenTrap(a) + else false + +bpParenthesized f== + a:=$stok + if bpEqKey "OPAREN" + then + if APPLY(f,nil) and (bpEqKey "CPAREN" or bpParenTrap(a)) + then true + else if bpEqKey "CPAREN" + then + bpPush bfTuple [] + true + else bpParenTrap(a) + else false + +bpBracket f== + a:=$stok + if bpEqKey "OBRACK" + then + if APPLY(f,nil) and (bpEqKey "CBRACK" or bpBrackTrap(a)) + then bpPush bfBracket bpPop1 () + else if bpEqKey "CBRACK" + then bpPush [] + else bpBrackTrap(a) + else false + +bpPileBracketed f== + if bpEqKey "SETTAB" + then if bpEqKey "BACKTAB" + then true + else if APPLY(f,nil) and + (bpEqKey "BACKTAB" or bpPileTrap()) + then bpPush bfPile bpPop1() + else false + else false + +bpListof(f,str1,g)== + if APPLY(f,nil) + then + if bpEqKey str1 and (APPLY(f,nil) or bpTrap()) + then + a:=$stack + $stack:=nil + while bpEqKey str1 and (APPLY(f,nil) or bpTrap()) repeat 0 + $stack:=cons(NREVERSE $stack,a) + bpPush FUNCALL(g, [bpPop3(),bpPop2(),:bpPop1()]) + else + true + else false + + +-- to do ,<backset> +bpListofFun(f,h,g)== + if APPLY(f,nil) + then + if APPLY(h,nil) and (APPLY(f,nil) or bpTrap()) + then + a:=$stack + $stack:=nil + while APPLY(h,nil) and (APPLY(f,nil) or bpTrap()) repeat 0 + $stack:=cons(NREVERSE $stack,a) + bpPush FUNCALL(g, bfListOf [bpPop3(),bpPop2(),:bpPop1()]) + else + true + else false + +bpList(f,str1,g)== + if APPLY(f,nil) + then + if bpEqKey str1 and (APPLY(f,nil) or bpTrap()) + then + a:=$stack + $stack:=nil + while bpEqKey str1 and (APPLY(f,nil) or bpTrap()) repeat 0 + $stack:=cons(NREVERSE $stack,a) + bpPush FUNCALL(g, [bpPop3(),bpPop2(),:bpPop1()]) + else + bpPush FUNCALL(g, [bpPop1()]) + else bpPush FUNCALL(g, []) + +bpOneOrMore f== + APPLY(f,nil)=> + a:=$stack + $stack:=nil + while APPLY(f,nil) repeat 0 + $stack:=cons(NREVERSE $stack,a) + bpPush cons(bpPop2(),bpPop1()) + false + + +-- s must transform the head of the stack +bpAnyNo s== + while APPLY(s,nil) repeat 0 + true + + +-- AndOr(k,p,f)= k p +bpAndOr(keyword,p,f)== + bpEqKey keyword and (APPLY(p,nil) or bpTrap()) + and bpPush FUNCALL(f, bpPop1()) + +bpConditional f== + if bpEqKey "IF" and (bpWhere() or bpTrap()) and + (bpEqKey "BACKSET" or true) + then + if bpEqKey "SETTAB" + then if bpEqKey "THEN" + then (APPLY(f,nil) or bpTrap()) and bpElse(f) and bpEqKey "BACKTAB" + else bpMissing "THEN" + else if bpEqKey "THEN" + then (APPLY(f,nil) or bpTrap()) and bpElse(f) + else bpMissing "then" + else false + +bpElse(f)== + a:=bpState() + if bpBacksetElse() + then (APPLY(f,nil) or bpTrap()) and + bpPush bfIf(bpPop3(),bpPop2(),bpPop1()) + else + bpRestore a + bpPush bfIfThenOnly(bpPop2(),bpPop1()) + +bpBacksetElse()== + if bpEqKey "BACKSET" + then bpEqKey "ELSE" + else bpEqKey "ELSE" + +bpEqPeek s == EQCAR($stok,"KEY") and EQ(s,$ttok) + +bpEqKey s == EQCAR($stok,"KEY") and EQ(s,$ttok) and bpNext() +bpEqKeyNextTok s == EQCAR($stok,"KEY") and EQ(s,$ttok) and + bpNextToken() + +bpPileTrap() == bpMissing "BACKTAB" +bpBrackTrap(x) == bpMissingMate("]",x) +bpParenTrap(x) == bpMissingMate(")",x) + +bpMissingMate(close,open)== + bpSpecificErrorAtToken(open, '"possibly missing mate") + bpMissing close + +bpMissing s== + bpSpecificErrorHere(CONCAT(PNAME s,'" possibly missing")) + THROW("TRAPPOINT","TRAPPED") + +bpCompMissing s == bpEqKey s or bpMissing s + +bpTrap()== + bpGeneralErrorHere() + THROW("TRAPPOINT","TRAPPED") + +bpRecoverTrap()== + bpFirstToken() + pos1 := shoeTokPosn $stok + bpMoveTo 0 + pos2 := shoeTokPosn $stok + bpIgnoredFromTo(pos1, pos2) + bpPush [['"pile syntax error"]] + +bpListAndRecover(f)== + a:=$stack + b:=nil + $stack:=nil + done:=false + c:=$inputStream + while not done repeat +-- $trapped:local:=false + found:=CATCH("TRAPPOINT",APPLY(f,nil)) + if found="TRAPPED" + then + $inputStream:=c + bpRecoverTrap() + else if not found + then + $inputStream:=c + bpGeneralErrorHere() + bpRecoverTrap() + if bpEqKey "BACKSET" + then + c:=$inputStream + else if bpEqPeek "BACKTAB" or null $inputStream + then + done:=true + else + $inputStream:=c + bpGeneralErrorHere() + bpRecoverTrap() + if bpEqPeek "BACKTAB" or null $inputStream + then done:=true + else + bpNext() + c:=$inputStream + b:=cons(bpPop1(),b) + $stack:=a + bpPush NREVERSE b + +bpMoveTo n== + null $inputStream => true + bpEqPeek "BACKTAB" => + n=0 => true + bpNextToken() + $bpCount:=$bpCount-1 + bpMoveTo(n-1) + bpEqPeek "BACKSET" => + n=0 => true + bpNextToken() + bpMoveTo n + bpEqPeek "SETTAB" => + bpNextToken() + bpMoveTo(n+1) + bpEqPeek "OPAREN" => + bpNextToken() + $bpParenCount:=$bpParenCount+1 + bpMoveTo n + bpEqPeek "CPAREN" => + bpNextToken() + $bpParenCount:=$bpParenCount-1 + bpMoveTo n + bpNextToken() + bpMoveTo n + +-- A fully qualified name could be interpreted as a left reduction +-- of an '::' infix operator. At the moment, we don't use +-- that general interpretation. + +-- When this routine is called, a symbol is already pushed on the +-- stack. When this routine finished execution, we have either +-- reduced a '::' and a name, or nothing. In either case, a +-- symbol is present on the stack. +bpQualifiedName() == + bpEqPeek "COLON-COLON" => + bpNext() + EQCAR($stok, "ID") and bpPushId() and bpNext() + and bpPush bfColonColon(bpPop2(), bpPop1()) + false + +++ Name: +++ ID +++ Name :: ID +bpName() == + EQCAR( $stok,"ID") => + bpPushId() + bpNext() + bpAnyNo function bpQualifiedName + false + + +++ Constant: +++ INTEGER +++ FLOAT +++ LISP +++ LISPEXPR +++ LINE +++ QUOTE S-Expression +++ STRING +bpConstTok() == + MEMQ(shoeTokType $stok, '(INTEGER FLOAT)) => + bpPush $ttok + bpNext() + EQCAR($stok,"LISP")=> bpPush bfReadLisp $ttok and bpNext() + EQCAR($stok,"LISPEXP")=> bpPush $ttok and bpNext() + EQCAR($stok,"LINE")=> bpPush ["+LINE", $ttok] and bpNext() + bpEqPeek "QUOTE" => + bpNext() + (bpSexp() or bpTrap()) and + bpPush bfSymbol bpPop1() + bpString() + +++ Parse a module definitoin +++ Module: +++ MODULE QUOTE String +bpModule() == + bpEqKey "MODULE" => + -- we really want to check that the next token is indeed + -- a string. For the moment, we delay the type checking + -- to the Lisp compiler/interpreter. That is likely to + -- cause cryptic diagnostics. To be fixed. + bpConstTok() and bpPush Module bpPop1() + false + +++ Parse a module import, or a import declaration for a foreign entity. +++ Import: +++ IMPORT Name for Signature +++ IMPORT QUOTE String +bpImport() == + bpEqKey "IMPORT" => + (bpName() and (bpEqKey "FOR" or bpTrap()) and bpSignature() + and bpPush ImportSignature(bpPop2(), bpPop1())) + or + -- we really want to check that the next token is indeed + -- a string. For the moment, we delay the type checking + -- to the Lisp compiler/interpreter. That is likely to + -- cause cryptic diagnostics. To be fixed. + (bpConstTok() and bpPush Import bpPop1()) + false + +-- Parse a type alias defnition: +-- type-alias-definition: +-- identifier <=> logical-expression +bpTypeAliasDefition() == + (bpName() or bpTrap()) and + bpEqKey "TDEF" and bpLogical() and + bpPush TypeAlias(bpPop2(), nil, bpPop1()) + +++ Parse a signature declaration +++ Signature: +++ Name COLON Mapping +bpSignature() == + bpName() and bpEqKey "COLON" and bpMapping() + and bpPush Signature(bpPop2(), bpPop1()) + +++ Parse a mapping expression +++ Mapping: +++ (Name | IdList) -> Name +bpMapping() == + (bpName() or bpIdList()) and bpEqKey "ARROW" and bpName() + and bpPush Mapping(bpPop1(), bpPop1()) + +bpCancel()== + a:=bpState() + if bpEqKeyNextTok "SETTAB" + then if bpCancel() + then if bpEqKeyNextTok "BACKTAB" + then true + else + bpRestore a + false + else + if bpEqKeyNextTok "BACKTAB" + then true + else + bpRestore a + false + else false +bpAddTokens n== + n=0 => nil + n>0=> cons(shoeTokConstruct("KEY","SETTAB",shoeTokPosn $stok),bpAddTokens(n-1)) + cons(shoeTokConstruct("KEY","BACKTAB",shoeTokPosn $stok),bpAddTokens(n+1)) + +bpExceptions()== + bpEqPeek "DOT" or bpEqPeek "QUOTE" or + bpEqPeek "OPAREN" or bpEqPeek "CPAREN" or + bpEqPeek "SETTAB" or bpEqPeek "BACKTAB" + or bpEqPeek "BACKSET" + + +bpSexpKey()== + EQCAR( $stok,"KEY") and not bpExceptions()=> + a:=GET($ttok,"SHOEINF") + null a=> bpPush $ttok and bpNext() + bpPush a and bpNext() + false + +bpAnyId()== + bpEqKey "MINUS" and (EQCAR($stok,"INTEGER") or bpTrap()) and + bpPush MINUS $ttok and bpNext() or + bpSexpKey() or + MEMQ(shoeTokType $stok, '(ID INTEGER STRING FLOAT)) + and bpPush $ttok and bpNext() + +bpSexp()== + bpAnyId() or + bpEqKey "QUOTE" and (bpSexp() or bpTrap()) + and bpPush bfSymbol bpPop1() or + bpIndentParenthesized function bpSexp1 + +bpSexp1()== bpFirstTok() and + bpSexp() and + (bpEqKey "DOT" and bpSexp() and bpPush CONS (bpPop2(),bpPop1())or + bpSexp1() and bpPush CONS (bpPop2(),bpPop1())) or + bpPush nil + +bpPrimary1() == + bpName() or + bpDot() or + bpConstTok() or + bpConstruct() or + bpCase() or + bpStruct() or + bpPDefinition() or + bpBPileDefinition() + +bpPrimary()== bpFirstTok() and (bpPrimary1() or bpPrefixOperator()) + +bpDot()== bpEqKey "DOT" and bpPush bfDot () + +bpPrefixOperator()== + EQCAR( $stok,"KEY") and + GET($ttok,"SHOEPRE") and bpPushId() and bpNext() + +bpInfixOperator()== + EQCAR( $stok,"KEY") and + GET($ttok,"SHOEINF") and bpPushId() and bpNext() + +bpSelector()== + bpEqKey "DOT" and (bpPrimary() + and bpPush(bfElt(bpPop2(),bpPop1())) + or bpPush bfSuffixDot bpPop1() ) + +bpOperator()== bpPrimary() and bpAnyNo function bpSelector + +bpApplication()== + bpPrimary() and bpAnyNo function bpSelector and + (bpApplication() and + bpPush(bfApplication(bpPop2(),bpPop1())) or true) + +bpTagged()== + bpApplication() and + (bpEqKey "COLON" and (bpApplication() or bpTrap()) and + bpPush bfTagged(bpPop2(),bpPop1()) or true) + +bpExpt()== bpRightAssoc('(POWER),function bpTagged) + +bpInfKey s== + EQCAR( $stok,"KEY") and + MEMBER($ttok,s) and bpPushId() and bpNext() + +bpInfGeneric s== bpInfKey s and (bpEqKey "BACKSET" or true) + +bpRightAssoc(o,p)== + a:=bpState() + if APPLY(p,nil) + then + while bpInfGeneric o and (bpRightAssoc(o,p) or bpTrap()) repeat + bpPush bfInfApplication(bpPop2(),bpPop2(),bpPop1()) + true + else + bpRestore a + false + +bpLeftAssoc(operations,parser)== + if APPLY(parser,nil) + then + while bpInfGeneric(operations) and + (APPLY(parser,nil) or bpTrap()) + repeat + bpPush bfInfApplication(bpPop2(),bpPop2(),bpPop1()) + true + else false + +bpString()== + EQ(shoeTokType $stok,"STRING") and + bpPush(["QUOTE",INTERN $ttok]) and bpNext() + +bpThetaName() == + if EQCAR( $stok,"ID") and GET($ttok,"SHOETHETA") + then + bpPushId() + bpNext() + else false + +bpReduceOperator()== + bpInfixOperator() or bpString() + or bpThetaName() + +bpReduce()== + a:=bpState() + if bpReduceOperator() and bpEqKey "SLASH" + then + bpEqPeek "OBRACK" => (bpDConstruct() or bpTrap()) and + bpPush bfReduceCollect(bpPop2(),bpPop1()) + (bpApplication() or bpTrap()) and + bpPush bfReduce(bpPop2(),bpPop1()) + else + bpRestore a + false + +bpTimes()== + bpReduce() or bpLeftAssoc('(TIMES SLASH),function bpExpt) + +bpMinus()== + bpInfGeneric '(MINUS) and (bpTimes() or bpTrap()) + and bpPush(bfApplication(bpPop2(),bpPop1())) + or bpTimes() + +bpArith()==bpLeftAssoc('(PLUS MINUS),function bpMinus) + +bpIs()== + bpArith() and (bpInfKey '(IS ISNT) and (bpPattern() or bpTrap()) + and bpPush bfISApplication(bpPop2(),bpPop2(),bpPop1()) + or true) + +bpBracketConstruct(f)== + bpBracket f and bpPush bfConstruct bpPop1 () + +bpCompare()== + bpIs() and (bpInfKey '(SHOEEQ SHOENE LT LE GT GE IN) + and (bpIs() or bpTrap()) + and bpPush bfInfApplication(bpPop2(),bpPop2(),bpPop1()) + or true) + +bpAnd()== bpLeftAssoc('(AND),function bpCompare) + + +++ Note the fact that a return statement is used in the body +++ of current function definition. +bpNoteReturnStmt() == + $bodyHasReturn := true + true + +bpReturn()== + (bpEqKey "RETURN" and bpNoteReturnStmt() and + (bpAnd() or bpTrap()) and + bpPush bfReturnNoName bpPop1()) or bpAnd() + + +bpLogical()== bpLeftAssoc('(OR),function bpReturn) + +bpExpression()== + bpEqKey "COLON" and (bpLogical() and + bpPush bfApplication ("COLON",bpPop1()) + or bpTrap()) or bpLogical() + +bpStatement()== + bpConditional function bpWhere or bpLoop() or bpExpression() + +bpLoop()== + bpIterators() and + (bpCompMissing "REPEAT" and + (bpWhere() or bpTrap()) and + bpPush bfLp(bpPop2(),bpPop1())) + or + bpEqKey "REPEAT" and (bpLogical() or bpTrap()) and + bpPush bfLoop1 bpPop1 () + +bpSuchThat()==bpAndOr("BAR",function bpWhere,function bfSuchthat) + +bpWhile()==bpAndOr ("WHILE",function bpLogical,function bfWhile) + +bpUntil()==bpAndOr ("UNTIL",function bpLogical,function bfUntil) + +bpForIn()== + bpEqKey "FOR" and (bpVariable() or bpTrap()) and (bpCompMissing "IN") + and ((bpSeg() or bpTrap()) and + (bpEqKey "BY" and (bpArith() or bpTrap()) and + bpPush bfForInBy(bpPop3(),bpPop2(),bpPop1())) or + bpPush bfForin(bpPop2(),bpPop1())) + +bpSeg()== + bpArith() and + (bpEqKey "SEG" and + (bpArith() and bpPush(bfSegment2(bpPop2(),bpPop1())) + or bpPush(bfSegment1(bpPop1()))) or true) + +bpIterator()== + bpForIn() or bpSuchThat() or bpWhile() or bpUntil() + +bpIteratorList()==bpOneOrMore function bpIterator + and bpPush bfIterators bpPop1 () + +bpCrossBackSet()== bpEqKey "CROSS" and (bpEqKey "BACKSET" or true) + +bpIterators()== + bpListofFun(function bpIteratorList, + function bpCrossBackSet,function bfCross) + +bpAssign()== + a:=bpState() + if bpStatement() + then + if bpEqPeek "BEC" + then + bpRestore a + bpAssignment() or bpTrap() + else true + else + bpRestore a + false + +bpAssignment()== + bpAssignVariable() and + bpEqKey "BEC" and + (bpAssign() or bpTrap()) and + bpPush bfAssign (bpPop2(),bpPop1()) + +-- should only be allowed in sequences +bpExit()== + bpAssign() and (bpEqKey "EXIT" and + ((bpWhere() or bpTrap()) and + bpPush bfExit (bpPop2(),bpPop1())) + or true) + +++ returns true if the next token introduces a definition. +bpBeginDefinition() == + bpEqPeek "DEF" or + $sawParenthesizedHead and bpEqPeek "COLON" + +bpDefinition()== + a:=bpState() + bpExit() => + bpBeginDefinition() => + bpRestore a + bpDef() + bpEqPeek "TDEF" => + bpRestore a + bpTypeAliasDefition() + bpEqPeek "MDEF" => + bpRestore a + bpMdef() + true + bpRestore a + false + +bpStoreName()== + $op := car $stack + $wheredefs := nil + $typings := nil + $returnType := true -- assume we may return anything + $bodyHasReturn := false + true + +bpReturnType() == + -- a return type is acceptable for a function definition only + -- if its parameters are written in round parenthesis. + -- In particular, we reject the situation `foo x:Integer == ...' + $sawParenthesizedHead and bpEqKey "COLON" => + bpApplication() or bpTrap() + $returnType := bpPop1() + true + true + +bpDef() == + bpName() and bpStoreName() and + bpDefTail() and bpPush bfCompDef bpPop1 () + +bpDDef() == bpName() and bpDefTail() + +++ Parse the remaining of a simple definition. +bpSimpleDefinitionTail() == + bpEqKey "DEF" and + (bpWhere() or bpTrap()) + and bpPush ConstantDefinition(bpPop2(), bpPop1()) + +++ Parse the remaining of a compound definition. +bpCompoundDefinitionTail() == + bpVariable() and bpReturnType() and + bpEqKey "DEF" and (bpWhere() or bpTrap()) + and bpPush bfDefinition(bpPop3(),bpPop2(),bpPop1()) + + +++ Parse the remainding of a definition. When we reach this point +++ we know we must parse a definition and we have already parsed +++ the name of the main operator in the definition. +bpDefTail() == + bpSimpleDefinitionTail() + or bpCompoundDefinitionTail() + + +bpMDefTail()== + -- bpEqKey "MDEF" and + -- (bpWhere() or bpTrap()) + -- and bpPush bfMDefinition1(bpPop2(),bpPop1()) + -- or + (bpVariable() or bpTrap()) and + bpEqKey "MDEF" and (bpWhere() or bpTrap()) + and bpPush bfMDefinition(bpPop3(),bpPop2(),bpPop1()) + +bpMdef()== bpName() and bpStoreName() and bpMDefTail() + +bpWhere()== + bpDefinition() and + (bpEqKey "WHERE" and (bpDefinitionItem() or bpTrap()) + and bpPush bfWhere(bpPop1(),bpPop1()) or true) + +bpDefinitionItem()== + a:=bpState() + if bpDDef() + then true + else + bpRestore a + if bpBDefinitionPileItems() + then true + else + bpRestore a + if bpPDefinitionItems() + then true + else + bpRestore a + bpWhere() + +bpDefinitionPileItems()== + bpListAndRecover function bpDefinitionItem + and bpPush bfDefSequence bpPop1() + +bpBDefinitionPileItems()== bpPileBracketed function bpDefinitionPileItems + +bpSemiColonDefinition()==bpSemiListing + (function bpDefinitionItem,function bfDefSequence) + +bpPDefinitionItems()==bpParenthesized function bpSemiColonDefinition + +bpComma()== + bpModule() or bpImport() or + bpTuple function bpWhere + +bpTuple(p)==bpListofFun(p,function bpCommaBackSet,function bfTuple) + +bpCommaBackSet()== bpEqKey "COMMA" and (bpEqKey "BACKSET" or true) + +bpSemiColon()==bpSemiListing (function bpComma,function bfSequence) + +bpSemiListing(p,f)==bpListofFun(p,function bpSemiBackSet,f) + +bpSemiBackSet()== bpEqKey "SEMICOLON" and (bpEqKey "BACKSET" or true) + +bpPDefinition()== bpIndentParenthesized function bpSemiColon + +bpPileItems()== + bpListAndRecover function bpSemiColon and bpPush bfSequence bpPop1() + +bpBPileDefinition()== bpPileBracketed function bpPileItems + +bpIteratorTail()== + (bpEqKey "REPEAT" or true) and bpIterators() + +--bpExpression()== bpLogical() + +bpConstruct()==bpBracket function bpConstruction + +bpConstruction()== + bpComma() and + (bpIteratorTail() and + bpPush bfCollect (bpPop2(),bpPop1()) or + bpPush bfTupleConstruct bpPop1()) + +bpDConstruct()==bpBracket function bpDConstruction + +bpDConstruction()== + bpComma() and + (bpIteratorTail() and + bpPush bfDCollect (bpPop2(),bpPop1()) or + bpPush bfDTuple bpPop1()) + + + +--PATTERN + +--bpNameOrDot() == bpName() or bpDot() or bpEqual() + +bpPattern()== bpBracketConstruct function bpPatternL + or bpName() or bpConstTok() + +bpEqual()== + bpEqKey "SHOEEQ" and (bpApplication() or bpConstTok() or + bpTrap()) and bpPush bfEqual bpPop1() + +bpRegularPatternItem() == + bpEqual() or + bpConstTok() or bpDot() or + bpName() and + ((bpEqKey "BEC" and (bpPattern() or bpTrap()) + and bpPush bfAssign(bpPop2(),bpPop1())) or true) + or bpBracketConstruct function bpPatternL + +bpRegularPatternItemL()== + bpRegularPatternItem() and bpPush [bpPop1()] + +bpRegularList()== + bpListof(function bpRegularPatternItemL,"COMMA",function bfAppend) + +bpPatternColon()== + bpEqKey "COLON" and (bpRegularPatternItem() or bpTrap()) + and bpPush [bfColon bpPop1()] + + +-- only one colon +bpPatternL() == bpPatternList() and bpPush bfTuple bpPop1() + +bpPatternList()== + if bpRegularPatternItemL() + then + while (bpEqKey "COMMA" and (bpRegularPatternItemL() or + (bpPatternTail() + and bpPush append(bpPop2(),bpPop1()) + or bpTrap();false) )) repeat + bpPush append(bpPop2(),bpPop1()) + true + else bpPatternTail() + +bpPatternTail()== + bpPatternColon() and + (bpEqKey "COMMA" and (bpRegularList() or bpTrap()) + and bpPush append (bpPop2(),bpPop1()) or true) + +-- BOUND VARIABLE +bpRegularBVItem() == + bpBVString() or + bpConstTok() or + (bpName() and + (bpEqKey "COLON" and (bpApplication() or bpTrap()) + and bpPush bfTagged(bpPop2(), bpPop1()) or + bpEqKey "BEC" and (bpPattern() or bpTrap()) + and bpPush bfAssign(bpPop2(),bpPop1()) or + (bpEqKey "IS" and (bpPattern() or bpTrap()) + and bpPush bfAssign(bpPop2(),bpPop1())) or true)) + or bpBracketConstruct function bpPatternL + +bpBVString()== + EQ(shoeTokType $stok,"STRING") and + bpPush(["BVQUOTE",INTERN $ttok]) and bpNext() + +bpRegularBVItemL() == + bpRegularBVItem() and bpPush [bpPop1()] + +bpColonName()== + bpEqKey "COLON" and (bpName() or bpBVString() or bpTrap()) + + +-- at most one colon at end +bpBoundVariablelist()== + if bpRegularBVItemL() + then + while (bpEqKey "COMMA" and (bpRegularBVItemL() or + (bpColonName() + and bpPush bfColonAppend(bpPop2(),bpPop1()) + or bpTrap();false) )) repeat + bpPush append(bpPop2(),bpPop1()) + true + else bpColonName() and bpPush bfColonAppend(nil,bpPop1()) + + +++ Mark the start of parameter list enclosed in round parenthesis +bpBeginParameterList() == + $sawParenthesizedHead := false + true + +++ Mark the end of parameter list enclosed in round parenthesis +bpEndParameterList() == + $sawParenthesizedHead := true + +bpVariable()== + bpBeginParameterList() and + bpParenthesized function bpBoundVariablelist and + bpPush bfTupleIf bpPop1() and bpEndParameterList() + or bpBracketConstruct function bpPatternL + or bpName() or bpConstTok() + +bpAssignVariable()== + bpBracketConstruct function bpPatternL or bpAssignLHS() + +bpAssignLHS()== + bpName() and (bpEqKey "COLON" and (bpApplication() or bpTrap()) + and bpPush bfLocal(bpPop2(),bpPop1()) + or bpEqKey "DOT" and bpList(function bpPrimary,"DOT", + function bfListOf) + and bpChecknull() and + bpPush bfTuple(cons(bpPop2(),bpPop1())) + or true) +bpChecknull()== + a:=bpPop1() + if null a + then bpTrap() + else bpPush a + +bpStruct()== + bpEqKey "STRUCTURE" and + (bpName() or bpTrap()) and + (bpEqKey "DEF" or bpTrap()) and + bpTypeList() and bpPush bfStruct(bpPop2(),bpPop1()) + +bpTypeList() == bpPileBracketed function bpTypeItemList + or bpTerm() and bpPush [bpPop1()] + +bpTypeItemList() == bpListAndRecover function bpTerm + +bpTerm() == + (bpName() or bpTrap()) and + ((bpParenthesized function bpIdList and + bpPush bfNameArgs (bpPop2(),bpPop1())) + or bpName() and bpPush bfNameArgs(bpPop2(),bpPop1())) + or bpPush(bfNameOnly bpPop1()) + +bpIdList()== bpTuple function bpName + +bpCase()== + bpEqKey "CASE" and + (bpWhere() or bpTrap()) and + (bpEqKey "OF" or bpMissing "OF") and + bpPiledCaseItems() + +bpPiledCaseItems()== + bpPileBracketed function bpCaseItemList and + bpPush bfCase(bpPop2(),bpPop1()) +bpCaseItemList()== + bpListAndRecover function bpCaseItem + +bpCaseItem()== + (bpTerm() or bpTrap()) and + (bpEqKey "EXIT" or bpTrap()) and + (bpWhere() or bpTrap()) and + bpPush bfCaseItem (bpPop2(),bpPop1()) + diff --git a/src/boot/pile.boot b/src/boot/pile.boot new file mode 100644 index 00000000..0b8b1651 --- /dev/null +++ b/src/boot/pile.boot @@ -0,0 +1,143 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +module '"boot-pile" +import '"includer" +import '"scanner" + +)package "BOOTTRAN" +shoeFirstTokPosn t== shoeTokPosn CAAR t +shoeLastTokPosn t== shoeTokPosn CADR t +shoePileColumn t==CDR shoeTokPosn CAAR t + +-- s is a token-dq-stream + +shoePileInsert (s)== + if bStreamNull s + then cons([],s) + else + toktype:=shoeTokType CAAAR s + if toktype ="LISP" or toktype = "LINE" + then cons([car s],cdr s) + else + a:=shoePileTree(-1,s) + cons([a.2],a.3) + +shoePileTree(n,s)== + if bStreamNull s + then [false,n,[],s] + else + [h,t]:=[car s,cdr s] + hh:=shoePileColumn h + if hh > n + then shoePileForests(h,hh,t) + else [false,n,[],s] + +eqshoePileTree(n,s)== + if bStreamNull s + then [false,n,[],s] + else + [h,t]:=[car s,cdr s] + hh:=shoePileColumn h + if hh = n + then shoePileForests(h,hh,t) + else [false,n,[],s] + +shoePileForest(n,s)== + [b,hh,h,t]:= shoePileTree(n,s) + if b + then + [h1,t1]:=shoePileForest1(hh,t) + [cons(h,h1),t1] + else [[],s] + +shoePileForest1(n,s)== + [b,n1,h,t]:= eqshoePileTree(n,s) + if b + then + [h1,t1]:=shoePileForest1(n,t) + [cons(h,h1),t1] + else [[],s] + +shoePileForests(h,n,s)== + [h1,t1]:=shoePileForest(n,s) + if bStreamNull h1 + then [true,n,h,s] + else shoePileForests(shoePileCtree(h,h1),n,t1) + +shoePileCtree(x,y)==dqAppend(x,shoePileCforest y) + +-- only enshoePiles forests with >=2 trees + +shoePileCforest x== + if null x + then [] + else if null cdr x + then car x + else + a:=car x + b:=shoePileCoagulate(a,rest x) + if null cdr b + then car b + else shoeEnPile shoeSeparatePiles b + +shoePileCoagulate(a,b)== + if null b + then [a] + else + c:=car b + if EQ(shoeTokPart CAAR c,"THEN") or EQ(shoeTokPart CAAR c,"ELSE") + then shoePileCoagulate (dqAppend(a,c),cdr b) + else + d:=CADR a + e:=shoeTokPart d + if EQCAR(d,"KEY") and + (GET(e,"SHOEINF") or EQ(e,"COMMA") or EQ(e,"SEMICOLON")) + then shoePileCoagulate(dqAppend(a,c),cdr b) + else cons(a,shoePileCoagulate(c,rest b)) + +shoeSeparatePiles x== + if null x + then [] + else if null cdr x + then car x + else + a:=car x + semicolon:=dqUnit + shoeTokConstruct("KEY", "BACKSET",shoeLastTokPosn a) + dqConcat [a,semicolon,shoeSeparatePiles cdr x] + +shoeEnPile x== + dqConcat [dqUnit shoeTokConstruct("KEY","SETTAB",shoeFirstTokPosn x), + x, _ + dqUnit shoeTokConstruct("KEY","BACKTAB",shoeLastTokPosn x)] + diff --git a/src/boot/scanner.boot b/src/boot/scanner.boot new file mode 100644 index 00000000..cd127781 --- /dev/null +++ b/src/boot/scanner.boot @@ -0,0 +1,514 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- All rights reserved. +-- Copyright (C) 2007-2008, Gabriel Dos Reis. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + + +module '"boot-lexer" +import '"tokens" +import '"includer" + +)package "BOOTTRAN" + +-- converts X to double-float. +double x == + FLOAT(x, 1.0) + +dqUnit s==(a:=[s];CONS(a,a)) + +dqAppend(x,y)== + if null x + then y + else if null y + then x + else + RPLACD (CDR x,CAR y) + RPLACD (x, CDR y) + x + +dqConcat ld== + if null ld + then nil + else if null rest ld + then first ld + else dqAppend(first ld,dqConcat rest ld) + +dqToList s==if null s then nil else CAR s + +shoeConstructToken(ln,lp,b,n)==[b.0,b.1,:cons(lp,n)] +shoeTokType x== CAR x +shoeTokPart x== CADR x +shoeTokPosn x== CDDR x +shoeTokConstruct(x,y,z)==[x,y,:z] + +shoeNextLine(s)== + if bStreamNull s + then false + else + $linepos:=s + $f:= CAR s + $r:= CDR s + $ln:=CAR $f + $n:=STRPOSL('" ",$ln,0,true) + $sz :=# $ln + null $n => true + QENUM($ln,$n)=shoeTAB => + a:=MAKE_-FULL_-CVEC (7-REM($n,8) ,'" ") + $ln.$n:='" ".0 + $ln:=CONCAT(a,$ln) + s1:=cons(cons($ln,CDR $f),$r) + shoeNextLine s1 + true + +shoeLineToks(s)== + $f: local:=nil + $r:local :=nil + $ln:local :=nil + $n:local:=nil + $sz:local := nil + $floatok:local:=true + $linepos:local:=s + not shoeNextLine s => CONS(nil,nil) + null $n => shoeLineToks $r + fst:=QENUM($ln,0) + EQL(fst,shoeCLOSEPAREN)=> + command:=shoeLine? $ln=> + dq:=dqUnit shoeConstructToken + ($ln,$linepos,shoeLeafLine command,0) + cons([dq],$r) + command:=shoeLisp? $ln=> shoeLispToken($r,command) + command:=shoePackage? $ln=> + -- z:=car shoeBiteOff command + a:=CONCAT('"(IN-PACKAGE ",command,'")") + dq:=dqUnit shoeConstructToken + ($ln,$linepos,shoeLeafLisp a,0) + cons([dq],$r) + shoeLineToks $r + toks:=[] + while $n<$sz repeat toks:=dqAppend(toks,shoeToken()) + null toks => shoeLineToks $r + cons([toks],$r) + +shoeLispToken(s,string)== + string:= + # string=0 or EQL(QENUM(string,0),QENUM('";",0))=> '"" + string + ln:=$ln + linepos:=$linepos + [r,:st]:=shoeAccumulateLines(s,string) + dq:=dqUnit shoeConstructToken(ln,linepos,shoeLeafLisp st,0) + cons([dq],r) + +shoeAccumulateLines(s,string)== + not shoeNextLine s => CONS(s,string) + null $n => shoeAccumulateLines($r,string) + # $ln=0 => shoeAccumulateLines($r,string) + fst:=QENUM($ln,0) + EQL(fst,shoeCLOSEPAREN)=> + command:=shoeLisp? $ln + command and #command>0 => + EQL(QENUM(command,0),QENUM('";",0))=> + shoeAccumulateLines($r,string) + a:=STRPOS('";",command,0,nil) + a=> + shoeAccumulateLines($r, + CONCAT(string,SUBSTRING(command,0,a-1))) + shoeAccumulateLines($r,CONCAT(string,command)) + shoeAccumulateLines($r,string) + CONS(s,string) + +-- returns true if token t is closing `parenthesis'. +shoeCloser t == + MEMQ(shoeKeyWord t, '(CPAREN CBRACK)) + +shoeToken () == + ln:=$ln + c:=QENUM($ln,$n) + linepos:=$linepos + n:=$n + ch:=$ln.$n + b:= + shoeStartsComment() => + shoeComment() + [] + shoeStartsNegComment() => + shoeNegComment() + [] + c=shoeLispESCAPE => + shoeLispEscape() + shoePunctuation c => shoePunct () + shoeStartsId ch => shoeWord (false) + c=shoeSPACE => + shoeSpace () + [] + c = shoeSTRING_CHAR => shoeString () + shoeDigit ch => shoeNumber () + c=shoeESCAPE => shoeEscape() + c=shoeTAB => + $n:=$n+1 + [] + shoeError () + null b => nil + dqUnit shoeConstructToken(ln,linepos,b,n) + +-- to pair badge and badgee +shoeLeafId x== ["ID",INTERN x] + +shoeLeafKey x==["KEY",shoeKeyWord x] + +shoeLeafInteger x==["INTEGER",shoeIntValue x] + +shoeLeafFloat(a,w,e)== + b:=shoeIntValue CONCAT(a,w) + c:= double b * EXPT(double 10, e-#w) + ["FLOAT",c] + +shoeLeafString x == ["STRING",x] + +shoeLeafLisp x == ["LISP",x] +shoeLeafLispExp x == ["LISPEXP",x] + +shoeLeafLine x == ["LINE",x] + +shoeLeafComment x == ["COMMENT", x] + +shoeLeafNegComment x== ["NEGCOMMENT", x] + +shoeLeafError x == ["ERROR",x] + +shoeLeafSpaces x == ["SPACES",x] + +shoeLispEscape()== + $n:=$n+1 + if $n>=$sz + then + SoftShoeError(cons($linepos,$n),'"lisp escape error") + shoeLeafError ($ln.$n) + else + a:=shoeReadLispString($ln,$n) + null a => + SoftShoeError(cons($linepos,$n),'"lisp escape error") + shoeLeafError ($ln.$n) + [exp,n]:=a + null n => + $n:= $sz + shoeLeafLispExp exp + $n:=n + shoeLeafLispExp exp +shoeEscape()== + $n:=$n+1 + a:=shoeEsc() + if a then shoeWord true else nil + +shoeEsc()== + if $n>=$sz + then if shoeNextLine($r) + then + while null $n repeat shoeNextLine($r) + shoeEsc() + false + else false + else + n1:=STRPOSL('" ",$ln,$n,true) + if null n1 + then + shoeNextLine($r) + while null $n repeat shoeNextLine($r) + shoeEsc() + false + else true + +shoeStartsComment()== + if $n<$sz + then + if QENUM($ln,$n)=shoePLUSCOMMENT + then + www:=$n+1 + if www>=$sz + then false + else QENUM($ln,www) = shoePLUSCOMMENT + else false + else false + +shoeStartsNegComment()== + if $n< $sz + then + if QENUM($ln,$n)=shoeMINUSCOMMENT + then + www:=$n+1 + if www>=$sz + then false + else QENUM($ln,www) = shoeMINUSCOMMENT + else false + else false + +shoeNegComment()== + n:=$n + $n:=$sz + shoeLeafNegComment SUBSTRING($ln,n,nil) + +shoeComment()== + n:=$n + $n:=$sz + shoeLeafComment SUBSTRING($ln,n,nil) + +shoePunct()== + sss:=shoeMatch($ln,$n) + $n:=$n+#sss + shoeKeyTr sss + +shoeKeyTr w== + if EQ(shoeKeyWord w,"DOT") + then if $floatok + then shoePossFloat(w) + else shoeLeafKey w + else + $floatok:=not shoeCloser w + shoeLeafKey w + +shoePossFloat (w)== + if $n>=$sz or not shoeDigit $ln.$n + then shoeLeafKey w + else + w:=shoeInteger() + shoeExponent('"0",w) + + +shoeSpace()== + n:=$n + $n:=STRPOSL('" ",$ln,$n,true) + $floatok:=true + if null $n + then + shoeLeafSpaces 0 + $n:= # $ln + else shoeLeafSpaces ($n-n) + +shoeString()== + $n:=$n+1 + $floatok:=false + shoeLeafString shoeS () + +shoeS()== + if $n>=$sz + then + SoftShoeError(cons($linepos,$n),'"quote added") + '"" + else + n:=$n + strsym :=STRPOS ('"_"",$ln,$n,nil) or $sz + escsym:=STRPOS ('"__" + ,$ln,$n,nil) or $sz + mn:=MIN(strsym,escsym) + if mn=$sz + then + $n:=$sz + SoftShoeError(cons($linepos,$n),'"quote added") + SUBSTRING($ln,n,nil) + else if mn=strsym + then + $n:=mn+1 + SUBSTRING($ln,n,mn-n) + else + str:=SUBSTRING($ln,n,mn-n) + $n:=mn+1 + a:=shoeEsc() + b:=if a + then + str:=CONCAT(str,$ln.$n) + $n:=$n+1 + shoeS() + else shoeS() + CONCAT(str,b) + + + + +shoeIdEnd(line,n)== + while n<#line and shoeIdChar line.n repeat n:=n+1 + n + + +shoeDigit x== DIGIT_-CHAR_-P x + +shoeW(b)== + n1:=$n + $n:=$n+1 + l:=$sz + endid:=shoeIdEnd($ln,$n) + if endid=l or QENUM($ln,endid)^=shoeESCAPE + then + $n:=endid + [b,SUBSTRING($ln,n1,endid-n1)] + else + str:=SUBSTRING($ln,n1,endid-n1) + $n:=endid+1 + a:=shoeEsc() + bb:=if a + then shoeW(true) + else [b,'""] -- escape finds space or newline + [bb.0 or b,CONCAT(str,bb.1)] + +shoeWord(esp) == + aaa:=shoeW(false) + w:=aaa.1 + $floatok:=false + if esp or aaa.0 + then shoeLeafId w + else if shoeKeyWordP w + then + $floatok:=true + shoeLeafKey w + else shoeLeafId w + +shoeInteger()==shoeInteger1(false) + +shoeInteger1(zro) == + n:=$n + l:= $sz + while $n<l and shoeDigit($ln.$n) repeat $n:=$n+1 + if $n=l or QENUM($ln,$n)^=shoeESCAPE + then if n=$n and zro + then '"0" + else SUBSTRING($ln,n,$n-n) + else + str:=SUBSTRING($ln,n,$n-n) + $n:=$n+1 + a:=shoeEsc() + bb:=shoeInteger1(zro) + CONCAT(str,bb) + +shoeIntValue(s) == + ns := #s + ival := 0 + for i in 0..ns-1 repeat + d := shoeOrdToNum ELT(s,i) + ival := 10*ival + d + ival + +shoeNumber() == + a := shoeInteger() + if $n>=$sz + then shoeLeafInteger a + else + if $floatok and QENUM($ln,$n)=shoeDOT + then + n:=$n + $n:=$n+1 + if $n<$sz and QENUM($ln,$n)=shoeDOT + then + $n:=n + shoeLeafInteger a + else + w:=shoeInteger1(true) + shoeExponent(a,w) + else shoeLeafInteger a + +shoeExponent(a,w)== + if $n>=$sz + then shoeLeafFloat(a,w,0) + else + n:=$n + c:=QENUM($ln,$n) + if c=shoeEXPONENT1 or c=shoeEXPONENT2 + then + $n:=$n+1 + if $n>=$sz + then + $n:=n + shoeLeafFloat(a,w,0) + else if shoeDigit($ln.$n) + then + e:=shoeInteger() + e:=shoeIntValue e + shoeLeafFloat(a,w,e) + else + c1:=QENUM($ln,$n) + if c1=shoePLUSCOMMENT or c1=shoeMINUSCOMMENT + then + $n:=$n+1 + if $n>=$sz + then + $n:=n + shoeLeafFloat(a,w,0) + else + if shoeDigit($ln.$n) + then + e:=shoeInteger() + e:=shoeIntValue e + shoeLeafFloat(a,w, + (if c1=shoeMINUSCOMMENT then MINUS e else e)) + else + $n:=n + shoeLeafFloat(a,w,0) + else shoeLeafFloat(a,w,0) + +shoeError()== + n:=$n + $n:=$n+1 + SoftShoeError(cons($linepos,n), + CONCAT( '"The character whose number is ", + STRINGIMAGE QENUM($ln,n),'" is not a Boot character")) + shoeLeafError ($ln.n) + +shoeOrdToNum x== DIGIT_-CHAR_-P x + +shoeKeyWord st == GETHASH(st,shoeKeyTable) + +shoeKeyWordP st == not null GETHASH(st,shoeKeyTable) + +shoeMatch(l,i)==shoeSubStringMatch(l,shoeDict,i) + +shoeSubStringMatch (l,d,i)== + h:= QENUM(l, i) + u:=ELT(d,h) + ll:=SIZE l + done:=false + s1:='"" + for j in 0.. SIZE u - 1 while not done repeat + s:=ELT(u,j) + ls:=SIZE s + done:=if ls+i > ll + then false + else + eql:= true + for k in 1..ls-1 while eql repeat + eql:= EQL(QENUM(s,k),QENUM(l,k+i)) + if eql + then + s1:=s + true + else false + s1 + +shoePunctuation c== shoePun.c =1 + diff --git a/src/boot/ast.boot.pamphlet b/src/boot/strap/ast.clisp index b0c2f483..591bd9bf 100644 --- a/src/boot/ast.boot.pamphlet +++ b/src/boot/strap/ast.clisp @@ -1,1118 +1,3 @@ -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/ast.boot} Pamphlet} -\author{The Axiom Team} - -\begin{document} -\maketitle -\begin{abstract} -\end{abstract} - -\tableofcontents -\eject - -Note that shoeReadLispString has a duplicate definition in this file. -I don't know why. I've commented out the first definition since it -gets overwritten. - -\section{License} - -<<license>>= --- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are --- met: --- --- - Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- - Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in --- the documentation and/or other materials provided with the --- distribution. --- --- - Neither the name of The Numerical ALgorithms Group Ltd. nor the --- names of its contributors may be used to endorse or promote products --- derived from this software without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -@ - -\section{Abstract syntax tree} - -<<abstract syntax tree>>= -++ A Boot string is no different from a Lisp string. Same holds -++ for symbols and sequences. In an ideal world, these would be -++ built-in/library data types. -String <=> STRING -Symbol <=> SYMBOL -Sequence <=> SEQUENCE - -++ Ideally, we would like to say that a List T if either nil or a -++ cons of a T and List of T. However, we don't support parameterized -++ alias definitions yet. -List <=> nil or cons - -++ Currently, the Boot processor uses Lisp symbol datatype for names. -++ That causes the BOOTTRAN package to contain more symbols than we would -++ like. In the future, we want want to intern `on demand'. How that -++ interacts with renaming is to be worked out. -structure Name == Name(Symbol) - -structure Ast == - Command(String) -- includer command - Module(String) -- module declaration - Import(String) -- import module - ImportSignature(Name, Signature) -- import function declaration - TypeAlias(Name, List, List) -- type alias definition - Signature(Name, Mapping) -- op: S -> T - Mapping(Ast, List) -- (S1, S2) -> T - SuffixDot(Ast) -- x . - Quote(Ast) -- 'x - EqualName(Name) -- =x -- patterns - Colon(Name) -- :x - QualifiedName(Name, Name) -- m::x - Bracket(Ast) -- [x, y] - UnboundedSegment(Ast) -- 3.. - BoundedSgement(Ast, Ast) -- 2..4 - Tuple(List) -- comma-separated expression sequence - ColonAppend(Ast, Ast) -- [:y] or [x, :y] - Is(Ast, Ast) -- e is p -- patterns - Isnt(Ast, Ast) -- e isnt p -- patterns - Reduce(Ast, Ast) -- +/[...] - PrefixExpr(Name, Ast) -- #v - Call(Ast, Sequence) -- f(x, y , z) - InfixExpr(Name, Ast, Ast) -- x + y - ConstantDefinition(Name, Ast) -- x == y - Definition(Name, List, Ast, Ast) -- f x == y - Macro(Name, List, Ast) -- m x ==> y - SuchThat(Ast) -- | p - Assignment(Ast, Ast) -- x := y - While(Ast) -- while p -- iterator - Until(Ast) -- until p -- iterator - For(Ast, Ast, Ast) -- for x in e by k -- iterator - Exit(Ast, Ast) -- p => x - Iterators(List) -- list of iterators - Cross(List) -- iterator cross product - Repeat(Sequence, Ast) -- while p repeat s - Pile(Sequence) -- pile of expression sequence - Append(Sequence) -- concatenate lists - Case(Ast, Sequence) -- case x of ... - Return(Ast) -- return x - Where(Ast, Sequence) -- e where f x == y - Structure(Ast, Sequence) -- structure Foo == ... -@ - - -\section{Putting it all together} -<<*>>= -<<license>> - -module '"boot-ast" -import '"includer" - -)package "BOOTTRAN" - -++ True means that Boot functions should be translated to use -++ hash tables to remember values. By default, functions are -++ translated with the obvious semantics, e.g. no caching. -$bfClamming := false - -<<abstract syntax tree>> - --- TRUE if we are currently building the syntax tree for an 'is' --- expression. -$inDefIS := false - -bfGenSymbol()== - $GenVarCounter:=$GenVarCounter+1 - INTERN(CONCAT ('"bfVar#",STRINGIMAGE $GenVarCounter)) - -bfListOf x==x - -bfColon x== ["COLON",x] - -bfColonColon(package, name) == - INTERN(SYMBOL_-NAME name, package) - -bfSymbol x== - STRINGP x=> x - ['QUOTE,x] - -bfDot()== "DOT" - -bfSuffixDot x==[x,"DOT"] - -bfEqual(name)== ["EQUAL",name] - -bfBracket(part) == part - -bfPile(part) == part - -bfAppend x== APPLY(function APPEND,x) - -bfColonAppend (x,y) == - if null x - then - if y is ["BVQUOTE",:a] - then ["&REST",["QUOTE",:a]] - else ["&REST",y] - else cons(CAR x,bfColonAppend(CDR x,y)) - -bfDefinition(bflhsitems, bfrhs,body) == - ['DEF,bflhsitems,bfrhs,body] - -bfMDefinition(bflhsitems, bfrhs,body) == - bfMDef('MDEF,bflhsitems,bfrhs,body) - -bfCompDef x == - case x of - ConstantDefinition(n, e) => x - otherwise => - x is [def, op, args, body] => - bfDef(def,op,args,body) - coreError '"invalid AST" - -bfBeginsDollar x== EQL('"$".0,(PNAME x).0) - -compFluid id== ["FLUID",id] - -compFluidize x== - IDENTP x and bfBeginsDollar x=>compFluid x - ATOM x =>x - EQCAR(x,"QUOTE")=>x - cons(compFluidize(CAR x),compFluidize(CDR x)) - -bfTuple x== ["TUPLE",:x] - -bfTupleP x==EQCAR(x,"TUPLE") - -bfTupleIf x== - if bfTupleP x - then x - else bfTuple x - -bfTupleConstruct b == - a:= if bfTupleP b - then cdr b - else [b] - or/[x is ["COLON",.] for x in a] => bfMakeCons a - ["LIST",:a] - -bfConstruct b == - a:= if bfTupleP b - then cdr b - else [b] - bfMakeCons a - -bfMakeCons l == - null l => NIL - l is [["COLON",a],:l1] => - l1 => ['APPEND,a,bfMakeCons l1] - a - ['CONS,first l,bfMakeCons rest l] - -bfFor(bflhs,U,step) == - if EQCAR (U,'tails) - then bfForTree('ON, bflhs, CADR U) - else - if EQCAR(U,"SEGMENT") - then bfSTEP(bflhs,CADR U,step,CADDR U) - else bfForTree('IN, bflhs, U) - -bfForTree(OP,lhs,whole)== - whole:=if bfTupleP whole then bfMakeCons cdr whole else whole - ATOM lhs =>bfINON [OP,lhs,whole] - lhs:=if bfTupleP lhs then CADR lhs else lhs - EQCAR(lhs,"L%T") => - G:=CADR lhs - [:bfINON [OP,G,whole],:bfSuchthat bfIS(G,CADDR lhs)] - G:=bfGenSymbol() - [:bfINON [OP,G,whole],:bfSuchthat bfIS(G,lhs)] - - -bfSTEP(id,fst,step,lst)== - initvar:=[id] - initval:=[fst] - inc:=if ATOM step - then step - else - g1:=bfGenSymbol() - initvar:=cons(g1,initvar) - initval:=cons(step,initval) - g1 - final:=if ATOM lst - then lst - else - g2:=bfGenSymbol() - initvar:=cons(g2,initvar) - initval:=cons(lst,initval) - g2 - ex:= - null lst=> [] - INTEGERP inc => - pred:=if MINUSP inc then "<" else ">" - [[pred,id,final]] - [['COND,[['MINUSP,inc], - ["<",id,final]],['T,[">",id,final]]]] - suc:=[['SETQ,id,["+",id,inc]]] - [[initvar,initval,suc,[],ex,[]]] - - -bfINON x== - [op,id,whole]:=x - if EQ(op,"ON") - then bfON(id,whole) - else bfIN(id,whole) - -bfIN(x,E)== - g:=bfGenSymbol() - [[[g,x],[E,nil],[['SETQ,g,['CDR, g]]],[], - [['OR,['ATOM,g],['PROGN,['SETQ,x,['CAR,g]] ,'NIL]]],[]]] - -bfON(x,E)== - [[[x],[E],[['SETQ,x,['CDR, x]]],[], - [['ATOM,x]],[]]] - -bfSuchthat p== [[[],[],[],[p],[],[]]] - -bfWhile p== [[[],[],[],[],[bfNOT p],[]]] - -bfUntil p== - g:=bfGenSymbol() - [[[g],[nil],[['SETQ,g,p]],[],[g],[]]] - -bfIterators x==["ITERATORS",:x] - -bfCross x== ["CROSS",:x] - -bfLp(iters,body)== - EQCAR (iters,"ITERATORS")=>bfLp1(CDR iters,body) - bfLpCross(CDR iters,body) - -bfLpCross(iters,body)== - if null cdr iters - then bfLp(car iters,body) - else bfLp(car iters,bfLpCross(cdr iters,body)) - -bfSep(iters)== - if null iters - then [[],[],[],[],[],[]] - else - f:=first iters - r:=bfSep rest iters - [append(i,j) for i in f for j in r] - -bfReduce(op,y)== - a:=if EQCAR(op,"QUOTE") then CADR op else op - op:=bfReName a - init:=GET(op,"SHOETHETA") - g:=bfGenSymbol() - g1:=bfGenSymbol() - body:=['SETQ,g,[op,g,g1]] - if null init - then - g2:=bfGenSymbol() - init:=['CAR,g2] - ny:=['CDR,g2] - it:= ["ITERATORS",:[[[[g],[init],[],[],[],[g]]],bfIN(g1,ny)]] - bfMKPROGN [['L%T,g2,y],bfLp(it,body)] - else - init:=car init - it:= ["ITERATORS",:[[[[g],[init],[],[],[],[g]]],bfIN(g1,y)]] - bfLp(it,body) - -bfReduceCollect(op,y)== - if EQCAR (y,"COLLECT") - then - body:=y.1 - itl:=y.2 - a:=if EQCAR(op,"QUOTE") then CADR op else op - op:=bfReName a - init:=GET(op,"SHOETHETA") - bfOpReduce(op,init,body,itl) - else - a:=bfTupleConstruct (y.1) - bfReduce(op,a) - --- delayed collect - -bfDCollect(y,itl)== ["COLLECT",y,itl] - -bfDTuple x== ["DTUPLE",x] - -bfCollect(y,itl) == - y is ["COLON",a] => bf0APPEND(a,itl) - y is ["TUPLE",:.] => - newBody:=bfConstruct y - bf0APPEND(newBody,itl) - bf0COLLECT(y,itl) - -bf0COLLECT(y,itl)==bfListReduce('CONS,y,itl) - - -bf0APPEND(y,itl)== - g:=bfGenSymbol() - body:=['SETQ,g,['APPEND,['REVERSE,y],g]] - extrait:= [[[g],[nil],[],[],[],[['NREVERSE,g]]]] - bfLp2(extrait,itl,body) - -bfListReduce(op,y,itl)== - g:=bfGenSymbol() - body:=['SETQ,g,[op,y,g]] - extrait:= [[[g],[nil],[],[],[],[['NREVERSE,g]]]] - bfLp2(extrait,itl,body) - -bfLp1(iters,body)== - [vars,inits,sucs,filters,exits,value]:=bfSep bfAppend iters - nbody:=if null filters then body else bfAND [:filters,body] - value:=if null value then "NIL" else car value - exits:= ["COND",[bfOR exits,["RETURN",value]], - ['(QUOTE T),nbody]] - loop := ["LOOP",exits,:sucs] - if vars then loop := - ["LET",[[v, i] for v in vars for i in inits], loop] - loop - -bfLp2(extrait,itl,body)== - EQCAR (itl,"ITERATORS")=>bfLp1(cons(extrait,CDR itl),body) - iters:=cdr itl - bfLpCross - ([["ITERATORS",extrait,:CDAR iters],:CDR iters],body) - -bfOpReduce(op,init,y,itl)== - g:=bfGenSymbol() - body:= - EQ(op,"AND")=> - bfMKPROGN [["SETQ",g,y], - ['COND, [['NOT,g],['RETURN,'NIL]]]] - EQ(op,"OR") => - bfMKPROGN [["SETQ",g,y], - ['COND, [g,['RETURN,g]]]] - ['SETQ,g,[op,g,y]] - if null init - then - g1:=bfGenSymbol() - init:=['CAR,g1] - y:=['CDR,g1] - extrait:= [[[g],[init],[],[],[],[g]]] - bfMKPROGN [['L%T,g1,y],bfLp2(extrait,itl,body)] - else - init:=car init - extrait:= [[[g],[init],[],[],[],[g]]] - bfLp2(extrait,itl,body) - -bfLoop1 body == bfLp (bfIterators nil,body) - -bfSegment1(lo)== ["SEGMENT",lo,nil] - -bfSegment2(lo,hi)== ["SEGMENT",lo,hi] - -bfForInBy(variable,collection,step)== - bfFor(variable,collection,step) - -bfForin(lhs,U)==bfFor(lhs,U,1) - -bfLocal(a,b)== - EQ(b,"FLUID")=> compFluid a - EQ(b,"fluid")=> compFluid a - EQ(b,"local") => compFluid a - -- $typings:=cons(["TYPE",b,a],$typings) - a - -bfTake(n,x)== - null x=>x - n=0 => nil - cons(car x,bfTake(n-1,cdr x)) - -bfDrop(n,x)== - null x or n=0 =>x - bfDrop(n-1,cdr x) - -bfDefSequence l == ['SEQ,: l] - -bfReturnNoName a == - ["RETURN",a] - -bfSUBLIS(p,e)== - ATOM e=>bfSUBLIS1(p,e) - EQCAR(e,"QUOTE")=>e - cons(bfSUBLIS(p,car e),bfSUBLIS(p,cdr e)) - -+++ Returns e/p, where e is an atom. We assume that the -+++ DEFs form a system admitting a fix point; otherwise we may -+++ loop forever. That can happen only if nullary goats -+++ are recursive -- which they are not supposed to be. -+++ We don't enforce that restriction though. -bfSUBLIS1(p,e)== - null p =>e - f:=CAR p - EQ(CAR f,e)=> bfSUBLIS(p, CDR f) - bfSUBLIS1(cdr p,e) - -defSheepAndGoats(x)== - EQCAR (x,"DEF") => - [def,op,args,body]:=x - argl:=if bfTupleP args - then cdr args - else [args] - if null argl - then - opassoc:=[[op,:body]] - [opassoc,[],[]] - else - op1:=INTERN CONCAT(PNAME $op,'",",PNAME op) - opassoc:=[[op,:op1]] - defstack:=[["DEF",op1,args,body]] - [opassoc,defstack,[]] - EQCAR (x,"SEQ") => defSheepAndGoatsList(cdr x) - [[],[],[x]] - -defSheepAndGoatsList(x)== - if null x - then [[],[],[]] - else - [opassoc,defs,nondefs] := defSheepAndGoats car x - [opassoc1,defs1,nondefs1] := defSheepAndGoatsList cdr x - [append(opassoc,opassoc1),append(defs,defs1), - append(nondefs,nondefs1)] ---% LET - -bfLetForm(lhs,rhs) == ['L%T,lhs,rhs] - -bfLET1(lhs,rhs) == - IDENTP lhs => bfLetForm(lhs,rhs) - lhs is ['FLUID,.] => bfLetForm(lhs,rhs) - IDENTP rhs and not bfCONTAINED(rhs,lhs) => - rhs1 := bfLET2(lhs,rhs) - EQCAR(rhs1,'L%T) => bfMKPROGN [rhs1,rhs] - EQCAR(rhs1,'PROGN) => APPEND(rhs1,[rhs]) - if IDENTP CAR rhs1 then rhs1 := CONS(rhs1,NIL) - bfMKPROGN [:rhs1,rhs] - CONSP(rhs) and EQCAR(rhs,'L%T) and IDENTP(name := CADR rhs) => - -- handle things like [a] := x := foo - l1 := bfLET1(name,CADDR rhs) - l2 := bfLET1(lhs,name) - EQCAR(l2,'PROGN) => bfMKPROGN [l1,:CDR l2] - if IDENTP CAR l2 then l2 := cons(l2,nil) - bfMKPROGN [l1,:l2,name] - g := INTERN CONCAT('"LETTMP#",STRINGIMAGE $letGenVarCounter) - $letGenVarCounter := $letGenVarCounter + 1 - rhs1 := ['L%T,g,rhs] - let1 := bfLET1(lhs,g) - EQCAR(let1,'PROGN) => bfMKPROGN [rhs1,:CDR let1] - if IDENTP CAR let1 then let1 := CONS(let1,NIL) - bfMKPROGN [rhs1,:let1,g] - -bfCONTAINED(x,y)== - EQ(x,y) => true - ATOM y=> false - bfCONTAINED(x,car y) or bfCONTAINED(x,cdr y) - -bfLET2(lhs,rhs) == - IDENTP lhs => bfLetForm(lhs,rhs) - NULL lhs => NIL - lhs is ['FLUID,.] => bfLetForm(lhs,rhs) - lhs is ['L%T,a,b] => - a := bfLET2(a,rhs) - null (b := bfLET2(b,rhs)) => a - ATOM b => [a,b] - CONSP CAR b => CONS(a,b) - [a,b] - lhs is ['CONS,var1,var2] => - var1 = "DOT" or (CONSP(var1) and EQCAR(var1,'QUOTE)) => - bfLET2(var2,addCARorCDR('CDR,rhs)) - l1 := bfLET2(var1,addCARorCDR('CAR,rhs)) - null var2 or EQ(var2,"DOT") =>l1 - if CONSP l1 and ATOM CAR l1 then l1 := cons(l1,nil) - IDENTP var2 => - [:l1,bfLetForm(var2,addCARorCDR('CDR,rhs))] - l2 := bfLET2(var2,addCARorCDR('CDR,rhs)) - if CONSP l2 and ATOM CAR l2 then l2 := cons(l2,nil) - APPEND(l1,l2) - lhs is ['APPEND,var1,var2] => - patrev := bfISReverse(var2,var1) - rev := ['REVERSE,rhs] - g := INTERN CONCAT('"LETTMP#", STRINGIMAGE $letGenVarCounter) - $letGenVarCounter := $letGenVarCounter + 1 - l2 := bfLET2(patrev,g) - if CONSP l2 and ATOM CAR l2 then l2 := cons(l2,nil) - var1 = "DOT" => [['L%T,g,rev],:l2] - last l2 is ['L%T, =var1, val1] => - [['L%T,g,rev],:REVERSE CDR REVERSE l2, - bfLetForm(var1,['NREVERSE,val1])] - [['L%T,g,rev],:l2,bfLetForm(var1,['NREVERSE,var1])] - lhs is ["EQUAL",var1] => - ['COND,[["EQUAL",var1,rhs],var1]] - -- The original expression may be one that involves literals as - -- sub-patterns, e.g. - -- ['SEQ, :l, ['exit, 1, x]] := item - -- We continue the processing as if that expression had been written - -- item is ['SEQ, :l, ['exit, 1, x]] - -- and generate appropriate codes. - -- -- gdr/2007-04-02. - isPred := - $inDefIS => bfIS1(rhs,lhs) - bfIS(rhs,lhs) - ['COND,[isPred,rhs]] - - -bfLET(lhs,rhs) == - $letGenVarCounter : local := 1 --- $inbfLet : local := true - bfLET1(lhs,rhs) - -addCARorCDR(acc,expr) == - NULL CONSP expr => [acc,expr] - acc = 'CAR and EQCAR(expr,'REVERSE) => - ["CAR",["LAST",:CDR expr]] - -- cons('last,CDR expr) - funs := '(CAR CDR CAAR CDAR CADR CDDR CAAAR CADAR CAADR CADDR - CDAAR CDDAR CDADR CDDDR) - p := bfPosition(CAR expr,funs) - p = -1 => [acc,expr] - funsA := '(CAAR CADR CAAAR CADAR CAADR CADDR CAAAAR CAADAR CAAADR - CAADDR CADAAR CADDAR CADADR CADDDR) - funsR := '(CDAR CDDR CDAAR CDDAR CDADR CDDDR CDAAAR CDADAR CDAADR - CDADDR CDDAAR CDDDAR CDDADR CDDDDR) - if acc = 'CAR then CONS(funsA.p,CDR expr) - else CONS(funsR.p,CDR expr) - -bfPosition(x,l) == bfPosn(x,l,0) -bfPosn(x,l,n) == - null l => -1 - x=first l => n - bfPosn(x,rest l,n+1) - ---% IS - -bfISApplication(op,left,right)== - EQ(op ,"IS") => bfIS(left,right) - EQ(op ,"ISNT") => bfNOT bfIS(left,right) - [op ,left,right] - -bfIS(left,right)== - $isGenVarCounter:local :=1 - $inDefIS :local :=true - bfIS1(left,right) - -bfISReverse(x,a) == - x is ['CONS,:.] => - NULL CADDR x => ['CONS,CADR x, a] - y := bfISReverse(CADDR x, NIL) - RPLACA(CDDR y,['CONS,CADR x,a]) - y - bpSpecificErrorHere '"Error in bfISReverse" - bpTrap() - -bfIS1(lhs,rhs) == - NULL rhs => - ['NULL,lhs] - STRINGP rhs => - ['EQ,lhs,['QUOTE,INTERN rhs]] - NUMBERP rhs => - ["EQUAL",lhs,rhs] - ATOM rhs => - ['PROGN,bfLetForm(rhs,lhs),''T] - rhs is ['QUOTE,a] => - IDENTP a => ['EQ,lhs,rhs] - ["EQUAL",lhs,rhs] - rhs is ['L%T,c,d] => - l := - bfLET(c,lhs) --- $inbfLet => bfLET1(c,lhs) --- bfLET(c,lhs) - bfAND [bfIS1(lhs,d),bfMKPROGN [l,''T]] - rhs is ["EQUAL",a] => - ["EQUAL",lhs,a] - CONSP lhs => - g := INTERN CONCAT('"ISTMP#",STRINGIMAGE $isGenVarCounter) - $isGenVarCounter := $isGenVarCounter + 1 - bfMKPROGN [['L%T,g,lhs],bfIS1(g,rhs)] - rhs is ['CONS,a,b] => - a = "DOT" => - NULL b => - bfAND [['CONSP,lhs], - ['EQ,['CDR,lhs],'NIL]] - bfAND [['CONSP,lhs], - bfIS1(['CDR,lhs],b)] - NULL b => - bfAND [['CONSP,lhs], - ['EQ,['CDR,lhs],'NIL],_ - bfIS1(['CAR,lhs],a)] - b = "DOT" => - bfAND [['CONSP,lhs],bfIS1(['CAR,lhs],a)] - a1 := bfIS1(['CAR,lhs],a) - b1 := bfIS1(['CDR,lhs],b) - a1 is ['PROGN,c,''T] and b1 is ['PROGN,:cls] => - bfAND [['CONSP,lhs],bfMKPROGN [c,:cls]] - bfAND [['CONSP,lhs],a1,b1] - rhs is ['APPEND,a,b] => - patrev := bfISReverse(b,a) - g := INTERN CONCAT('"ISTMP#",STRINGIMAGE $isGenVarCounter) - $isGenVarCounter := $isGenVarCounter + 1 - rev := bfAND [['CONSP,lhs],['PROGN,['L%T,g,['REVERSE,lhs]],''T]] - l2 := bfIS1(g,patrev) - if CONSP l2 and ATOM CAR l2 then l2 := cons(l2,nil) - a = "DOT" => bfAND [rev,:l2] - bfAND [rev,:l2,['PROGN,bfLetForm(a,['NREVERSE,a]),''T]] - bpSpecificErrorHere '"bad IS code is generated" - bpTrap() - -bfApplication(bfop, bfarg) == - if bfTupleP bfarg - then cons(bfop,CDR bfarg) - else cons(bfop,[bfarg]) - - -++ Token renaming. New Boot and Old Boot differs in the set of -++ tokens they rename. When converting code written in Old Boot -++ to New Boot, it is helpful to have some noise about potential -++ divergence in semantics. So, when compiling with --boot=old, -++ we compute the renaming in both Old Boot and New Boot and compare -++ the results. If they differ, we prefer the old meaning, with some -++ warnings. Notice that the task is compounded by the fact the -++ tokens in both language do not always agreee. -++ However, to minimize the flood of false positive, we -++ keep a list of symbols which apparently differ in meanings, but -++ which have been verified to agree. -++ This is a valuable automated tool during the transition period. - --- return the meaning of the x in Old Boot. -bfGetOldBootName x == - a := GET(x, "OLD-BOOT") => car a - x - --- returns true if x has same meaning in both Old Boot and New Boot. -bfSameMeaning x == - GET(x, 'RENAME_-OK) - --- returns the meaning of x in the appropriate Boot dialect. -bfReName x== - newName := - a := GET(x,"SHOERENAME") => car a - x - $translatingOldBoot and not bfSameMeaning x => - oldName := bfGetOldBootName x - if newName ^= oldName then - warn [PNAME x, '" as `", PNAME newName, _ - '"_' differs from Old Boot `", PNAME oldName, '"_'"] - oldName - newName - - -bfInfApplication(op,left,right)== - EQ(op,"EQUAL") => bfQ(left,right) - EQ(op,"/=") => bfNOT bfQ(left,right) - EQ(op,">") => bfLessp(right,left) - EQ(op,"<") => bfLessp(left,right) - EQ(op,"<=") => bfNOT bfLessp(right,left) - EQ(op,">=") => bfNOT bfLessp(left,right) - EQ(op,"OR") => bfOR [left,right] - EQ(op,"AND") => bfAND [left,right] - [op,left,right] - -bfNOT x== - x is ["NOT",a]=> a - x is ["NULL",a]=> a - ["NOT",x] - -bfFlatten(op, x) == - EQCAR(x,op) => CDR x - [x] - -bfOR l == - null l => NIL - null cdr l => CAR l - ["OR",:[:bfFlatten("OR",c) for c in l]] - -bfAND l == - null l=> 'T - null cdr l => CAR l - ["AND",:[:bfFlatten("AND",c) for c in l]] - - -defQuoteId x== EQCAR(x,"QUOTE") and IDENTP CADR x - -bfSmintable x== - INTEGERP x or CONSP x and - MEMQ(CAR x, '(SIZE LENGTH)) - -bfQ(l,r)== - if bfSmintable l or bfSmintable r - then ["EQL",l,r] - else if defQuoteId l or defQuoteId r - then ["EQ",l,r] - else - if null l - then ["NULL",r] - else if null r - then ["NULL",l] - else ["EQUAL",l,r] - -bfLessp(l,r)== - if r=0 - then ["MINUSP", l] - else ["<",l,r] - -bfMDef (defOp,op,args,body) == - argl:=if bfTupleP args then cdr args else [args] - [gargl,sgargl,nargl,largl]:=bfGargl argl - sb:=[cons(i,j) for i in nargl for j in sgargl] - body:= SUBLIS(sb,body) - sb2 := [["CONS",["QUOTE",i],j] for i in sgargl for j in largl] - body := ["SUBLIS",["LIST",:sb2],["QUOTE",body]] - lamex:= ["MLAMBDA",gargl,body] - def:= [op,lamex] - bfTuple - cons(shoeComp def,[:shoeComps bfDef1 d for d in $wheredefs]) - -bfGargl argl== - if null argl - then [[],[],[],[]] - else - [a,b,c,d]:=bfGargl cdr argl - if car argl="&REST" - then [cons(car argl,b),b,c, - cons(["CONS",["QUOTE","LIST"],car d],cdr d)] - else - f:=bfGenSymbol() - [cons(f,a),cons(f,b),cons(car argl,c),cons(f,d)] - -bfDef1 [defOp,op,args,body] == - argl:=if bfTupleP args then cdr args else [args] - [quotes,control,arglp,body]:=bfInsertLet (argl,body) - quotes=>shoeLAM(op,arglp,control,body) - [[op,["LAMBDA",arglp,body]]] - -shoeLAM (op,args,control,body)== - margs :=bfGenSymbol() - innerfunc:=INTERN(CONCAT(PNAME op,",LAM")) - [[innerfunc,["LAMBDA",args,body]], - [op,["MLAMBDA",["&REST",margs],["CONS",["QUOTE", innerfunc], - ["WRAP",margs, ["QUOTE", control]]]]]] - -bfDef(defOp,op,args,body) == - $bfClamming => - [.,op1,arg1,:body1]:=shoeComp first bfDef1 [defOp,op,args,body] - bfCompHash(op1,arg1,body1) - bfTuple - [:shoeComps bfDef1 d for d in cons([defOp,op,args,body],$wheredefs)] - -shoeComps x==[shoeComp def for def in x] -shoeComp x== - a:=shoeCompTran CADR x - if EQCAR(a,"LAMBDA") - then ["DEFUN",CAR x,CADR a,:CDDR a] - else ["DEFMACRO",CAR x,CADR a,:CDDR a] - -bfInsertLet(x,body)== - if null x - then [false,nil,x,body] - else - if x is ["&REST",a] - then if a is ["QUOTE",b] - then [true,"QUOTE",["&REST",b],body] - else [false,nil,x,body] - else - [b,norq,name1,body1]:= bfInsertLet1 (car x,body) - [b1,norq1,name2,body2]:= bfInsertLet (cdr x,body1) - [b or b1,cons(norq,norq1),cons(name1,name2),body2] - -bfInsertLet1(y,body)== - if y is ["L%T",l,r] - then [false,nil,l,bfMKPROGN [bfLET(r,l),body]] - else if IDENTP y - then [false,nil,y,body] - else - if y is ["BVQUOTE",b] - then [true,"QUOTE",b,body] - else - g:=bfGenSymbol() - ATOM y => [false,nil,g,body] - [false,nil,g,bfMKPROGN [bfLET(compFluidize y,g),body]] - -shoeCompTran x== - lamtype:=CAR x - args :=CADR x - body :=CDDR x - $fluidVars:local:=nil - $locVars:local:=nil - $dollarVars:local:=nil - shoeCompTran1 body - $locVars:=SETDIFFERENCE(SETDIFFERENCE($locVars, - $fluidVars),shoeATOMs args) - body:= - if $fluidVars or $locVars or $dollarVars or $typings - then - lvars:=append($fluidVars,$locVars) - $fluidVars:=UNION($fluidVars,$dollarVars) - if null $fluidVars - then - null $typings=> shoePROG(lvars,body) - shoePROG(lvars,[["DECLARE",:$typings],:body]) - else - fvars:=["DECLARE",["SPECIAL",:$fluidVars]] - null $typings => shoePROG(lvars,[fvars,:body]) - shoePROG(lvars,[fvars,["DECLARE",:$typings],:body]) - else shoePROG([], body) - fl:=shoeFluids args - body:=if fl - then - fvs:=["DECLARE",["SPECIAL",:fl]] - cons(fvs,body) - else body - [lamtype,args, :body] - -shoePROG(v,b)== - null b => [["PROG", v]] - [:blist,blast] := b - [["PROG",v,:blist,["RETURN", blast]]] - -shoeFluids x== - if null x - then nil - else if IDENTP x and bfBeginsDollar x - then [x] - else - if EQCAR(x,"QUOTE") - then [] - else - if ATOM x - then nil - else append(shoeFluids car x,shoeFluids cdr x) -shoeATOMs x== - if null x - then nil - else if ATOM x - then [x] - else append(shoeATOMs car x,shoeATOMs cdr x) - -shoeCompTran1 x== - ATOM x=> - IDENTP x and bfBeginsDollar x=> - $dollarVars:= - MEMQ(x,$dollarVars)=>$dollarVars - cons(x,$dollarVars) - nil - U:=car x - EQ(U,"QUOTE")=>nil - x is ["L%T",l,r]=> - RPLACA (x,"SETQ") - shoeCompTran1 r - IDENTP l => - not bfBeginsDollar l=> - $locVars:= - MEMQ(l,$locVars)=>$locVars - cons(l,$locVars) - $dollarVars:= - MEMQ(l,$dollarVars)=>$dollarVars - cons(l,$dollarVars) - EQCAR(l,"FLUID")=> - $fluidVars:= - MEMQ(CADR l,$fluidVars)=>$fluidVars - cons(CADR l,$fluidVars) - RPLACA (CDR x,CADR l) - MEMQ(U,'(PROG LAMBDA))=> - newbindings:=nil - for y in CADR x repeat - not MEMQ(y,$locVars)=> - $locVars:=cons(y,$locVars) - newbindings:=cons(y,newbindings) - res:=shoeCompTran1 CDDR x - $locVars:=[y for y in $locVars | not MEMQ(y,newbindings)] - shoeCompTran1 car x - shoeCompTran1 cdr x - -bfTagged(a,b)== - IDENTP a => - EQ(b,"FLUID") => bfLET(compFluid a,NIL) - EQ(b,"fluid") => bfLET(compFluid a,NIL) - EQ(b,"local") => bfLET(compFluid a,NIL) - $typings:=cons(["TYPE",b,a],$typings) - a - ["THE",b,a] - -bfAssign(l,r)== - if bfTupleP l then bfSetelt(CADR l,CDDR l ,r) else bfLET(l,r) - -bfSetelt(e,l,r)== - if null cdr l - then defSETELT(e,car l,r) - else bfSetelt(bfElt(e,car l),cdr l,r) - -bfElt(expr,sel)== - y:=SYMBOLP sel and GET(sel,"SHOESELFUNCTION") - y=> - INTEGERP y => ["ELT",expr,y] - [y,expr] - ["ELT",expr,sel] - -defSETELT(var,sel,expr)== - y:=SYMBOLP sel and GET(sel,"SHOESELFUNCTION") - y=> - INTEGERP y => ["SETF",["ELT",var,y],expr] - ["SETF",[y,var],expr] - ["SETF",["ELT",var,sel],expr] - -bfIfThenOnly(a,b)== - b1:=if EQCAR (b,"PROGN") then CDR b else [b] - ["COND",[a,:b1]] - -bfIf(a,b,c)== - b1:=if EQCAR (b,"PROGN") then CDR b else [b] - EQCAR (c,"COND") => ["COND",[a,:b1],:CDR c] - c1:=if EQCAR (c,"PROGN") then CDR c else [c] - ["COND",[a,:b1],['(QUOTE T),:c1]] - -bfExit(a,b)== ["COND",[a,["IDENTITY",b]]] - -bfMKPROGN l== - a:=[:bfFlattenSeq c for c in tails l] - null a=> nil - null CDR a=> CAR a - ["PROGN",:a] - -bfFlattenSeq x == - null x=>NIL - f:=CAR x - ATOM f =>if CDR x then nil else [f] - EQCAR(f,"PROGN") => - CDR x=> [i for i in CDR f| not ATOM i] - CDR f - [f] - -bfSequence l == - null l=> NIL - transform:= [[a,b] for x in l while - x is ["COND",[a,["IDENTITY",b]]]] - no:=#transform - before:= bfTake(no,l) - aft := bfDrop(no,l) - null before => - null rest l => - f:=first l - if EQCAR(f,"PROGN") - then bfSequence CDR f - else f - bfMKPROGN [first l,bfSequence rest l] - null aft => ["COND",:transform] - ["COND",:transform,['(QUOTE T),bfSequence aft]] - -bfWhere (context,expr)== - [opassoc,defs,nondefs] := defSheepAndGoats context - a:=[[def,op,args,bfSUBLIS(opassoc,body)] - for d in defs |d is [def,op,args,body]] - $wheredefs:=append(a,$wheredefs) - bfMKPROGN bfSUBLIS(opassoc,NCONC(nondefs,[expr])) - ---shoeReadLispString(s,n)== --- n>= # s => nil --- [exp,ind]:=shoeReadLisp(s,n) --- null exp => nil --- cons(exp,shoeReadLispString(s,ind)) - -bfReadLisp string==bfTuple shoeReadLispString (string,0) - -bfCompHash(op,argl,body) == - auxfn:= INTERN CONCAT (PNAME op,'";") - computeFunction:= ["DEFUN",auxfn,argl,:body] - bfTuple [computeFunction,:bfMain(auxfn,op)] - -shoeCompileTimeEvaluation x == - ["EVAL-WHEN", [KEYWORD::COMPILE_-TOPLEVEL], x] - -shoeEVALANDFILEACTQ x== - ["EVAL-WHEN", [KEYWORD::EXECUTE, KEYWORD::LOAD_-TOPLEVEL], x] - -bfMain(auxfn,op)== - g1:= bfGenSymbol() - arg:=["&REST",g1] - computeValue := ['APPLY,["FUNCTION",auxfn],g1] - cacheName:= INTERN CONCAT (PNAME op,'";AL") - g2:= bfGenSymbol() - getCode:= ['GETHASH,g1,cacheName] - secondPredPair:= [['SETQ,g2,getCode],g2] - putCode:= ['SETF ,getCode,computeValue] - thirdPredPair:= ['(QUOTE T),putCode] - codeBody:= ['PROG,[g2], - ['RETURN,['COND,secondPredPair,thirdPredPair]]] - mainFunction:= ["DEFUN",op,arg,codeBody] - - cacheType:= 'hash_-table - cacheResetCode:= ['SETQ,cacheName,['MAKE_-HASHTABLE, - ["QUOTE","UEQUAL"]]] - cacheCountCode:= ['hashCount,cacheName] - cacheVector:= - [op,cacheName,cacheType,cacheResetCode,cacheCountCode] - [mainFunction, - shoeEVALANDFILEACTQ - ["SETF",["GET", - ["QUOTE", op],["QUOTE",'cacheInfo]],["QUOTE", cacheVector]], - shoeEVALANDFILEACTQ cacheResetCode ] - -bfNameOnly x== - if x="t" - then ["T"] - else [x] - -bfNameArgs (x,y)== - y:=if EQCAR(y,"TUPLE") then CDR y else [y] - cons(x,y) - -bfStruct(name,arglist)== - bfTuple [bfCreateDef i for i in arglist] - -bfCreateDef x== - if null cdr x - then - f:=car x - ["SETQ",f,["LIST",["QUOTE",f]]] - else - a:=[bfGenSymbol() for i in cdr x] - ["DEFUN",car x,a,["CONS",["QUOTE",car x],["LIST",:a]]] - -bfCaseItem(x,y)==[x,y] - -bfCase(x,y)== - g:=bfGenSymbol() - g1:=bfGenSymbol() - a:=bfLET(g,x) - b:=bfLET(g1,["CDR",g]) - c:=bfCaseItems (g1,y) - bfMKPROGN [a,b,["CASE",["CAR", g],:c]] - -bfCaseItems(g,x)== [bfCI(g,i,j) for [i,j] in x] - -bfCI(g,x,y)== - a:=cdr x - if null a - then [car x,y] - else - b:=[[i,bfCARCDR(j,g)] for i in a for j in 0..] - [car x,["LET",b,y]] - -bfCARCDR (n,g)==[INTERN CONCAT ('"CA",bfDs n,'"R"),g] - -bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) - -@ - -<<ast.clisp>>= (EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-ast")) (IMPORT-MODULE "includer") @@ -1137,90 +22,99 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (DEFUN |Import| #0=(|bfVar#4|) (CONS '|Import| (LIST . #0#))) -(DEFUN |TypeAlias| #0=(|bfVar#5| |bfVar#6| |bfVar#7|) +(DEFUN |ImportSignature| #0=(|bfVar#5| |bfVar#6|) + (CONS '|ImportSignature| (LIST . #0#))) + +(DEFUN |TypeAlias| #0=(|bfVar#7| |bfVar#8| |bfVar#9|) (CONS '|TypeAlias| (LIST . #0#))) -(DEFUN |SuffixDot| #0=(|bfVar#8|) (CONS '|SuffixDot| (LIST . #0#))) +(DEFUN |Signature| #0=(|bfVar#10| |bfVar#11|) + (CONS '|Signature| (LIST . #0#))) + +(DEFUN |Mapping| #0=(|bfVar#12| |bfVar#13|) + (CONS '|Mapping| (LIST . #0#))) -(DEFUN |Quote| #0=(|bfVar#9|) (CONS '|Quote| (LIST . #0#))) +(DEFUN |SuffixDot| #0=(|bfVar#14|) (CONS '|SuffixDot| (LIST . #0#))) -(DEFUN |EqualName| #0=(|bfVar#10|) (CONS '|EqualName| (LIST . #0#))) +(DEFUN |Quote| #0=(|bfVar#15|) (CONS '|Quote| (LIST . #0#))) -(DEFUN |Colon| #0=(|bfVar#11|) (CONS '|Colon| (LIST . #0#))) +(DEFUN |EqualName| #0=(|bfVar#16|) (CONS '|EqualName| (LIST . #0#))) -(DEFUN |QualifiedName| #0=(|bfVar#12| |bfVar#13|) +(DEFUN |Colon| #0=(|bfVar#17|) (CONS '|Colon| (LIST . #0#))) + +(DEFUN |QualifiedName| #0=(|bfVar#18| |bfVar#19|) (CONS '|QualifiedName| (LIST . #0#))) -(DEFUN |Bracket| #0=(|bfVar#14|) (CONS '|Bracket| (LIST . #0#))) +(DEFUN |Bracket| #0=(|bfVar#20|) (CONS '|Bracket| (LIST . #0#))) -(DEFUN |UnboundedSegment| #0=(|bfVar#15|) +(DEFUN |UnboundedSegment| #0=(|bfVar#21|) (CONS '|UnboundedSegment| (LIST . #0#))) -(DEFUN |BoundedSgement| #0=(|bfVar#16| |bfVar#17|) +(DEFUN |BoundedSgement| #0=(|bfVar#22| |bfVar#23|) (CONS '|BoundedSgement| (LIST . #0#))) -(DEFUN |Tuple| #0=(|bfVar#18|) (CONS '|Tuple| (LIST . #0#))) +(DEFUN |Tuple| #0=(|bfVar#24|) (CONS '|Tuple| (LIST . #0#))) -(DEFUN |ColonAppend| #0=(|bfVar#19| |bfVar#20|) +(DEFUN |ColonAppend| #0=(|bfVar#25| |bfVar#26|) (CONS '|ColonAppend| (LIST . #0#))) -(DEFUN |Is| #0=(|bfVar#21| |bfVar#22|) (CONS '|Is| (LIST . #0#))) +(DEFUN |Is| #0=(|bfVar#27| |bfVar#28|) (CONS '|Is| (LIST . #0#))) -(DEFUN |Isnt| #0=(|bfVar#23| |bfVar#24|) (CONS '|Isnt| (LIST . #0#))) +(DEFUN |Isnt| #0=(|bfVar#29| |bfVar#30|) (CONS '|Isnt| (LIST . #0#))) -(DEFUN |Reduce| #0=(|bfVar#25| |bfVar#26|) +(DEFUN |Reduce| #0=(|bfVar#31| |bfVar#32|) (CONS '|Reduce| (LIST . #0#))) -(DEFUN |PrefixExpr| #0=(|bfVar#27| |bfVar#28|) +(DEFUN |PrefixExpr| #0=(|bfVar#33| |bfVar#34|) (CONS '|PrefixExpr| (LIST . #0#))) -(DEFUN |Call| #0=(|bfVar#29| |bfVar#30|) (CONS '|Call| (LIST . #0#))) +(DEFUN |Call| #0=(|bfVar#35| |bfVar#36|) (CONS '|Call| (LIST . #0#))) -(DEFUN |InfixExpr| #0=(|bfVar#31| |bfVar#32| |bfVar#33|) +(DEFUN |InfixExpr| #0=(|bfVar#37| |bfVar#38| |bfVar#39|) (CONS '|InfixExpr| (LIST . #0#))) -(DEFUN |ConstantDefinition| #0=(|bfVar#34| |bfVar#35|) +(DEFUN |ConstantDefinition| #0=(|bfVar#40| |bfVar#41|) (CONS '|ConstantDefinition| (LIST . #0#))) -(DEFUN |Definition| #0=(|bfVar#36| |bfVar#37| |bfVar#38| |bfVar#39|) +(DEFUN |Definition| #0=(|bfVar#42| |bfVar#43| |bfVar#44| |bfVar#45|) (CONS '|Definition| (LIST . #0#))) -(DEFUN |Macro| #0=(|bfVar#40| |bfVar#41| |bfVar#42|) +(DEFUN |Macro| #0=(|bfVar#46| |bfVar#47| |bfVar#48|) (CONS '|Macro| (LIST . #0#))) -(DEFUN |SuchThat| #0=(|bfVar#43|) (CONS '|SuchThat| (LIST . #0#))) +(DEFUN |SuchThat| #0=(|bfVar#49|) (CONS '|SuchThat| (LIST . #0#))) -(DEFUN |Assignment| #0=(|bfVar#44| |bfVar#45|) +(DEFUN |Assignment| #0=(|bfVar#50| |bfVar#51|) (CONS '|Assignment| (LIST . #0#))) -(DEFUN |While| #0=(|bfVar#46|) (CONS '|While| (LIST . #0#))) +(DEFUN |While| #0=(|bfVar#52|) (CONS '|While| (LIST . #0#))) -(DEFUN |Until| #0=(|bfVar#47|) (CONS '|Until| (LIST . #0#))) +(DEFUN |Until| #0=(|bfVar#53|) (CONS '|Until| (LIST . #0#))) -(DEFUN |For| #0=(|bfVar#48| |bfVar#49| |bfVar#50|) +(DEFUN |For| #0=(|bfVar#54| |bfVar#55| |bfVar#56|) (CONS '|For| (LIST . #0#))) -(DEFUN |Exit| #0=(|bfVar#51| |bfVar#52|) (CONS '|Exit| (LIST . #0#))) +(DEFUN |Exit| #0=(|bfVar#57| |bfVar#58|) (CONS '|Exit| (LIST . #0#))) -(DEFUN |Iterators| #0=(|bfVar#53|) (CONS '|Iterators| (LIST . #0#))) +(DEFUN |Iterators| #0=(|bfVar#59|) (CONS '|Iterators| (LIST . #0#))) -(DEFUN |Cross| #0=(|bfVar#54|) (CONS '|Cross| (LIST . #0#))) +(DEFUN |Cross| #0=(|bfVar#60|) (CONS '|Cross| (LIST . #0#))) -(DEFUN |Repeat| #0=(|bfVar#55| |bfVar#56|) +(DEFUN |Repeat| #0=(|bfVar#61| |bfVar#62|) (CONS '|Repeat| (LIST . #0#))) -(DEFUN |Pile| #0=(|bfVar#57|) (CONS '|Pile| (LIST . #0#))) +(DEFUN |Pile| #0=(|bfVar#63|) (CONS '|Pile| (LIST . #0#))) -(DEFUN |Append| #0=(|bfVar#58|) (CONS '|Append| (LIST . #0#))) +(DEFUN |Append| #0=(|bfVar#64|) (CONS '|Append| (LIST . #0#))) -(DEFUN |Case| #0=(|bfVar#59| |bfVar#60|) (CONS '|Case| (LIST . #0#))) +(DEFUN |Case| #0=(|bfVar#65| |bfVar#66|) (CONS '|Case| (LIST . #0#))) -(DEFUN |Return| #0=(|bfVar#61|) (CONS '|Return| (LIST . #0#))) +(DEFUN |Return| #0=(|bfVar#67|) (CONS '|Return| (LIST . #0#))) -(DEFUN |Where| #0=(|bfVar#62| |bfVar#63|) +(DEFUN |Where| #0=(|bfVar#68| |bfVar#69|) (CONS '|Where| (LIST . #0#))) -(DEFUN |Structure| #0=(|bfVar#64| |bfVar#65|) +(DEFUN |Structure| #0=(|bfVar#70| |bfVar#71|) (CONS '|Structure| (LIST . #0#))) (DEFPARAMETER |$inDefIS| NIL) @@ -1275,14 +169,14 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (DEFUN |bfCompDef| (|x|) (PROG (|body| |ISTMP#3| |args| |ISTMP#2| |op| |ISTMP#1| |def| - |bfVar#67| |bfVar#66|) + |bfVar#73| |bfVar#72|) (RETURN (PROGN - (SETQ |bfVar#66| |x|) - (SETQ |bfVar#67| (CDR |bfVar#66|)) - (CASE (CAR |bfVar#66|) + (SETQ |bfVar#72| |x|) + (SETQ |bfVar#73| (CDR |bfVar#72|)) + (CASE (CAR |bfVar#72|) (|ConstantDefinition| - (LET ((|n| (CAR |bfVar#67|)) (|e| (CADR |bfVar#67|))) + (LET ((|n| (CAR |bfVar#73|)) (|e| (CADR |bfVar#73|))) |x|)) (T (COND ((AND (CONSP |x|) @@ -1334,22 +228,22 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (PROGN (SETQ |a| (COND ((|bfTupleP| |b|) (CDR |b|)) ('T (LIST |b|)))) (COND - ((LET ((|bfVar#69| NIL) (|bfVar#68| |a|) (|x| NIL)) + ((LET ((|bfVar#75| NIL) (|bfVar#74| |a|) (|x| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#68|) - (PROGN (SETQ |x| (CAR |bfVar#68|)) NIL)) - (RETURN |bfVar#69|)) + ((OR (ATOM |bfVar#74|) + (PROGN (SETQ |x| (CAR |bfVar#74|)) NIL)) + (RETURN |bfVar#75|)) ('T (PROGN - (SETQ |bfVar#69| + (SETQ |bfVar#75| (AND (CONSP |x|) (EQ (CAR |x|) 'COLON) (PROGN (SETQ |ISTMP#1| (CDR |x|)) (AND (CONSP |ISTMP#1|) (EQ (CDR |ISTMP#1|) NIL))))) - (COND (|bfVar#69| (RETURN |bfVar#69|)))))) - (SETQ |bfVar#68| (CDR |bfVar#68|)))) + (COND (|bfVar#75| (RETURN |bfVar#75|)))))) + (SETQ |bfVar#74| (CDR |bfVar#74|)))) (|bfMakeCons| |a|)) ('T (CONS 'LIST |a|))))))) @@ -1519,19 +413,19 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (COND ((NULL |iters|) (LIST NIL NIL NIL NIL NIL NIL)) ('T (SETQ |f| (CAR |iters|)) (SETQ |r| (|bfSep| (CDR |iters|))) - (LET ((|bfVar#72| NIL) (|bfVar#70| |f|) (|i| NIL) - (|bfVar#71| |r|) (|j| NIL)) + (LET ((|bfVar#78| NIL) (|bfVar#76| |f|) (|i| NIL) + (|bfVar#77| |r|) (|j| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#70|) - (PROGN (SETQ |i| (CAR |bfVar#70|)) NIL) - (ATOM |bfVar#71|) - (PROGN (SETQ |j| (CAR |bfVar#71|)) NIL)) - (RETURN (NREVERSE |bfVar#72|))) + ((OR (ATOM |bfVar#76|) + (PROGN (SETQ |i| (CAR |bfVar#76|)) NIL) + (ATOM |bfVar#77|) + (PROGN (SETQ |j| (CAR |bfVar#77|)) NIL)) + (RETURN (NREVERSE |bfVar#78|))) ('T - (SETQ |bfVar#72| (CONS (APPEND |i| |j|) |bfVar#72|)))) - (SETQ |bfVar#70| (CDR |bfVar#70|)) - (SETQ |bfVar#71| (CDR |bfVar#71|))))))))) + (SETQ |bfVar#78| (CONS (APPEND |i| |j|) |bfVar#78|)))) + (SETQ |bfVar#76| (CDR |bfVar#76|)) + (SETQ |bfVar#77| (CDR |bfVar#77|))))))))) (DEFUN |bfReduce| (|op| |y|) (PROG (|it| |ny| |g2| |body| |g1| |g| |init| |a|) @@ -1543,7 +437,7 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (SETQ |init| (GET |op| 'SHOETHETA)) (SETQ |g| (|bfGenSymbol|)) (SETQ |g1| (|bfGenSymbol|)) - (SETQ |body| (LIST 'SETQ |g| (LIST |op| |g1| |g|))) + (SETQ |body| (LIST 'SETQ |g| (LIST |op| |g| |g1|))) (COND ((NULL |init|) (SETQ |g2| (|bfGenSymbol|)) (SETQ |init| (LIST 'CAR |g2|)) (SETQ |ny| (LIST 'CDR |g2|)) @@ -1648,25 +542,25 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (COND (|vars| (SETQ |loop| (LIST 'LET - (LET ((|bfVar#75| NIL) - (|bfVar#73| |vars|) (|v| NIL) - (|bfVar#74| |inits|) (|i| NIL)) + (LET ((|bfVar#81| NIL) + (|bfVar#79| |vars|) (|v| NIL) + (|bfVar#80| |inits|) (|i| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#73|) + ((OR (ATOM |bfVar#79|) (PROGN - (SETQ |v| (CAR |bfVar#73|)) + (SETQ |v| (CAR |bfVar#79|)) NIL) - (ATOM |bfVar#74|) + (ATOM |bfVar#80|) (PROGN - (SETQ |i| (CAR |bfVar#74|)) + (SETQ |i| (CAR |bfVar#80|)) NIL)) - (RETURN (NREVERSE |bfVar#75|))) + (RETURN (NREVERSE |bfVar#81|))) ('T - (SETQ |bfVar#75| - (CONS (LIST |v| |i|) |bfVar#75|)))) - (SETQ |bfVar#73| (CDR |bfVar#73|)) - (SETQ |bfVar#74| (CDR |bfVar#74|)))) + (SETQ |bfVar#81| + (CONS (LIST |v| |i|) |bfVar#81|)))) + (SETQ |bfVar#79| (CDR |bfVar#79|)) + (SETQ |bfVar#80| (CDR |bfVar#80|)))) |loop|)))) |loop|)))) @@ -2308,17 +1202,17 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) ((NULL (CDR |l|)) (CAR |l|)) ('T (CONS 'OR - (LET ((|bfVar#77| NIL) (|bfVar#76| |l|) (|c| NIL)) + (LET ((|bfVar#83| NIL) (|bfVar#82| |l|) (|c| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#76|) - (PROGN (SETQ |c| (CAR |bfVar#76|)) NIL)) - (RETURN (NREVERSE |bfVar#77|))) + ((OR (ATOM |bfVar#82|) + (PROGN (SETQ |c| (CAR |bfVar#82|)) NIL)) + (RETURN (NREVERSE |bfVar#83|))) ('T - (SETQ |bfVar#77| + (SETQ |bfVar#83| (APPEND (REVERSE (|bfFlatten| 'OR |c|)) - |bfVar#77|)))) - (SETQ |bfVar#76| (CDR |bfVar#76|)))))))))) + |bfVar#83|)))) + (SETQ |bfVar#82| (CDR |bfVar#82|)))))))))) (DEFUN |bfAND| (|l|) (PROG () @@ -2328,17 +1222,17 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) ((NULL (CDR |l|)) (CAR |l|)) ('T (CONS 'AND - (LET ((|bfVar#79| NIL) (|bfVar#78| |l|) (|c| NIL)) + (LET ((|bfVar#85| NIL) (|bfVar#84| |l|) (|c| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#78|) - (PROGN (SETQ |c| (CAR |bfVar#78|)) NIL)) - (RETURN (NREVERSE |bfVar#79|))) + ((OR (ATOM |bfVar#84|) + (PROGN (SETQ |c| (CAR |bfVar#84|)) NIL)) + (RETURN (NREVERSE |bfVar#85|))) ('T - (SETQ |bfVar#79| + (SETQ |bfVar#85| (APPEND (REVERSE (|bfFlatten| 'AND |c|)) - |bfVar#79|)))) - (SETQ |bfVar#78| (CDR |bfVar#78|)))))))))) + |bfVar#85|)))) + (SETQ |bfVar#84| (CDR |bfVar#84|)))))))))) (DEFUN |defQuoteId| (|x|) (PROG () (RETURN (AND (EQCAR |x| 'QUOTE) (IDENTP (CADR |x|)))))) @@ -2381,55 +1275,55 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (SETQ |nargl| (CADDR . #0#)) (SETQ |largl| (CADDDR . #0#)) (SETQ |sb| - (LET ((|bfVar#82| NIL) (|bfVar#80| |nargl|) (|i| NIL) - (|bfVar#81| |sgargl|) (|j| NIL)) + (LET ((|bfVar#88| NIL) (|bfVar#86| |nargl|) (|i| NIL) + (|bfVar#87| |sgargl|) (|j| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#80|) - (PROGN (SETQ |i| (CAR |bfVar#80|)) NIL) - (ATOM |bfVar#81|) - (PROGN (SETQ |j| (CAR |bfVar#81|)) NIL)) - (RETURN (NREVERSE |bfVar#82|))) + ((OR (ATOM |bfVar#86|) + (PROGN (SETQ |i| (CAR |bfVar#86|)) NIL) + (ATOM |bfVar#87|) + (PROGN (SETQ |j| (CAR |bfVar#87|)) NIL)) + (RETURN (NREVERSE |bfVar#88|))) (#1='T - (SETQ |bfVar#82| (CONS (CONS |i| |j|) |bfVar#82|)))) - (SETQ |bfVar#80| (CDR |bfVar#80|)) - (SETQ |bfVar#81| (CDR |bfVar#81|))))) + (SETQ |bfVar#88| (CONS (CONS |i| |j|) |bfVar#88|)))) + (SETQ |bfVar#86| (CDR |bfVar#86|)) + (SETQ |bfVar#87| (CDR |bfVar#87|))))) (SETQ |body| (SUBLIS |sb| |body|)) (SETQ |sb2| - (LET ((|bfVar#85| NIL) (|bfVar#83| |sgargl|) (|i| NIL) - (|bfVar#84| |largl|) (|j| NIL)) + (LET ((|bfVar#91| NIL) (|bfVar#89| |sgargl|) (|i| NIL) + (|bfVar#90| |largl|) (|j| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#83|) - (PROGN (SETQ |i| (CAR |bfVar#83|)) NIL) - (ATOM |bfVar#84|) - (PROGN (SETQ |j| (CAR |bfVar#84|)) NIL)) - (RETURN (NREVERSE |bfVar#85|))) + ((OR (ATOM |bfVar#89|) + (PROGN (SETQ |i| (CAR |bfVar#89|)) NIL) + (ATOM |bfVar#90|) + (PROGN (SETQ |j| (CAR |bfVar#90|)) NIL)) + (RETURN (NREVERSE |bfVar#91|))) (#1# - (SETQ |bfVar#85| + (SETQ |bfVar#91| (CONS (LIST 'CONS (LIST 'QUOTE |i|) |j|) - |bfVar#85|)))) - (SETQ |bfVar#83| (CDR |bfVar#83|)) - (SETQ |bfVar#84| (CDR |bfVar#84|))))) + |bfVar#91|)))) + (SETQ |bfVar#89| (CDR |bfVar#89|)) + (SETQ |bfVar#90| (CDR |bfVar#90|))))) (SETQ |body| (LIST 'SUBLIS (CONS 'LIST |sb2|) (LIST 'QUOTE |body|))) (SETQ |lamex| (LIST 'MLAMBDA |gargl| |body|)) (SETQ |def| (LIST |op| |lamex|)) (|bfTuple| (CONS (|shoeComp| |def|) - (LET ((|bfVar#87| NIL) (|bfVar#86| |$wheredefs|) + (LET ((|bfVar#93| NIL) (|bfVar#92| |$wheredefs|) (|d| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#86|) - (PROGN (SETQ |d| (CAR |bfVar#86|)) NIL)) - (RETURN (NREVERSE |bfVar#87|))) + ((OR (ATOM |bfVar#92|) + (PROGN (SETQ |d| (CAR |bfVar#92|)) NIL)) + (RETURN (NREVERSE |bfVar#93|))) (#1# - (SETQ |bfVar#87| + (SETQ |bfVar#93| (APPEND (REVERSE (|shoeComps| (|bfDef1| |d|))) - |bfVar#87|)))) - (SETQ |bfVar#86| (CDR |bfVar#86|)))))))))) + |bfVar#93|)))) + (SETQ |bfVar#92| (CDR |bfVar#92|)))))))))) (DEFUN |bfGargl| (|argl|) (PROG (|f| |d| |c| |b| |a| |LETTMP#1|) @@ -2449,13 +1343,13 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (LIST (CONS |f| |a|) (CONS |f| |b|) (CONS (CAR |argl|) |c|) (CONS |f| |d|))))))))) -(DEFUN |bfDef1| (|bfVar#88|) +(DEFUN |bfDef1| (|bfVar#94|) (PROG (|arglp| |control| |quotes| |LETTMP#1| |argl| |body| |args| |op| |defOp|) (RETURN (PROGN - (SETQ |defOp| (CAR |bfVar#88|)) - (SETQ |op| (CADR . #0=(|bfVar#88|))) + (SETQ |defOp| (CAR |bfVar#94|)) + (SETQ |op| (CADR . #0=(|bfVar#94|))) (SETQ |args| (CADDR . #0#)) (SETQ |body| (CADDDR . #0#)) (SETQ |argl| @@ -2501,33 +1395,33 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (|bfCompHash| |op1| |arg1| |body1|))) ('T (|bfTuple| - (LET ((|bfVar#90| NIL) - (|bfVar#89| + (LET ((|bfVar#96| NIL) + (|bfVar#95| (CONS (LIST |defOp| |op| |args| |body|) |$wheredefs|)) (|d| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#89|) - (PROGN (SETQ |d| (CAR |bfVar#89|)) NIL)) - (RETURN (NREVERSE |bfVar#90|))) + ((OR (ATOM |bfVar#95|) + (PROGN (SETQ |d| (CAR |bfVar#95|)) NIL)) + (RETURN (NREVERSE |bfVar#96|))) ('T - (SETQ |bfVar#90| + (SETQ |bfVar#96| (APPEND (REVERSE (|shoeComps| (|bfDef1| |d|))) - |bfVar#90|)))) - (SETQ |bfVar#89| (CDR |bfVar#89|)))))))))) + |bfVar#96|)))) + (SETQ |bfVar#95| (CDR |bfVar#95|)))))))))) (DEFUN |shoeComps| (|x|) (PROG () (RETURN - (LET ((|bfVar#92| NIL) (|bfVar#91| |x|) (|def| NIL)) + (LET ((|bfVar#98| NIL) (|bfVar#97| |x|) (|def| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#91|) - (PROGN (SETQ |def| (CAR |bfVar#91|)) NIL)) - (RETURN (NREVERSE |bfVar#92|))) - ('T (SETQ |bfVar#92| (CONS (|shoeComp| |def|) |bfVar#92|)))) - (SETQ |bfVar#91| (CDR |bfVar#91|))))))) + ((OR (ATOM |bfVar#97|) + (PROGN (SETQ |def| (CAR |bfVar#97|)) NIL)) + (RETURN (NREVERSE |bfVar#98|))) + ('T (SETQ |bfVar#98| (CONS (|shoeComp| |def|) |bfVar#98|)))) + (SETQ |bfVar#97| (CDR |bfVar#97|))))))) (DEFUN |shoeComp| (|x|) (PROG (|a|) @@ -2737,11 +1631,11 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) ((MEMQ U '(PROG LAMBDA)) (PROGN (SETQ |newbindings| NIL) - (LET ((|bfVar#93| (CADR |x|)) (|y| NIL)) + (LET ((|bfVar#99| (CADR |x|)) (|y| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#93|) - (PROGN (SETQ |y| (CAR |bfVar#93|)) NIL)) + ((OR (ATOM |bfVar#99|) + (PROGN (SETQ |y| (CAR |bfVar#99|)) NIL)) (RETURN NIL)) (#1='T (COND @@ -2751,23 +1645,23 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (SETQ |$locVars| (CONS |y| |$locVars|)) (SETQ |newbindings| (CONS |y| |newbindings|)))))))) - (SETQ |bfVar#93| (CDR |bfVar#93|)))) + (SETQ |bfVar#99| (CDR |bfVar#99|)))) (SETQ |res| (|shoeCompTran1| (CDDR |x|))) (SETQ |$locVars| - (LET ((|bfVar#95| NIL) (|bfVar#94| |$locVars|) + (LET ((|bfVar#101| NIL) (|bfVar#100| |$locVars|) (|y| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#94|) + ((OR (ATOM |bfVar#100|) (PROGN - (SETQ |y| (CAR |bfVar#94|)) + (SETQ |y| (CAR |bfVar#100|)) NIL)) - (RETURN (NREVERSE |bfVar#95|))) + (RETURN (NREVERSE |bfVar#101|))) (#1# (AND (NULL (MEMQ |y| |newbindings|)) - (SETQ |bfVar#95| - (CONS |y| |bfVar#95|))))) - (SETQ |bfVar#94| (CDR |bfVar#94|))))))) + (SETQ |bfVar#101| + (CONS |y| |bfVar#101|))))) + (SETQ |bfVar#100| (CDR |bfVar#100|))))))) (#0# (PROGN (|shoeCompTran1| (CAR |x|)) @@ -2859,14 +1753,14 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (RETURN (PROGN (SETQ |a| - (LET ((|bfVar#96| NIL) (|c| |l|)) + (LET ((|bfVar#102| NIL) (|c| |l|)) (LOOP (COND - ((ATOM |c|) (RETURN (NREVERSE |bfVar#96|))) + ((ATOM |c|) (RETURN (NREVERSE |bfVar#102|))) ('T - (SETQ |bfVar#96| + (SETQ |bfVar#102| (APPEND (REVERSE (|bfFlattenSeq| |c|)) - |bfVar#96|)))) + |bfVar#102|)))) (SETQ |c| (CDR |c|))))) (COND ((NULL |a|) NIL) @@ -2886,17 +1780,17 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) ((EQCAR |f| 'PROGN) (COND ((CDR |x|) - (LET ((|bfVar#98| NIL) (|bfVar#97| (CDR |f|)) + (LET ((|bfVar#104| NIL) (|bfVar#103| (CDR |f|)) (|i| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#97|) - (PROGN (SETQ |i| (CAR |bfVar#97|)) NIL)) - (RETURN (NREVERSE |bfVar#98|))) + ((OR (ATOM |bfVar#103|) + (PROGN (SETQ |i| (CAR |bfVar#103|)) NIL)) + (RETURN (NREVERSE |bfVar#104|))) ('T (AND (NULL (ATOM |i|)) - (SETQ |bfVar#98| (CONS |i| |bfVar#98|))))) - (SETQ |bfVar#97| (CDR |bfVar#97|))))) + (SETQ |bfVar#104| (CONS |i| |bfVar#104|))))) + (SETQ |bfVar#103| (CDR |bfVar#103|))))) (#0# (CDR |f|)))) (#0# (LIST |f|))))))))) @@ -2909,11 +1803,11 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (#0='T (PROGN (SETQ |transform| - (LET ((|bfVar#100| NIL) (|bfVar#99| |l|) (|x| NIL)) + (LET ((|bfVar#106| NIL) (|bfVar#105| |l|) (|x| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#99|) - (PROGN (SETQ |x| (CAR |bfVar#99|)) NIL) + ((OR (ATOM |bfVar#105|) + (PROGN (SETQ |x| (CAR |bfVar#105|)) NIL) (NOT (AND (CONSP |x|) (EQ (CAR |x|) 'COND) (PROGN (SETQ |ISTMP#1| (CDR |x|)) @@ -2948,11 +1842,11 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (SETQ |b| (CAR |ISTMP#5|)) 'T)))))))))))))) - (RETURN (NREVERSE |bfVar#100|))) + (RETURN (NREVERSE |bfVar#106|))) ('T - (SETQ |bfVar#100| - (CONS (LIST |a| |b|) |bfVar#100|)))) - (SETQ |bfVar#99| (CDR |bfVar#99|))))) + (SETQ |bfVar#106| + (CONS (LIST |a| |b|) |bfVar#106|)))) + (SETQ |bfVar#105| (CDR |bfVar#105|))))) (SETQ |no| (LENGTH |transform|)) (SETQ |before| (|bfTake| |no| |l|)) (SETQ |aft| (|bfDrop| |no| |l|)) @@ -2985,12 +1879,12 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (SETQ |defs| (CADR . #0=(|LETTMP#1|))) (SETQ |nondefs| (CADDR . #0#)) (SETQ |a| - (LET ((|bfVar#102| NIL) (|bfVar#101| |defs|) (|d| NIL)) + (LET ((|bfVar#108| NIL) (|bfVar#107| |defs|) (|d| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#101|) - (PROGN (SETQ |d| (CAR |bfVar#101|)) NIL)) - (RETURN (NREVERSE |bfVar#102|))) + ((OR (ATOM |bfVar#107|) + (PROGN (SETQ |d| (CAR |bfVar#107|)) NIL)) + (RETURN (NREVERSE |bfVar#108|))) ('T (AND (CONSP |d|) (PROGN @@ -3009,11 +1903,11 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (PROGN (SETQ |body| (CAR |ISTMP#3|)) 'T))))))) - (SETQ |bfVar#102| + (SETQ |bfVar#108| (CONS (LIST |def| |op| |args| (|bfSUBLIS| |opassoc| |body|)) - |bfVar#102|))))) - (SETQ |bfVar#101| (CDR |bfVar#101|))))) + |bfVar#108|))))) + (SETQ |bfVar#107| (CDR |bfVar#107|))))) (SETQ |$wheredefs| (APPEND |a| |$wheredefs|)) (|bfMKPROGN| (|bfSUBLIS| |opassoc| (NCONC |nondefs| (LIST |expr|)))))))) @@ -3090,16 +1984,16 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (PROG () (RETURN (|bfTuple| - (LET ((|bfVar#104| NIL) (|bfVar#103| |arglist|) (|i| NIL)) + (LET ((|bfVar#110| NIL) (|bfVar#109| |arglist|) (|i| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#103|) - (PROGN (SETQ |i| (CAR |bfVar#103|)) NIL)) - (RETURN (NREVERSE |bfVar#104|))) + ((OR (ATOM |bfVar#109|) + (PROGN (SETQ |i| (CAR |bfVar#109|)) NIL)) + (RETURN (NREVERSE |bfVar#110|))) ('T - (SETQ |bfVar#104| - (CONS (|bfCreateDef| |i|) |bfVar#104|)))) - (SETQ |bfVar#103| (CDR |bfVar#103|)))))))) + (SETQ |bfVar#110| + (CONS (|bfCreateDef| |i|) |bfVar#110|)))) + (SETQ |bfVar#109| (CDR |bfVar#109|)))))))) (DEFUN |bfCreateDef| (|x|) (PROG (|a| |f|) @@ -3109,17 +2003,17 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (LIST 'SETQ |f| (LIST 'LIST (LIST 'QUOTE |f|)))) ('T (SETQ |a| - (LET ((|bfVar#106| NIL) (|bfVar#105| (CDR |x|)) + (LET ((|bfVar#112| NIL) (|bfVar#111| (CDR |x|)) (|i| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#105|) - (PROGN (SETQ |i| (CAR |bfVar#105|)) NIL)) - (RETURN (NREVERSE |bfVar#106|))) + ((OR (ATOM |bfVar#111|) + (PROGN (SETQ |i| (CAR |bfVar#111|)) NIL)) + (RETURN (NREVERSE |bfVar#112|))) ('T - (SETQ |bfVar#106| - (CONS (|bfGenSymbol|) |bfVar#106|)))) - (SETQ |bfVar#105| (CDR |bfVar#105|))))) + (SETQ |bfVar#112| + (CONS (|bfGenSymbol|) |bfVar#112|)))) + (SETQ |bfVar#111| (CDR |bfVar#111|))))) (LIST 'DEFUN (CAR |x|) |a| (LIST 'CONS (LIST 'QUOTE (CAR |x|)) (CONS 'LIST |a|)))))))) @@ -3140,22 +2034,22 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (DEFUN |bfCaseItems| (|g| |x|) (PROG (|j| |ISTMP#1| |i|) (RETURN - (LET ((|bfVar#109| NIL) (|bfVar#108| |x|) (|bfVar#107| NIL)) + (LET ((|bfVar#115| NIL) (|bfVar#114| |x|) (|bfVar#113| NIL)) (LOOP (COND - ((OR (ATOM |bfVar#108|) - (PROGN (SETQ |bfVar#107| (CAR |bfVar#108|)) NIL)) - (RETURN (NREVERSE |bfVar#109|))) + ((OR (ATOM |bfVar#114|) + (PROGN (SETQ |bfVar#113| (CAR |bfVar#114|)) NIL)) + (RETURN (NREVERSE |bfVar#115|))) ('T - (AND (CONSP |bfVar#107|) + (AND (CONSP |bfVar#113|) (PROGN - (SETQ |i| (CAR |bfVar#107|)) - (SETQ |ISTMP#1| (CDR |bfVar#107|)) + (SETQ |i| (CAR |bfVar#113|)) + (SETQ |ISTMP#1| (CDR |bfVar#113|)) (AND (CONSP |ISTMP#1|) (EQ (CDR |ISTMP#1|) NIL) (PROGN (SETQ |j| (CAR |ISTMP#1|)) 'T))) - (SETQ |bfVar#109| - (CONS (|bfCI| |g| |i| |j|) |bfVar#109|))))) - (SETQ |bfVar#108| (CDR |bfVar#108|))))))) + (SETQ |bfVar#115| + (CONS (|bfCI| |g| |i| |j|) |bfVar#115|))))) + (SETQ |bfVar#114| (CDR |bfVar#114|))))))) (DEFUN |bfCI| (|g| |x| |y|) (PROG (|b| |a|) @@ -3166,18 +2060,18 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) ((NULL |a|) (LIST (CAR |x|) |y|)) ('T (SETQ |b| - (LET ((|bfVar#111| NIL) (|bfVar#110| |a|) (|i| NIL) + (LET ((|bfVar#117| NIL) (|bfVar#116| |a|) (|i| NIL) (|j| 0)) (LOOP (COND - ((OR (ATOM |bfVar#110|) - (PROGN (SETQ |i| (CAR |bfVar#110|)) NIL)) - (RETURN (NREVERSE |bfVar#111|))) + ((OR (ATOM |bfVar#116|) + (PROGN (SETQ |i| (CAR |bfVar#116|)) NIL)) + (RETURN (NREVERSE |bfVar#117|))) ('T - (SETQ |bfVar#111| + (SETQ |bfVar#117| (CONS (LIST |i| (|bfCARCDR| |j| |g|)) - |bfVar#111|)))) - (SETQ |bfVar#110| (CDR |bfVar#110|)) + |bfVar#117|)))) + (SETQ |bfVar#116| (CDR |bfVar#116|)) (SETQ |j| (+ |j| 1))))) (LIST (CAR |x|) (LIST 'LET |b| |y|)))))))) @@ -3190,6 +2084,3 @@ bfDs n== if n=0 then '"" else CONCAT('"D",bfDs(n-1)) (RETURN (COND ((EQL |n| 0) "") ('T (CONCAT "D" (|bfDs| (- |n| 1)))))))) -@ - -\end{document} diff --git a/src/boot/strap/includer.clisp b/src/boot/strap/includer.clisp new file mode 100644 index 00000000..a2324315 --- /dev/null +++ b/src/boot/strap/includer.clisp @@ -0,0 +1,553 @@ +(EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-includer")) + +(IMPORT-MODULE "tokens") + +(IN-PACKAGE "BOOTTRAN") + +(DEFUN PNAME (|x|) + (PROG () + (RETURN + (COND + ((SYMBOLP |x|) (SYMBOL-NAME |x|)) + ((CHARACTERP |x|) (STRING |x|)) + ('T NIL))))) + +(DEFUN |char| (|x|) (PROG () (RETURN (CHAR (PNAME |x|) 0)))) + +(DEFUN EQCAR (|x| |y|) + (PROG () (RETURN (AND (CONSP |x|) (EQ (CAR |x|) |y|))))) + +(DEFUN STRINGIMAGE (|x|) (PROG () (RETURN (WRITE-TO-STRING |x|)))) + +(DEFUN |shoeCLOSE| (|stream|) (PROG () (RETURN (CLOSE |stream|)))) + +(DEFUN |shoeNotFound| (|fn|) + (PROG () + (RETURN (PROGN (|coreError| (LIST |fn| " not found")) NIL)))) + +(DEFUN |shoeReadLispString| (|s| |n|) + (PROG (|l|) + (RETURN + (PROGN + (SETQ |l| (LENGTH |s|)) + (COND + ((NOT (< |n| |l|)) NIL) + ('T + (READ-FROM-STRING + (CONCAT '|(| (SUBSTRING |s| |n| (- |l| |n|)) '|)|)))))))) + +(DEFUN |shoeReadLine| (|stream|) + (PROG () (RETURN (READ-LINE |stream| NIL NIL)))) + +(DEFUN |shoeConsole| (|line|) + (PROG () (RETURN (WRITE-LINE |line| *TERMINAL-IO*)))) + +(DEFUN |shoeSpaces| (|n|) (PROG () (RETURN (MAKE-FULL-CVEC |n| ".")))) + +(DEFUN |SoftShoeError| (|posn| |key|) + (PROG () + (RETURN + (PROGN + (|coreError| (LIST "in line " (STRINGIMAGE (|lineNo| |posn|)))) + (|shoeConsole| (|lineString| |posn|)) + (|shoeConsole| + (CONCAT (|shoeSpaces| (|lineCharacter| |posn|)) "|")) + (|shoeConsole| |key|))))) + +(DEFUN |bpSpecificErrorAtToken| (|tok| |key|) + (PROG (|a|) + (RETURN + (PROGN + (SETQ |a| (|shoeTokPosn| |tok|)) + (|SoftShoeError| |a| |key|))))) + +(DEFUN |bpSpecificErrorHere| (|key|) + (PROG () + (DECLARE (SPECIAL |$stok|)) + (RETURN (|bpSpecificErrorAtToken| |$stok| |key|)))) + +(DEFUN |bpGeneralErrorHere| () + (PROG () (RETURN (|bpSpecificErrorHere| "syntax error")))) + +(DEFUN |bpIgnoredFromTo| (|pos1| |pos2|) + (PROG () + (RETURN + (PROGN + (|shoeConsole| + (CONCAT "ignored from line " + (STRINGIMAGE (|lineNo| |pos1|)))) + (|shoeConsole| (|lineString| |pos1|)) + (|shoeConsole| + (CONCAT (|shoeSpaces| (|lineCharacter| |pos1|)) "|")) + (|shoeConsole| + (CONCAT "ignored through line " + (STRINGIMAGE (|lineNo| |pos2|)))) + (|shoeConsole| (|lineString| |pos2|)) + (|shoeConsole| + (CONCAT (|shoeSpaces| (|lineCharacter| |pos2|)) "|")))))) + +(DEFUN |lineNo| (|p|) (PROG () (RETURN (CDAAR |p|)))) + +(DEFUN |lineString| (|p|) (PROG () (RETURN (CAAAR |p|)))) + +(DEFUN |lineCharacter| (|p|) (PROG () (RETURN (CDR |p|)))) + +(DEFUN |shoePackageStartsAt| (|lines| |sz| |name| |stream|) + (PROG (|a|) + (RETURN + (COND + ((|bStreamNull| |stream|) (LIST NIL (LIST '|nullstream|))) + ('T + (PROGN + (SETQ |a| (CAAR |stream|)) + (COND + ((AND (NOT (< (LENGTH |a|) 8)) + (EQUAL (SUBSTRING |a| 0 8) ")package")) + (|shoePackageStartsAt| (CONS (CAAR |stream|) |lines|) + |sz| |name| (CDR |stream|))) + ((< (LENGTH |a|) |sz|) + (|shoePackageStartsAt| |lines| |sz| |name| + (CDR |stream|))) + ((AND (EQUAL (SUBSTRING |a| 0 |sz|) |name|) + (< |sz| (LENGTH |a|)) + (NULL (|shoeIdChar| (ELT |a| |sz|)))) + (LIST |lines| |stream|)) + ('T + (|shoePackageStartsAt| |lines| |sz| |name| + (CDR |stream|)))))))))) + +(DEFUN |shoeFindLines| (|fn| |name| |a|) + (PROG (|b| |lines| |LETTMP#1|) + (RETURN + (COND + ((NULL |a|) (|shoeNotFound| |fn|) NIL) + (#0='T + (SETQ |LETTMP#1| + (|shoePackageStartsAt| NIL (LENGTH |name|) |name| + (|shoeInclude| + (|bAddLineNumber| (|bRgen| |a|) (|bIgen| 0))))) + (SETQ |lines| (CAR |LETTMP#1|)) (SETQ |b| (CADR |LETTMP#1|)) + (SETQ |b| (|shoeTransform2| |b|)) + (COND + ((|bStreamNull| |b|) + (|shoeConsole| (CONCAT |name| " not found in " |fn|)) NIL) + (#0# + (COND + ((NULL |lines|) (|shoeConsole| ")package not found"))) + (APPEND (REVERSE |lines|) (CAR |b|))))))))) + +(DEFPARAMETER |$bStreamNil| (LIST '|nullstream|)) + +(DEFUN |bStreamNull| (|x|) + (PROG (|st|) + (RETURN + (COND + ((OR (NULL |x|) (EQCAR |x| '|nullstream|)) T) + ('T + (PROGN + (LOOP + (COND + ((NOT (EQCAR |x| '|nonnullstream|)) (RETURN NIL)) + ('T + (PROGN + (SETQ |st| (APPLY (CADR |x|) (CDDR |x|))) + (RPLACA |x| (CAR |st|)) + (RPLACD |x| (CDR |st|)))))) + (EQCAR |x| '|nullstream|))))))) + +(DEFUN |bMap| (|f| |x|) + (PROG () (RETURN (|bDelay| #'|bMap1| (LIST |f| |x|))))) + +(DEFUN |bMap1| (&REST |z|) + (PROG (|x| |f|) + (DECLARE (SPECIAL |$bStreamNil|)) + (RETURN + (PROGN + (SETQ |f| (CAR |z|)) + (SETQ |x| (CADR |z|)) + (COND + ((|bStreamNull| |x|) |$bStreamNil|) + ('T (CONS (FUNCALL |f| (CAR |x|)) (|bMap| |f| (CDR |x|))))))))) + +(DEFUN |shoeFileMap| (|f| |fn|) + (PROG (|a|) + (DECLARE (SPECIAL |$bStreamNil|)) + (RETURN + (PROGN + (SETQ |a| (|shoeInputFile| |fn|)) + (COND + ((NULL |a|) + (PROGN + (|shoeConsole| (CONCAT |fn| " NOT FOUND")) + |$bStreamNil|)) + ('T + (PROGN + (|shoeConsole| (CONCAT "READING " |fn|)) + (|shoeInclude| + (|bAddLineNumber| (|bMap| |f| (|bRgen| |a|)) + (|bIgen| 0)))))))))) + +(DEFUN |bDelay| (|f| |x|) + (PROG () (RETURN (CONS '|nonnullstream| (CONS |f| |x|))))) + +(DEFUN |bAppend| (|x| |y|) + (PROG () (RETURN (|bDelay| #'|bAppend1| (LIST |x| |y|))))) + +(DEFUN |bAppend1| (&REST |z|) + (PROG () + (RETURN + (COND + ((|bStreamNull| (CAR |z|)) + (COND + ((|bStreamNull| (CADR |z|)) (LIST '|nullstream|)) + (#0='T (CADR |z|)))) + (#0# (CONS (CAAR |z|) (|bAppend| (CDAR |z|) (CADR |z|)))))))) + +(DEFUN |bNext| (|f| |s|) + (PROG () (RETURN (|bDelay| #'|bNext1| (LIST |f| |s|))))) + +(DEFUN |bNext1| (|f| |s|) + (PROG (|h|) + (RETURN + (COND + ((|bStreamNull| |s|) (LIST '|nullstream|)) + ('T + (PROGN + (SETQ |h| (APPLY |f| (LIST |s|))) + (|bAppend| (CAR |h|) (|bNext| |f| (CDR |h|))))))))) + +(DEFUN |bRgen| (|s|) + (PROG () (RETURN (|bDelay| #'|bRgen1| (LIST |s|))))) + +(DEFUN |bRgen1| (&REST |s|) + (PROG (|a|) + (RETURN + (PROGN + (SETQ |a| (|shoeReadLine| (CAR |s|))) + (COND + ((|shoePLACEP| |a|) (LIST '|nullstream|)) + ('T (CONS |a| (|bRgen| (CAR |s|))))))))) + +(DEFUN |bIgen| (|n|) + (PROG () (RETURN (|bDelay| #'|bIgen1| (LIST |n|))))) + +(DEFUN |bIgen1| (&REST |n|) + (PROG () + (RETURN + (PROGN (SETQ |n| (+ (CAR |n|) 1)) (CONS |n| (|bIgen| |n|)))))) + +(DEFUN |bAddLineNumber| (|f1| |f2|) + (PROG () (RETURN (|bDelay| #'|bAddLineNumber1| (LIST |f1| |f2|))))) + +(DEFUN |bAddLineNumber1| (&REST |f|) + (PROG (|f2| |f1|) + (RETURN + (PROGN + (SETQ |f1| (CAR |f|)) + (SETQ |f2| (CADR |f|)) + (COND + ((|bStreamNull| |f1|) (LIST '|nullstream|)) + ((|bStreamNull| |f2|) (LIST '|nullstream|)) + ('T + (CONS (CONS (CAR |f1|) (CAR |f2|)) + (|bAddLineNumber| (CDR |f1|) (CDR |f2|))))))))) + +(DEFUN |shoeFileInput| (|fn|) + (PROG () (RETURN (|shoeFileMap| #'IDENTITY |fn|)))) + +(DEFUN |shoePrefixLisp| (|x|) (PROG () (RETURN (CONCAT ")lisp" |x|)))) + +(DEFUN |shoeLispFileInput| (|fn|) + (PROG () (RETURN (|shoeFileMap| #'|shoePrefixLisp| |fn|)))) + +(DEFUN |shoePrefixLine| (|x|) (PROG () (RETURN (CONCAT ")line" |x|)))) + +(DEFUN |shoeLineFileInput| (|fn|) + (PROG () (RETURN (|shoeFileMap| #'|shoePrefixLine| |fn|)))) + +(DEFUN |shoePrefix?| (|prefix| |whole|) + (PROG (|good|) + (RETURN + (COND + ((< (LENGTH |whole|) (LENGTH |prefix|)) NIL) + ('T + (PROGN + (SETQ |good| T) + (LET ((|bfVar#1| (- (LENGTH |prefix|) 1)) (|i| 0) (|j| 0)) + (LOOP + (COND + ((OR (> |i| |bfVar#1|) (NOT |good|)) (RETURN NIL)) + ('T + (SETQ |good| + (EQUAL (ELT |prefix| |i|) (ELT |whole| |j|))))) + (SETQ |i| (+ |i| 1)) + (SETQ |j| (+ |j| 1)))) + (COND + (|good| (SUBSTRING |whole| (LENGTH |prefix|) NIL)) + ('T |good|)))))))) + +(DEFUN |shoePlainLine?| (|s|) + (PROG () + (RETURN + (COND + ((EQL (LENGTH |s|) 0) T) + ('T (NOT (EQUAL (ELT |s| 0) (|char| '|)|)))))))) + +(DEFUN |shoeSay?| (|s|) (PROG () (RETURN (|shoePrefix?| ")say" |s|)))) + +(DEFUN |shoeEval?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")eval" |s|)))) + +(DEFUN |shoeInclude?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")include" |s|)))) + +(DEFUN |shoeFin?| (|s|) (PROG () (RETURN (|shoePrefix?| ")fin" |s|)))) + +(DEFUN |shoeIf?| (|s|) (PROG () (RETURN (|shoePrefix?| ")if" |s|)))) + +(DEFUN |shoeEndIf?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")endif" |s|)))) + +(DEFUN |shoeElse?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")else" |s|)))) + +(DEFUN |shoeElseIf?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")elseif" |s|)))) + +(DEFUN |shoePackage?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")package" |s|)))) + +(DEFUN |shoeLisp?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")lisp" |s|)))) + +(DEFUN |shoeIncludeLisp?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")includelisp" |s|)))) + +(DEFUN |shoeLine?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")line" |s|)))) + +(DEFUN |shoeIncludeLines?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")includelines" |s|)))) + +(DEFUN |shoeIncludeFunction?| (|s|) + (PROG () (RETURN (|shoePrefix?| ")includefunction" |s|)))) + +(DEFUN |shoeBiteOff| (|x|) + (PROG (|n1| |n|) + (RETURN + (PROGN + (SETQ |n| (STRPOSL " " |x| 0 T)) + (COND + ((NULL |n|) NIL) + (#0='T + (PROGN + (SETQ |n1| (STRPOSL " " |x| |n| NIL)) + (COND + ((NULL |n1|) (LIST (SUBSTRING |x| |n| NIL) "")) + (#0# + (LIST (SUBSTRING |x| |n| (- |n1| |n|)) + (SUBSTRING |x| |n1| NIL))))))))))) + +(DEFUN |shoeFileName| (|x|) + (PROG (|c| |a|) + (RETURN + (PROGN + (SETQ |a| (|shoeBiteOff| |x|)) + (COND + ((NULL |a|) "") + (#0='T + (PROGN + (SETQ |c| (|shoeBiteOff| (CADR |a|))) + (COND + ((NULL |c|) (CAR |a|)) + (#0# (CONCAT (CAR |a|) "." (CAR |c|))))))))))) + +(DEFUN |shoeFnFileName| (|x|) + (PROG (|c| |a|) + (RETURN + (PROGN + (SETQ |a| (|shoeBiteOff| |x|)) + (COND + ((NULL |a|) (LIST "" "")) + (#0='T + (PROGN + (SETQ |c| (|shoeFileName| (CADR |a|))) + (COND + ((NULL |c|) (LIST (CAR |a|) "")) + (#0# (LIST (CAR |a|) |c|)))))))))) + +(DEFUN |shoeFunctionFileInput| (|bfVar#2|) + (PROG (|fn| |fun|) + (RETURN + (PROGN + (SETQ |fun| (CAR |bfVar#2|)) + (SETQ |fn| (CADR |bfVar#2|)) + (|shoeOpenInputFile| |a| |fn| + (|shoeInclude| + (|bAddLineNumber| (|shoeFindLines| |fn| |fun| |a|) + (|bIgen| 0)))))))) + +(DEFUN |shoeInclude| (|s|) + (PROG () (RETURN (|bDelay| #'|shoeInclude1| (LIST |s|))))) + +(DEFUN |shoeInclude1| (|s|) + (PROG (|command| |string| |t| |h|) + (DECLARE (SPECIAL |$bStreamNil|)) + (RETURN + (COND + ((|bStreamNull| |s|) |s|) + (#0='T + (PROGN + (SETQ |h| (CAR |s|)) + (SETQ |t| (CDR |s|)) + (SETQ |string| (CAR |h|)) + (COND + ((SETQ |command| (|shoeFin?| |string|)) |$bStreamNil|) + ((SETQ |command| (|shoeIf?| |string|)) + (|shoeThen| (LIST T) (LIST (STTOMC |command|)) |t|)) + (#0# + (|bAppend| (|shoeSimpleLine| |h|) (|shoeInclude| |t|)))))))))) + +(DEFUN |shoeSimpleLine| (|h|) + (PROG (|command| |string|) + (RETURN + (PROGN + (SETQ |string| (CAR |h|)) + (COND + ((|shoePlainLine?| |string|) (LIST |h|)) + ((SETQ |command| (|shoeLisp?| |string|)) (LIST |h|)) + ((SETQ |command| (|shoeIncludeLisp?| |string|)) + (|shoeLispFileInput| (|shoeFileName| |command|))) + ((SETQ |command| (|shoeIncludeFunction?| |string|)) + (|shoeFunctionFileInput| (|shoeFnFileName| |command|))) + ((SETQ |command| (|shoeLine?| |string|)) (LIST |h|)) + ((SETQ |command| (|shoeIncludeLines?| |string|)) + (|shoeLineFileInput| (|shoeFileName| |command|))) + ((SETQ |command| (|shoeInclude?| |string|)) + (|shoeFileInput| (|shoeFileName| |command|))) + ((SETQ |command| (|shoePackage?| |string|)) (LIST |h|)) + ((SETQ |command| (|shoeSay?| |string|)) + (PROGN (|shoeConsole| |command|) NIL)) + ((SETQ |command| (|shoeEval?| |string|)) + (PROGN (STTOMC |command|) NIL)) + ('T (PROGN (|shoeLineSyntaxError| |h|) NIL))))))) + +(DEFUN |shoeThen| (|keep| |b| |s|) + (PROG () (RETURN (|bDelay| #'|shoeThen1| (LIST |keep| |b| |s|))))) + +(DEFUN |shoeThen1| (|keep| |b| |s|) + (PROG (|b1| |keep1| |command| |string| |t| |h|) + (RETURN + (COND + ((|bPremStreamNull| |s|) |s|) + (#0='T + (PROGN + (SETQ |h| (CAR |s|)) + (SETQ |t| (CDR |s|)) + (SETQ |string| (CAR |h|)) + (COND + ((SETQ |command| (|shoeFin?| |string|)) + (|bPremStreamNil| |h|)) + (#0# + (PROGN + (SETQ |keep1| (CAR |keep|)) + (SETQ |b1| (CAR |b|)) + (COND + ((SETQ |command| (|shoeIf?| |string|)) + (COND + ((AND |keep1| |b1|) + (|shoeThen| (CONS T |keep|) + (CONS (STTOMC |command|) |b|) |t|)) + (#0# + (|shoeThen| (CONS NIL |keep|) (CONS NIL |b|) |t|)))) + ((SETQ |command| (|shoeElseIf?| |string|)) + (COND + ((AND |keep1| (NULL |b1|)) + (|shoeThen| (CONS T (CDR |keep|)) + (CONS (STTOMC |command|) (CDR |b|)) |t|)) + (#0# + (|shoeThen| (CONS NIL (CDR |keep|)) + (CONS NIL (CDR |b|)) |t|)))) + ((SETQ |command| (|shoeElse?| |string|)) + (COND + ((AND |keep1| (NULL |b1|)) + (|shoeElse| (CONS T (CDR |keep|)) + (CONS T (CDR |b|)) |t|)) + (#0# + (|shoeElse| (CONS NIL (CDR |keep|)) + (CONS NIL (CDR |b|)) |t|)))) + ((SETQ |command| (|shoeEndIf?| |string|)) + (COND + ((NULL (CDR |b|)) (|shoeInclude| |t|)) + (#0# (|shoeThen| (CDR |keep|) (CDR |b|) |t|)))) + ((AND |keep1| |b1|) + (|bAppend| (|shoeSimpleLine| |h|) + (|shoeThen| |keep| |b| |t|))) + (#0# (|shoeThen| |keep| |b| |t|)))))))))))) + +(DEFUN |shoeElse| (|keep| |b| |s|) + (PROG () (RETURN (|bDelay| #'|shoeElse1| (LIST |keep| |b| |s|))))) + +(DEFUN |shoeElse1| (|keep| |b| |s|) + (PROG (|keep1| |b1| |command| |string| |t| |h|) + (RETURN + (COND + ((|bPremStreamNull| |s|) |s|) + (#0='T + (PROGN + (SETQ |h| (CAR |s|)) + (SETQ |t| (CDR |s|)) + (SETQ |string| (CAR |h|)) + (COND + ((SETQ |command| (|shoeFin?| |string|)) + (|bPremStreamNil| |h|)) + (#0# + (PROGN + (SETQ |b1| (CAR |b|)) + (SETQ |keep1| (CAR |keep|)) + (COND + ((SETQ |command| (|shoeIf?| |string|)) + (COND + ((AND |keep1| |b1|) + (|shoeThen| (CONS T |keep|) + (CONS (STTOMC |command|) |b|) |t|)) + (#0# + (|shoeThen| (CONS NIL |keep|) (CONS NIL |b|) |t|)))) + ((SETQ |command| (|shoeEndIf?| |string|)) + (COND + ((NULL (CDR |b|)) (|shoeInclude| |t|)) + (#0# (|shoeThen| (CDR |keep|) (CDR |b|) |t|)))) + ((AND |keep1| |b1|) + (|bAppend| (|shoeSimpleLine| |h|) + (|shoeElse| |keep| |b| |t|))) + (#0# (|shoeElse| |keep| |b| |t|)))))))))))) + +(DEFUN |shoeLineSyntaxError| (|h|) + (PROG () + (RETURN + (PROGN + (|shoeConsole| + (CONCAT "INCLUSION SYNTAX ERROR IN LINE " + (STRINGIMAGE (CDR |h|)))) + (|shoeConsole| (CAR |h|)) + (|shoeConsole| "LINE IGNORED"))))) + +(DEFUN |bPremStreamNil| (|h|) + (PROG () + (DECLARE (SPECIAL |$bStreamNil|)) + (RETURN + (PROGN + (|shoeConsole| + (CONCAT "UNEXPECTED )fin IN LINE " (STRINGIMAGE (CDR |h|)))) + (|shoeConsole| (CAR |h|)) + (|shoeConsole| "REST OF FILE IGNORED") + |$bStreamNil|)))) + +(DEFUN |bPremStreamNull| (|s|) + (PROG () + (RETURN + (COND + ((|bStreamNull| |s|) + (|shoeConsole| "FILE TERMINATED BEFORE )endif") T) + ('T NIL))))) + diff --git a/src/boot/parser.boot.pamphlet b/src/boot/strap/parser.clisp index 2ff33d38..cfc9b0fa 100644 --- a/src/boot/parser.boot.pamphlet +++ b/src/boot/strap/parser.clisp @@ -1,1144 +1,3 @@ -\documentclass{article} -\usepackage{axiom} -\usepackage{fancyvrb} - -\CustomVerbatimEnvironment{Grammar}{Verbatim}% - {frame=none,fontsize=\small,commandchars=\\\{\}} -\newcommand{\production}[1]{{\rmfamily\itshape{#1}}} -\newcommand{\Terminal}[1]{\ensuremath{\mathbf{#1}}} -\newcommand{\Bar}{\ensuremath{\mid}} -\newcommand{\Comment}[1]{-- \textrm{#1}} - -\title{\File{src/boot/parser.boot} Pamphlet} -\author{The Axiom Team} - -\begin{document} -\maketitle - -\begin{abstract} - This file defines the Boot grammar and parser. The parser - is hand-written based on \emph{parser combinators} technology. -\end{abstract} - -\tableofcontents -\eject - -\section{Introduction} -\label{sec:intro} - -This file defines the grammar, and implements the parser for the -Boot language. The parser is -recursive descent and uses \emph{parser combinators} techniques. - -\section{The Parser} -\label{sec:parser} - - -\subsection{Names} -\label{sec:parser:name} - -\begin{Grammar} - \production{Name:} - \Terminal{ID} - \production{Name} :: \Terminal{ID} -\end{Grammar} - -<<Name>>= --- A fully qualified name could be interpreted as a left reduction --- of an '::' infix operator. At the moment, we don't use --- that general interpretation. - --- When this routine is called, a symbol is already pushed on the --- stack. When this routine finished execution, we have either --- reduced a '::' and a name, or nothing. In either case, a --- symbol is present on the stack. -bpQualifiedName() == - bpEqPeek "COLON-COLON" => - bpNext() - EQCAR($stok, "ID") and bpPushId() and bpNext() - and bpPush bfColonColon(bpPop2(), bpPop1()) - false - -bpName() == - EQCAR( $stok,"ID") => - bpPushId() - bpNext() - bpAnyNo function bpQualifiedName - false -@ - - -\subsection{Constants} -\label{sec:parser:constant} - -\begin{Grammar} - \production{Constant:} - \Terminal{INTEGER} - \Bar \Terminal{FLOAT} - \Bar \Terminal{LISP} - \Bar \Terminal{LISPEXPR} - \Bar \Terminal{LINE} - \Bar \Terminal{QUOTE} \production{S-Expression} - \Bar \Terminal{STRING} -\end{Grammar} - -<<Constant>>= -bpConstTok() == - MEMQ(shoeTokType $stok, '(INTEGER FLOAT)) => - bpPush $ttok - bpNext() - EQCAR($stok,"LISP")=> bpPush bfReadLisp $ttok and bpNext() - EQCAR($stok,"LISPEXP")=> bpPush $ttok and bpNext() - EQCAR($stok,"LINE")=> bpPush ["+LINE", $ttok] and bpNext() - bpEqPeek "QUOTE" => - bpNext() - (bpSexp() or bpTrap()) and - bpPush bfSymbol bpPop1() - bpString() -@ - -\subsection{Wildchar} -\label{sec:parser:dot} - -The dot character (\verb!.!) is used both as a selection operator and -as wild character in patterns. -\begin{Grammar} - \production{Dot:} - \Terminal{DOT} -\end{Grammar} - -<<Dot>>= -bpDot()== bpEqKey "DOT" and bpPush bfDot () -@ - - -\subsection{Prefix operators} -\label{sec:parser:prefix-op} - -Boot has two prefix operators. -\begin{Grammar} - \production{PrefixOperator:} \textrm{one of} - ^ # -\end{Grammar} - -<<PrefixOperator>>= -bpPrefixOperator()== - EQCAR( $stok,"KEY") and - GET($ttok,"SHOEPRE") and bpPushId() and bpNext() -@ - -\subsection{Infix operators} -\label{sec:parser:infix-op} - -\begin{Grammar} - \production{InfixOperator:} \textrm{one of} - = * + is isnt and or / ** - < > <= >= ^= -\end{Grammar} - -<<InfixOperator>>= -bpInfixOperator()== - EQCAR( $stok,"KEY") and - GET($ttok,"SHOEINF") and bpPushId() and bpNext() -@ - -\section{License} - -<<license>>= --- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are --- met: --- --- - Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- - Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in --- the documentation and/or other materials provided with the --- distribution. --- --- - Neither the name of The Numerical ALgorithms Group Ltd. nor the --- names of its contributors may be used to endorse or promote products --- derived from this software without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -@ -<<*>>= -<<license>> - -module '"boot-parser" -import '"includer" -import '"scanner" -import '"ast" - -)package "BOOTTRAN" - - -++ true when the current function definition has its parameters -++ written round parenthesis. -$sawParenthesizedHead := false - -++ true if the current function definition has a return statement. -$bodyHasReturn := false - - -bpFirstToken()== - $stok:= - if null $inputStream - then shoeTokConstruct("ERROR","NOMORE",shoeTokPosn $stok) - else CAR $inputStream - $ttok:=shoeTokPart $stok - true - -bpFirstTok()== - $stok:= - if null $inputStream - then shoeTokConstruct("ERROR","NOMORE",shoeTokPosn $stok) - else CAR $inputStream - $ttok:=shoeTokPart $stok - $bpParenCount>0 and EQCAR($stok,"KEY") => - EQ($ttok,"SETTAB")=> - $bpCount:=$bpCount+1 - bpNext() - EQ($ttok,"BACKTAB")=> - $bpCount:=$bpCount-1 - bpNext() - EQ($ttok,"BACKSET")=> - bpNext() - true - true - -bpNext() == - $inputStream := CDR($inputStream) - bpFirstTok() - -bpNextToken() == - $inputStream := CDR($inputStream) - bpFirstToken() - -bpState()== [$inputStream,$stack,$bpParenCount,$bpCount] ---cons($inputStream,$stack) - -bpRestore(x)== - $inputStream:=CAR x - bpFirstToken() - $stack:=CADR x - $bpParenCount:=CADDR x - $bpCount:=CADDDR x - true - -bpPush x==$stack:=CONS(x,$stack) - -bpPushId()== - $stack:=CONS(bfReName $ttok,$stack) - -bpPop1()== - a:=CAR $stack - $stack:=CDR $stack - a - -bpPop2()== - a:=CADR $stack - RPLACD($stack,CDDR $stack) - a - -bpPop3()== - a:=CADDR $stack - RPLACD(CDR $stack,CDDDR $stack) - a - -bpIndentParenthesized f== - $bpCount:local:=0 - a:=$stok - if bpEqPeek "OPAREN" - then - $bpParenCount:=$bpParenCount+1 - bpNext() - if APPLY(f,nil) and bpFirstTok() and - (bpEqPeek "CPAREN" or bpParenTrap(a)) - then - $bpParenCount:=$bpParenCount-1 - bpNextToken() - $bpCount=0 => true - $inputStream:=append( bpAddTokens $bpCount,$inputStream) - bpFirstToken() - $bpParenCount=0 => - bpCancel() - true - true - else if bpEqPeek "CPAREN" - then - bpPush bfTuple [] - $bpParenCount:=$bpParenCount-1 - bpNextToken() - true - else bpParenTrap(a) - else false - -bpParenthesized f== - a:=$stok - if bpEqKey "OPAREN" - then - if APPLY(f,nil) and (bpEqKey "CPAREN" or bpParenTrap(a)) - then true - else if bpEqKey "CPAREN" - then - bpPush bfTuple [] - true - else bpParenTrap(a) - else false - -bpBracket f== - a:=$stok - if bpEqKey "OBRACK" - then - if APPLY(f,nil) and (bpEqKey "CBRACK" or bpBrackTrap(a)) - then bpPush bfBracket bpPop1 () - else if bpEqKey "CBRACK" - then bpPush [] - else bpBrackTrap(a) - else false - -bpPileBracketed f== - if bpEqKey "SETTAB" - then if bpEqKey "BACKTAB" - then true - else if APPLY(f,nil) and - (bpEqKey "BACKTAB" or bpPileTrap()) - then bpPush bfPile bpPop1() - else false - else false - -bpListof(f,str1,g)== - if APPLY(f,nil) - then - if bpEqKey str1 and (APPLY(f,nil) or bpTrap()) - then - a:=$stack - $stack:=nil - while bpEqKey str1 and (APPLY(f,nil) or bpTrap()) repeat 0 - $stack:=cons(NREVERSE $stack,a) - bpPush FUNCALL(g, [bpPop3(),bpPop2(),:bpPop1()]) - else - true - else false - - --- to do ,<backset> -bpListofFun(f,h,g)== - if APPLY(f,nil) - then - if APPLY(h,nil) and (APPLY(f,nil) or bpTrap()) - then - a:=$stack - $stack:=nil - while APPLY(h,nil) and (APPLY(f,nil) or bpTrap()) repeat 0 - $stack:=cons(NREVERSE $stack,a) - bpPush FUNCALL(g, bfListOf [bpPop3(),bpPop2(),:bpPop1()]) - else - true - else false - -bpList(f,str1,g)== - if APPLY(f,nil) - then - if bpEqKey str1 and (APPLY(f,nil) or bpTrap()) - then - a:=$stack - $stack:=nil - while bpEqKey str1 and (APPLY(f,nil) or bpTrap()) repeat 0 - $stack:=cons(NREVERSE $stack,a) - bpPush FUNCALL(g, [bpPop3(),bpPop2(),:bpPop1()]) - else - bpPush FUNCALL(g, [bpPop1()]) - else bpPush FUNCALL(g, []) - -bpOneOrMore f== - APPLY(f,nil)=> - a:=$stack - $stack:=nil - while APPLY(f,nil) repeat 0 - $stack:=cons(NREVERSE $stack,a) - bpPush cons(bpPop2(),bpPop1()) - false - - --- s must transform the head of the stack -bpAnyNo s== - while APPLY(s,nil) repeat 0 - true - - --- AndOr(k,p,f)= k p -bpAndOr(keyword,p,f)== - bpEqKey keyword and (APPLY(p,nil) or bpTrap()) - and bpPush FUNCALL(f, bpPop1()) - -bpConditional f== - if bpEqKey "IF" and (bpWhere() or bpTrap()) and - (bpEqKey "BACKSET" or true) - then - if bpEqKey "SETTAB" - then if bpEqKey "THEN" - then (APPLY(f,nil) or bpTrap()) and bpElse(f) and bpEqKey "BACKTAB" - else bpMissing "THEN" - else if bpEqKey "THEN" - then (APPLY(f,nil) or bpTrap()) and bpElse(f) - else bpMissing "then" - else false - -bpElse(f)== - a:=bpState() - if bpBacksetElse() - then (APPLY(f,nil) or bpTrap()) and - bpPush bfIf(bpPop3(),bpPop2(),bpPop1()) - else - bpRestore a - bpPush bfIfThenOnly(bpPop2(),bpPop1()) - -bpBacksetElse()== - if bpEqKey "BACKSET" - then bpEqKey "ELSE" - else bpEqKey "ELSE" - -bpEqPeek s == EQCAR($stok,"KEY") and EQ(s,$ttok) - -bpEqKey s == EQCAR($stok,"KEY") and EQ(s,$ttok) and bpNext() -bpEqKeyNextTok s == EQCAR($stok,"KEY") and EQ(s,$ttok) and - bpNextToken() - -bpPileTrap() == bpMissing "BACKTAB" -bpBrackTrap(x) == bpMissingMate("]",x) -bpParenTrap(x) == bpMissingMate(")",x) - -bpMissingMate(close,open)== - bpSpecificErrorAtToken(open, '"possibly missing mate") - bpMissing close - -bpMissing s== - bpSpecificErrorHere(CONCAT(PNAME s,'" possibly missing")) - THROW("TRAPPOINT","TRAPPED") - -bpCompMissing s == bpEqKey s or bpMissing s - -bpTrap()== - bpGeneralErrorHere() - THROW("TRAPPOINT","TRAPPED") - -bpRecoverTrap()== - bpFirstToken() - pos1 := shoeTokPosn $stok - bpMoveTo 0 - pos2 := shoeTokPosn $stok - bpIgnoredFromTo(pos1, pos2) - bpPush [['"pile syntax error"]] - -bpListAndRecover(f)== - a:=$stack - b:=nil - $stack:=nil - done:=false - c:=$inputStream - while not done repeat --- $trapped:local:=false - found:=CATCH("TRAPPOINT",APPLY(f,nil)) - if found="TRAPPED" - then - $inputStream:=c - bpRecoverTrap() - else if not found - then - $inputStream:=c - bpGeneralErrorHere() - bpRecoverTrap() - if bpEqKey "BACKSET" - then - c:=$inputStream - else if bpEqPeek "BACKTAB" or null $inputStream - then - done:=true - else - $inputStream:=c - bpGeneralErrorHere() - bpRecoverTrap() - if bpEqPeek "BACKTAB" or null $inputStream - then done:=true - else - bpNext() - c:=$inputStream - b:=cons(bpPop1(),b) - $stack:=a - bpPush NREVERSE b - -bpMoveTo n== - null $inputStream => true - bpEqPeek "BACKTAB" => - n=0 => true - bpNextToken() - $bpCount:=$bpCount-1 - bpMoveTo(n-1) - bpEqPeek "BACKSET" => - n=0 => true - bpNextToken() - bpMoveTo n - bpEqPeek "SETTAB" => - bpNextToken() - bpMoveTo(n+1) - bpEqPeek "OPAREN" => - bpNextToken() - $bpParenCount:=$bpParenCount+1 - bpMoveTo n - bpEqPeek "CPAREN" => - bpNextToken() - $bpParenCount:=$bpParenCount-1 - bpMoveTo n - bpNextToken() - bpMoveTo n - -<<Name>> - -<<Constant>> - -++ Parse a module definitoin -++ Module: -++ MODULE QUOTE String -bpModule() == - bpEqKey "MODULE" => - -- we really want to check that the next token is indeed - -- a string. For the moment, we delay the type checking - -- to the Lisp compiler/interpreter. That is likely to - -- cause cryptic diagnostics. To be fixed. - bpConstTok() and bpPush Module bpPop1() - false - -++ Parse a module import, or a import declaration for a foreign entity. -++ Import: -++ IMPORT Name for Signature -++ IMPORT QUOTE String -bpImport() == - bpEqKey "IMPORT" => - (bpName() and (bpEqKey "FOR" or bpTrap()) and bpSignature() - and bpPush ImportSignature(bpPop2(), bpPop1())) - or - -- we really want to check that the next token is indeed - -- a string. For the moment, we delay the type checking - -- to the Lisp compiler/interpreter. That is likely to - -- cause cryptic diagnostics. To be fixed. - (bpConstTok() and bpPush Import bpPop1()) - false - --- Parse a type alias defnition: --- type-alias-definition: --- identifier <=> logical-expression -bpTypeAliasDefition() == - (bpName() or bpTrap()) and - bpEqKey "TDEF" and bpLogical() and - bpPush TypeAlias(bpPop2(), nil, bpPop1()) - -++ Parse a signature declaration -++ Signature: -++ Name COLON Mapping -bpSignature() == - bpName() and bpEqKey "COLON" and bpMapping() - and bpPush Signature(bpPop2(), bpPop1()) - -++ Parse a mapping expression -++ Mapping: -++ (Name | IdList) -> Name -bpMapping() == - (bpName() or bpIdList()) and bpEqKey "ARROW" and bpName() - and bpPush Mapping(bpPop1(), bpPop1()) - -bpCancel()== - a:=bpState() - if bpEqKeyNextTok "SETTAB" - then if bpCancel() - then if bpEqKeyNextTok "BACKTAB" - then true - else - bpRestore a - false - else - if bpEqKeyNextTok "BACKTAB" - then true - else - bpRestore a - false - else false -bpAddTokens n== - n=0 => nil - n>0=> cons(shoeTokConstruct("KEY","SETTAB",shoeTokPosn $stok),bpAddTokens(n-1)) - cons(shoeTokConstruct("KEY","BACKTAB",shoeTokPosn $stok),bpAddTokens(n+1)) - -bpExceptions()== - bpEqPeek "DOT" or bpEqPeek "QUOTE" or - bpEqPeek "OPAREN" or bpEqPeek "CPAREN" or - bpEqPeek "SETTAB" or bpEqPeek "BACKTAB" - or bpEqPeek "BACKSET" - - -bpSexpKey()== - EQCAR( $stok,"KEY") and not bpExceptions()=> - a:=GET($ttok,"SHOEINF") - null a=> bpPush $ttok and bpNext() - bpPush a and bpNext() - false - -bpAnyId()== - bpEqKey "MINUS" and (EQCAR($stok,"INTEGER") or bpTrap()) and - bpPush MINUS $ttok and bpNext() or - bpSexpKey() or - MEMQ(shoeTokType $stok, '(ID INTEGER STRING FLOAT)) - and bpPush $ttok and bpNext() - -bpSexp()== - bpAnyId() or - bpEqKey "QUOTE" and (bpSexp() or bpTrap()) - and bpPush bfSymbol bpPop1() or - bpIndentParenthesized function bpSexp1 - -bpSexp1()== bpFirstTok() and - bpSexp() and - (bpEqKey "DOT" and bpSexp() and bpPush CONS (bpPop2(),bpPop1())or - bpSexp1() and bpPush CONS (bpPop2(),bpPop1())) or - bpPush nil - -bpPrimary1() == - bpName() or - bpDot() or - bpConstTok() or - bpConstruct() or - bpCase() or - bpStruct() or - bpPDefinition() or - bpBPileDefinition() - -bpPrimary()== bpFirstTok() and (bpPrimary1() or bpPrefixOperator()) - -<<Dot>> - -<<PrefixOperator>> - -<<InfixOperator>> - -bpSelector()== - bpEqKey "DOT" and (bpPrimary() - and bpPush(bfElt(bpPop2(),bpPop1())) - or bpPush bfSuffixDot bpPop1() ) - -bpOperator()== bpPrimary() and bpAnyNo function bpSelector - -bpApplication()== - bpPrimary() and bpAnyNo function bpSelector and - (bpApplication() and - bpPush(bfApplication(bpPop2(),bpPop1())) or true) - -bpTagged()== - bpApplication() and - (bpEqKey "COLON" and (bpApplication() or bpTrap()) and - bpPush bfTagged(bpPop2(),bpPop1()) or true) - -bpExpt()== bpRightAssoc('(POWER),function bpTagged) - -bpInfKey s== - EQCAR( $stok,"KEY") and - MEMBER($ttok,s) and bpPushId() and bpNext() - -bpInfGeneric s== bpInfKey s and (bpEqKey "BACKSET" or true) - -bpRightAssoc(o,p)== - a:=bpState() - if APPLY(p,nil) - then - while bpInfGeneric o and (bpRightAssoc(o,p) or bpTrap()) repeat - bpPush bfInfApplication(bpPop2(),bpPop2(),bpPop1()) - true - else - bpRestore a - false - -bpLeftAssoc(operations,parser)== - if APPLY(parser,nil) - then - while bpInfGeneric(operations) and - (APPLY(parser,nil) or bpTrap()) - repeat - bpPush bfInfApplication(bpPop2(),bpPop2(),bpPop1()) - true - else false - -bpString()== - EQ(shoeTokType $stok,"STRING") and - bpPush(["QUOTE",INTERN $ttok]) and bpNext() - -bpThetaName() == - if EQCAR( $stok,"ID") and GET($ttok,"SHOETHETA") - then - bpPushId() - bpNext() - else false - -bpReduceOperator()== - bpInfixOperator() or bpString() - or bpThetaName() - -bpReduce()== - a:=bpState() - if bpReduceOperator() and bpEqKey "SLASH" - then - bpEqPeek "OBRACK" => (bpDConstruct() or bpTrap()) and - bpPush bfReduceCollect(bpPop2(),bpPop1()) - (bpApplication() or bpTrap()) and - bpPush bfReduce(bpPop2(),bpPop1()) - else - bpRestore a - false - -bpTimes()== - bpReduce() or bpLeftAssoc('(TIMES SLASH),function bpExpt) - -bpMinus()== - bpInfGeneric '(MINUS) and (bpTimes() or bpTrap()) - and bpPush(bfApplication(bpPop2(),bpPop1())) - or bpTimes() - -bpArith()==bpLeftAssoc('(PLUS MINUS),function bpMinus) - -bpIs()== - bpArith() and (bpInfKey '(IS ISNT) and (bpPattern() or bpTrap()) - and bpPush bfISApplication(bpPop2(),bpPop2(),bpPop1()) - or true) - -bpBracketConstruct(f)== - bpBracket f and bpPush bfConstruct bpPop1 () - -bpCompare()== - bpIs() and (bpInfKey '(SHOEEQ SHOENE LT LE GT GE IN) - and (bpIs() or bpTrap()) - and bpPush bfInfApplication(bpPop2(),bpPop2(),bpPop1()) - or true) - -bpAnd()== bpLeftAssoc('(AND),function bpCompare) - - -++ Note the fact that a return statement is used in the body -++ of current function definition. -bpNoteReturnStmt() == - $bodyHasReturn := true - true - -bpReturn()== - (bpEqKey "RETURN" and bpNoteReturnStmt() and - (bpAnd() or bpTrap()) and - bpPush bfReturnNoName bpPop1()) or bpAnd() - - -bpLogical()== bpLeftAssoc('(OR),function bpReturn) - -bpExpression()== - bpEqKey "COLON" and (bpLogical() and - bpPush bfApplication ("COLON",bpPop1()) - or bpTrap()) or bpLogical() - -bpStatement()== - bpConditional function bpWhere or bpLoop() or bpExpression() - -bpLoop()== - bpIterators() and - (bpCompMissing "REPEAT" and - (bpWhere() or bpTrap()) and - bpPush bfLp(bpPop2(),bpPop1())) - or - bpEqKey "REPEAT" and (bpLogical() or bpTrap()) and - bpPush bfLoop1 bpPop1 () - -bpSuchThat()==bpAndOr("BAR",function bpWhere,function bfSuchthat) - -bpWhile()==bpAndOr ("WHILE",function bpLogical,function bfWhile) - -bpUntil()==bpAndOr ("UNTIL",function bpLogical,function bfUntil) - -bpForIn()== - bpEqKey "FOR" and (bpVariable() or bpTrap()) and (bpCompMissing "IN") - and ((bpSeg() or bpTrap()) and - (bpEqKey "BY" and (bpArith() or bpTrap()) and - bpPush bfForInBy(bpPop3(),bpPop2(),bpPop1())) or - bpPush bfForin(bpPop2(),bpPop1())) - -bpSeg()== - bpArith() and - (bpEqKey "SEG" and - (bpArith() and bpPush(bfSegment2(bpPop2(),bpPop1())) - or bpPush(bfSegment1(bpPop1()))) or true) - -bpIterator()== - bpForIn() or bpSuchThat() or bpWhile() or bpUntil() - -bpIteratorList()==bpOneOrMore function bpIterator - and bpPush bfIterators bpPop1 () - -bpCrossBackSet()== bpEqKey "CROSS" and (bpEqKey "BACKSET" or true) - -bpIterators()== - bpListofFun(function bpIteratorList, - function bpCrossBackSet,function bfCross) - -bpAssign()== - a:=bpState() - if bpStatement() - then - if bpEqPeek "BEC" - then - bpRestore a - bpAssignment() or bpTrap() - else true - else - bpRestore a - false - -bpAssignment()== - bpAssignVariable() and - bpEqKey "BEC" and - (bpAssign() or bpTrap()) and - bpPush bfAssign (bpPop2(),bpPop1()) - --- should only be allowed in sequences -bpExit()== - bpAssign() and (bpEqKey "EXIT" and - ((bpWhere() or bpTrap()) and - bpPush bfExit (bpPop2(),bpPop1())) - or true) - -++ returns true if the next token introduces a definition. -bpBeginDefinition() == - bpEqPeek "DEF" or - $sawParenthesizedHead and bpEqPeek "COLON" - -bpDefinition()== - a:=bpState() - bpExit() => - bpBeginDefinition() => - bpRestore a - bpDef() - bpEqPeek "TDEF" => - bpRestore a - bpTypeAliasDefition() - bpEqPeek "MDEF" => - bpRestore a - bpMdef() - true - bpRestore a - false - -bpStoreName()== - $op := car $stack - $wheredefs := nil - $typings := nil - $returnType := true -- assume we may return anything - $bodyHasReturn := false - true - -bpReturnType() == - -- a return type is acceptable for a function definition only - -- if its parameters are written in round parenthesis. - -- In particular, we reject the situation `foo x:Integer == ...' - $sawParenthesizedHead and bpEqKey "COLON" => - bpApplication() or bpTrap() - $returnType := bpPop1() - true - true - -bpDef() == - bpName() and bpStoreName() and - bpDefTail() and bpPush bfCompDef bpPop1 () - -bpDDef() == bpName() and bpDefTail() - -++ Parse the remaining of a simple definition. -bpSimpleDefinitionTail() == - bpEqKey "DEF" and - (bpWhere() or bpTrap()) - and bpPush ConstantDefinition(bpPop2(), bpPop1()) - -++ Parse the remaining of a compound definition. -bpCompoundDefinitionTail() == - bpVariable() and bpReturnType() and - bpEqKey "DEF" and (bpWhere() or bpTrap()) - and bpPush bfDefinition(bpPop3(),bpPop2(),bpPop1()) - - -++ Parse the remainding of a definition. When we reach this point -++ we know we must parse a definition and we have already parsed -++ the name of the main operator in the definition. -bpDefTail() == - bpSimpleDefinitionTail() - or bpCompoundDefinitionTail() - - -bpMDefTail()== - -- bpEqKey "MDEF" and - -- (bpWhere() or bpTrap()) - -- and bpPush bfMDefinition1(bpPop2(),bpPop1()) - -- or - (bpVariable() or bpTrap()) and - bpEqKey "MDEF" and (bpWhere() or bpTrap()) - and bpPush bfMDefinition(bpPop3(),bpPop2(),bpPop1()) - -bpMdef()== bpName() and bpStoreName() and bpMDefTail() - -bpWhere()== - bpDefinition() and - (bpEqKey "WHERE" and (bpDefinitionItem() or bpTrap()) - and bpPush bfWhere(bpPop1(),bpPop1()) or true) - -bpDefinitionItem()== - a:=bpState() - if bpDDef() - then true - else - bpRestore a - if bpBDefinitionPileItems() - then true - else - bpRestore a - if bpPDefinitionItems() - then true - else - bpRestore a - bpWhere() - -bpDefinitionPileItems()== - bpListAndRecover function bpDefinitionItem - and bpPush bfDefSequence bpPop1() - -bpBDefinitionPileItems()== bpPileBracketed function bpDefinitionPileItems - -bpSemiColonDefinition()==bpSemiListing - (function bpDefinitionItem,function bfDefSequence) - -bpPDefinitionItems()==bpParenthesized function bpSemiColonDefinition - -bpComma()== - bpModule() or bpImport() or - bpTuple function bpWhere - -bpTuple(p)==bpListofFun(p,function bpCommaBackSet,function bfTuple) - -bpCommaBackSet()== bpEqKey "COMMA" and (bpEqKey "BACKSET" or true) - -bpSemiColon()==bpSemiListing (function bpComma,function bfSequence) - -bpSemiListing(p,f)==bpListofFun(p,function bpSemiBackSet,f) - -bpSemiBackSet()== bpEqKey "SEMICOLON" and (bpEqKey "BACKSET" or true) - -bpPDefinition()== bpIndentParenthesized function bpSemiColon - -bpPileItems()== - bpListAndRecover function bpSemiColon and bpPush bfSequence bpPop1() - -bpBPileDefinition()== bpPileBracketed function bpPileItems - -bpIteratorTail()== - (bpEqKey "REPEAT" or true) and bpIterators() - ---bpExpression()== bpLogical() - -bpConstruct()==bpBracket function bpConstruction - -bpConstruction()== - bpComma() and - (bpIteratorTail() and - bpPush bfCollect (bpPop2(),bpPop1()) or - bpPush bfTupleConstruct bpPop1()) - -bpDConstruct()==bpBracket function bpDConstruction - -bpDConstruction()== - bpComma() and - (bpIteratorTail() and - bpPush bfDCollect (bpPop2(),bpPop1()) or - bpPush bfDTuple bpPop1()) - - - ---PATTERN - ---bpNameOrDot() == bpName() or bpDot() or bpEqual() - -bpPattern()== bpBracketConstruct function bpPatternL - or bpName() or bpConstTok() - -bpEqual()== - bpEqKey "SHOEEQ" and (bpApplication() or bpConstTok() or - bpTrap()) and bpPush bfEqual bpPop1() - -bpRegularPatternItem() == - bpEqual() or - bpConstTok() or bpDot() or - bpName() and - ((bpEqKey "BEC" and (bpPattern() or bpTrap()) - and bpPush bfAssign(bpPop2(),bpPop1())) or true) - or bpBracketConstruct function bpPatternL - -bpRegularPatternItemL()== - bpRegularPatternItem() and bpPush [bpPop1()] - -bpRegularList()== - bpListof(function bpRegularPatternItemL,"COMMA",function bfAppend) - -bpPatternColon()== - bpEqKey "COLON" and (bpRegularPatternItem() or bpTrap()) - and bpPush [bfColon bpPop1()] - - --- only one colon -bpPatternL() == bpPatternList() and bpPush bfTuple bpPop1() - -bpPatternList()== - if bpRegularPatternItemL() - then - while (bpEqKey "COMMA" and (bpRegularPatternItemL() or - (bpPatternTail() - and bpPush append(bpPop2(),bpPop1()) - or bpTrap();false) )) repeat - bpPush append(bpPop2(),bpPop1()) - true - else bpPatternTail() - -bpPatternTail()== - bpPatternColon() and - (bpEqKey "COMMA" and (bpRegularList() or bpTrap()) - and bpPush append (bpPop2(),bpPop1()) or true) - --- BOUND VARIABLE -bpRegularBVItem() == - bpBVString() or - bpConstTok() or - (bpName() and - (bpEqKey "COLON" and (bpApplication() or bpTrap()) - and bpPush bfTagged(bpPop2(), bpPop1()) or - bpEqKey "BEC" and (bpPattern() or bpTrap()) - and bpPush bfAssign(bpPop2(),bpPop1()) or - (bpEqKey "IS" and (bpPattern() or bpTrap()) - and bpPush bfAssign(bpPop2(),bpPop1())) or true)) - or bpBracketConstruct function bpPatternL - -bpBVString()== - EQ(shoeTokType $stok,"STRING") and - bpPush(["BVQUOTE",INTERN $ttok]) and bpNext() - -bpRegularBVItemL() == - bpRegularBVItem() and bpPush [bpPop1()] - -bpColonName()== - bpEqKey "COLON" and (bpName() or bpBVString() or bpTrap()) - - --- at most one colon at end -bpBoundVariablelist()== - if bpRegularBVItemL() - then - while (bpEqKey "COMMA" and (bpRegularBVItemL() or - (bpColonName() - and bpPush bfColonAppend(bpPop2(),bpPop1()) - or bpTrap();false) )) repeat - bpPush append(bpPop2(),bpPop1()) - true - else bpColonName() and bpPush bfColonAppend(nil,bpPop1()) - - -++ Mark the start of parameter list enclosed in round parenthesis -bpBeginParameterList() == - $sawParenthesizedHead := false - true - -++ Mark the end of parameter list enclosed in round parenthesis -bpEndParameterList() == - $sawParenthesizedHead := true - -bpVariable()== - bpBeginParameterList() and - bpParenthesized function bpBoundVariablelist and - bpPush bfTupleIf bpPop1() and bpEndParameterList() - or bpBracketConstruct function bpPatternL - or bpName() or bpConstTok() - -bpAssignVariable()== - bpBracketConstruct function bpPatternL or bpAssignLHS() - -bpAssignLHS()== - bpName() and (bpEqKey "COLON" and (bpApplication() or bpTrap()) - and bpPush bfLocal(bpPop2(),bpPop1()) - or bpEqKey "DOT" and bpList(function bpPrimary,"DOT", - function bfListOf) - and bpChecknull() and - bpPush bfTuple(cons(bpPop2(),bpPop1())) - or true) -bpChecknull()== - a:=bpPop1() - if null a - then bpTrap() - else bpPush a - -bpStruct()== - bpEqKey "STRUCTURE" and - (bpName() or bpTrap()) and - (bpEqKey "DEF" or bpTrap()) and - bpTypeList() and bpPush bfStruct(bpPop2(),bpPop1()) - -bpTypeList() == bpPileBracketed function bpTypeItemList - or bpTerm() and bpPush [bpPop1()] - -bpTypeItemList() == bpListAndRecover function bpTerm - -bpTerm() == - (bpName() or bpTrap()) and - ((bpParenthesized function bpIdList and - bpPush bfNameArgs (bpPop2(),bpPop1())) - or bpName() and bpPush bfNameArgs(bpPop2(),bpPop1())) - or bpPush(bfNameOnly bpPop1()) - -bpIdList()== bpTuple function bpName - -bpCase()== - bpEqKey "CASE" and - (bpWhere() or bpTrap()) and - (bpEqKey "OF" or bpMissing "OF") and - bpPiledCaseItems() - -bpPiledCaseItems()== - bpPileBracketed function bpCaseItemList and - bpPush bfCase(bpPop2(),bpPop1()) -bpCaseItemList()== - bpListAndRecover function bpCaseItem - -bpCaseItem()== - (bpTerm() or bpTrap()) and - (bpEqKey "EXIT" or bpTrap()) and - (bpWhere() or bpTrap()) and - bpPush bfCaseItem (bpPop2(),bpPop1()) - -@ - - -\section{The Common Lisp translation} -\label{sec:cl-translation} - -<<parser.clisp>>= (EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-parser")) (IMPORT-MODULE "includer") @@ -1655,7 +514,10 @@ bpCaseItem()== (RETURN (COND ((|bpEqKey| 'IMPORT) - (AND (|bpConstTok|) (|bpPush| (|Import| (|bpPop1|))))) + (OR (AND (|bpName|) (OR (|bpEqKey| 'FOR) (|bpTrap|)) + (|bpSignature|) + (|bpPush| (|ImportSignature| (|bpPop2|) (|bpPop1|)))) + (AND (|bpConstTok|) (|bpPush| (|Import| (|bpPop1|)))))) ('T NIL))))) (DEFUN |bpTypeAliasDefition| () @@ -1664,6 +526,18 @@ bpCaseItem()== (AND (OR (|bpName|) (|bpTrap|)) (|bpEqKey| 'TDEF) (|bpLogical|) (|bpPush| (|TypeAlias| (|bpPop2|) NIL (|bpPop1|))))))) +(DEFUN |bpSignature| () + (PROG () + (RETURN + (AND (|bpName|) (|bpEqKey| 'COLON) (|bpMapping|) + (|bpPush| (|Signature| (|bpPop2|) (|bpPop1|))))))) + +(DEFUN |bpMapping| () + (PROG () + (RETURN + (AND (OR (|bpName|) (|bpIdList|)) (|bpEqKey| 'ARROW) (|bpName|) + (|bpPush| (|Mapping| (|bpPop1|) (|bpPop1|))))))) + (DEFUN |bpCancel| () (PROG (|a|) (RETURN @@ -2455,6 +1329,3 @@ bpCaseItem()== (OR (|bpWhere|) (|bpTrap|)) (|bpPush| (|bfCaseItem| (|bpPop2|) (|bpPop1|))))))) -@ - -\end{document} diff --git a/src/boot/pile.boot.pamphlet b/src/boot/strap/pile.clisp index eaad129f..caa56d3e 100644 --- a/src/boot/pile.boot.pamphlet +++ b/src/boot/strap/pile.clisp @@ -1,171 +1,3 @@ -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/pile.boot} Pamphlet} -\author{The Axiom Team} - -\begin{document} -\maketitle - -\begin{abstract} -\end{abstract} - -\eject -\tableofcontents -\eject - -\section{License} - -<<license>>= --- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are --- met: --- --- - Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- - Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in --- the documentation and/or other materials provided with the --- distribution. --- --- - Neither the name of The Numerical ALgorithms Group Ltd. nor the --- names of its contributors may be used to endorse or promote products --- derived from this software without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -@ -<<*>>= -<<license>> - -module '"boot-pile" -import '"includer" -import '"scanner" - -)package "BOOTTRAN" -shoeFirstTokPosn t== shoeTokPosn CAAR t -shoeLastTokPosn t== shoeTokPosn CADR t -shoePileColumn t==CDR shoeTokPosn CAAR t - --- s is a token-dq-stream - -shoePileInsert (s)== - if bStreamNull s - then cons([],s) - else - toktype:=shoeTokType CAAAR s - if toktype ="LISP" or toktype = "LINE" - then cons([car s],cdr s) - else - a:=shoePileTree(-1,s) - cons([a.2],a.3) - -shoePileTree(n,s)== - if bStreamNull s - then [false,n,[],s] - else - [h,t]:=[car s,cdr s] - hh:=shoePileColumn h - if hh > n - then shoePileForests(h,hh,t) - else [false,n,[],s] - -eqshoePileTree(n,s)== - if bStreamNull s - then [false,n,[],s] - else - [h,t]:=[car s,cdr s] - hh:=shoePileColumn h - if hh = n - then shoePileForests(h,hh,t) - else [false,n,[],s] - -shoePileForest(n,s)== - [b,hh,h,t]:= shoePileTree(n,s) - if b - then - [h1,t1]:=shoePileForest1(hh,t) - [cons(h,h1),t1] - else [[],s] - -shoePileForest1(n,s)== - [b,n1,h,t]:= eqshoePileTree(n,s) - if b - then - [h1,t1]:=shoePileForest1(n,t) - [cons(h,h1),t1] - else [[],s] - -shoePileForests(h,n,s)== - [h1,t1]:=shoePileForest(n,s) - if bStreamNull h1 - then [true,n,h,s] - else shoePileForests(shoePileCtree(h,h1),n,t1) - -shoePileCtree(x,y)==dqAppend(x,shoePileCforest y) - --- only enshoePiles forests with >=2 trees - -shoePileCforest x== - if null x - then [] - else if null cdr x - then car x - else - a:=car x - b:=shoePileCoagulate(a,rest x) - if null cdr b - then car b - else shoeEnPile shoeSeparatePiles b - -shoePileCoagulate(a,b)== - if null b - then [a] - else - c:=car b - if EQ(shoeTokPart CAAR c,"THEN") or EQ(shoeTokPart CAAR c,"ELSE") - then shoePileCoagulate (dqAppend(a,c),cdr b) - else - d:=CADR a - e:=shoeTokPart d - if EQCAR(d,"KEY") and - (GET(e,"SHOEINF") or EQ(e,"COMMA") or EQ(e,"SEMICOLON")) - then shoePileCoagulate(dqAppend(a,c),cdr b) - else cons(a,shoePileCoagulate(c,rest b)) - -shoeSeparatePiles x== - if null x - then [] - else if null cdr x - then car x - else - a:=car x - semicolon:=dqUnit - shoeTokConstruct("KEY", "BACKSET",shoeLastTokPosn a) - dqConcat [a,semicolon,shoeSeparatePiles cdr x] - -shoeEnPile x== - dqConcat [dqUnit shoeTokConstruct("KEY","SETTAB",shoeFirstTokPosn x), - x, _ - dqUnit shoeTokConstruct("KEY","BACKTAB",shoeLastTokPosn x)] - -@ - -<<pile.clisp>>= (EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-pile")) (IMPORT-MODULE "includer") @@ -320,6 +152,3 @@ shoeEnPile x== (|shoeTokConstruct| 'KEY 'BACKTAB (|shoeLastTokPosn| |x|)))))))) -@ - -\end{document} diff --git a/src/boot/scanner.boot.pamphlet b/src/boot/strap/scanner.clisp index b6bc1175..50078c3d 100644 --- a/src/boot/scanner.boot.pamphlet +++ b/src/boot/strap/scanner.clisp @@ -1,537 +1,3 @@ -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/scanner.boot} Pamphlet} -\author{The Axiom Team} - -\begin{document} -\maketitle -\begin{abstract} -\end{abstract} -\eject -\tableofcontents -\eject - -\section{License} - -<<license>>= --- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are --- met: --- --- - Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- - Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in --- the documentation and/or other materials provided with the --- distribution. --- --- - Neither the name of The Numerical ALgorithms Group Ltd. nor the --- names of its contributors may be used to endorse or promote products --- derived from this software without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -@ - -<<*>>= -<<license>> - -module '"boot-lexer" -import '"tokens" -import '"includer" - -)package "BOOTTRAN" - --- converts X to double-float. -double x == - FLOAT(x, 1.0) - -dqUnit s==(a:=[s];CONS(a,a)) - -dqAppend(x,y)== - if null x - then y - else if null y - then x - else - RPLACD (CDR x,CAR y) - RPLACD (x, CDR y) - x - -dqConcat ld== - if null ld - then nil - else if null rest ld - then first ld - else dqAppend(first ld,dqConcat rest ld) - -dqToList s==if null s then nil else CAR s - -shoeConstructToken(ln,lp,b,n)==[b.0,b.1,:cons(lp,n)] -shoeTokType x== CAR x -shoeTokPart x== CADR x -shoeTokPosn x== CDDR x -shoeTokConstruct(x,y,z)==[x,y,:z] - -shoeNextLine(s)== - if bStreamNull s - then false - else - $linepos:=s - $f:= CAR s - $r:= CDR s - $ln:=CAR $f - $n:=STRPOSL('" ",$ln,0,true) - $sz :=# $ln - null $n => true - QENUM($ln,$n)=shoeTAB => - a:=MAKE_-FULL_-CVEC (7-REM($n,8) ,'" ") - $ln.$n:='" ".0 - $ln:=CONCAT(a,$ln) - s1:=cons(cons($ln,CDR $f),$r) - shoeNextLine s1 - true - -shoeLineToks(s)== - $f: local:=nil - $r:local :=nil - $ln:local :=nil - $n:local:=nil - $sz:local := nil - $floatok:local:=true - $linepos:local:=s - not shoeNextLine s => CONS(nil,nil) - null $n => shoeLineToks $r - fst:=QENUM($ln,0) - EQL(fst,shoeCLOSEPAREN)=> - command:=shoeLine? $ln=> - dq:=dqUnit shoeConstructToken - ($ln,$linepos,shoeLeafLine command,0) - cons([dq],$r) - command:=shoeLisp? $ln=> shoeLispToken($r,command) - command:=shoePackage? $ln=> - -- z:=car shoeBiteOff command - a:=CONCAT('"(IN-PACKAGE ",command,'")") - dq:=dqUnit shoeConstructToken - ($ln,$linepos,shoeLeafLisp a,0) - cons([dq],$r) - shoeLineToks $r - toks:=[] - while $n<$sz repeat toks:=dqAppend(toks,shoeToken()) - null toks => shoeLineToks $r - cons([toks],$r) - -shoeLispToken(s,string)== - string:= - # string=0 or EQL(QENUM(string,0),QENUM('";",0))=> '"" - string - ln:=$ln - linepos:=$linepos - [r,:st]:=shoeAccumulateLines(s,string) - dq:=dqUnit shoeConstructToken(ln,linepos,shoeLeafLisp st,0) - cons([dq],r) - -shoeAccumulateLines(s,string)== - not shoeNextLine s => CONS(s,string) - null $n => shoeAccumulateLines($r,string) - # $ln=0 => shoeAccumulateLines($r,string) - fst:=QENUM($ln,0) - EQL(fst,shoeCLOSEPAREN)=> - command:=shoeLisp? $ln - command and #command>0 => - EQL(QENUM(command,0),QENUM('";",0))=> - shoeAccumulateLines($r,string) - a:=STRPOS('";",command,0,nil) - a=> - shoeAccumulateLines($r, - CONCAT(string,SUBSTRING(command,0,a-1))) - shoeAccumulateLines($r,CONCAT(string,command)) - shoeAccumulateLines($r,string) - CONS(s,string) - --- returns true if token t is closing `parenthesis'. -shoeCloser t == - MEMQ(shoeKeyWord t, '(CPAREN CBRACK)) - -shoeToken () == - ln:=$ln - c:=QENUM($ln,$n) - linepos:=$linepos - n:=$n - ch:=$ln.$n - b:= - shoeStartsComment() => - shoeComment() - [] - shoeStartsNegComment() => - shoeNegComment() - [] - c=shoeLispESCAPE => - shoeLispEscape() - shoePunctuation c => shoePunct () - shoeStartsId ch => shoeWord (false) - c=shoeSPACE => - shoeSpace () - [] - c = shoeSTRING_CHAR => shoeString () - shoeDigit ch => shoeNumber () - c=shoeESCAPE => shoeEscape() - c=shoeTAB => - $n:=$n+1 - [] - shoeError () - null b => nil - dqUnit shoeConstructToken(ln,linepos,b,n) - --- to pair badge and badgee -shoeLeafId x== ["ID",INTERN x] - -shoeLeafKey x==["KEY",shoeKeyWord x] - -shoeLeafInteger x==["INTEGER",shoeIntValue x] - -shoeLeafFloat(a,w,e)== - b:=shoeIntValue CONCAT(a,w) - c:= double b * EXPT(double 10, e-#w) - ["FLOAT",c] - -shoeLeafString x == ["STRING",x] - -shoeLeafLisp x == ["LISP",x] -shoeLeafLispExp x == ["LISPEXP",x] - -shoeLeafLine x == ["LINE",x] - -shoeLeafComment x == ["COMMENT", x] - -shoeLeafNegComment x== ["NEGCOMMENT", x] - -shoeLeafError x == ["ERROR",x] - -shoeLeafSpaces x == ["SPACES",x] - -shoeLispEscape()== - $n:=$n+1 - if $n>=$sz - then - SoftShoeError(cons($linepos,$n),'"lisp escape error") - shoeLeafError ($ln.$n) - else - a:=shoeReadLispString($ln,$n) - null a => - SoftShoeError(cons($linepos,$n),'"lisp escape error") - shoeLeafError ($ln.$n) - [exp,n]:=a - null n => - $n:= $sz - shoeLeafLispExp exp - $n:=n - shoeLeafLispExp exp -shoeEscape()== - $n:=$n+1 - a:=shoeEsc() - if a then shoeWord true else nil - -shoeEsc()== - if $n>=$sz - then if shoeNextLine($r) - then - while null $n repeat shoeNextLine($r) - shoeEsc() - false - else false - else - n1:=STRPOSL('" ",$ln,$n,true) - if null n1 - then - shoeNextLine($r) - while null $n repeat shoeNextLine($r) - shoeEsc() - false - else true - -shoeStartsComment()== - if $n<$sz - then - if QENUM($ln,$n)=shoePLUSCOMMENT - then - www:=$n+1 - if www>=$sz - then false - else QENUM($ln,www) = shoePLUSCOMMENT - else false - else false - -shoeStartsNegComment()== - if $n< $sz - then - if QENUM($ln,$n)=shoeMINUSCOMMENT - then - www:=$n+1 - if www>=$sz - then false - else QENUM($ln,www) = shoeMINUSCOMMENT - else false - else false - -shoeNegComment()== - n:=$n - $n:=$sz - shoeLeafNegComment SUBSTRING($ln,n,nil) - -shoeComment()== - n:=$n - $n:=$sz - shoeLeafComment SUBSTRING($ln,n,nil) - -shoePunct()== - sss:=shoeMatch($ln,$n) - $n:=$n+#sss - shoeKeyTr sss - -shoeKeyTr w== - if EQ(shoeKeyWord w,"DOT") - then if $floatok - then shoePossFloat(w) - else shoeLeafKey w - else - $floatok:=not shoeCloser w - shoeLeafKey w - -shoePossFloat (w)== - if $n>=$sz or not shoeDigit $ln.$n - then shoeLeafKey w - else - w:=shoeInteger() - shoeExponent('"0",w) - - -shoeSpace()== - n:=$n - $n:=STRPOSL('" ",$ln,$n,true) - $floatok:=true - if null $n - then - shoeLeafSpaces 0 - $n:= # $ln - else shoeLeafSpaces ($n-n) - -shoeString()== - $n:=$n+1 - $floatok:=false - shoeLeafString shoeS () - -shoeS()== - if $n>=$sz - then - SoftShoeError(cons($linepos,$n),'"quote added") - '"" - else - n:=$n - strsym :=STRPOS ('"_"",$ln,$n,nil) or $sz - escsym:=STRPOS ('"__" - ,$ln,$n,nil) or $sz - mn:=MIN(strsym,escsym) - if mn=$sz - then - $n:=$sz - SoftShoeError(cons($linepos,$n),'"quote added") - SUBSTRING($ln,n,nil) - else if mn=strsym - then - $n:=mn+1 - SUBSTRING($ln,n,mn-n) - else - str:=SUBSTRING($ln,n,mn-n) - $n:=mn+1 - a:=shoeEsc() - b:=if a - then - str:=CONCAT(str,$ln.$n) - $n:=$n+1 - shoeS() - else shoeS() - CONCAT(str,b) - - - - -shoeIdEnd(line,n)== - while n<#line and shoeIdChar line.n repeat n:=n+1 - n - - -shoeDigit x== DIGIT_-CHAR_-P x - -shoeW(b)== - n1:=$n - $n:=$n+1 - l:=$sz - endid:=shoeIdEnd($ln,$n) - if endid=l or QENUM($ln,endid)^=shoeESCAPE - then - $n:=endid - [b,SUBSTRING($ln,n1,endid-n1)] - else - str:=SUBSTRING($ln,n1,endid-n1) - $n:=endid+1 - a:=shoeEsc() - bb:=if a - then shoeW(true) - else [b,'""] -- escape finds space or newline - [bb.0 or b,CONCAT(str,bb.1)] - -shoeWord(esp) == - aaa:=shoeW(false) - w:=aaa.1 - $floatok:=false - if esp or aaa.0 - then shoeLeafId w - else if shoeKeyWordP w - then - $floatok:=true - shoeLeafKey w - else shoeLeafId w - -shoeInteger()==shoeInteger1(false) - -shoeInteger1(zro) == - n:=$n - l:= $sz - while $n<l and shoeDigit($ln.$n) repeat $n:=$n+1 - if $n=l or QENUM($ln,$n)^=shoeESCAPE - then if n=$n and zro - then '"0" - else SUBSTRING($ln,n,$n-n) - else - str:=SUBSTRING($ln,n,$n-n) - $n:=$n+1 - a:=shoeEsc() - bb:=shoeInteger1(zro) - CONCAT(str,bb) - -shoeIntValue(s) == - ns := #s - ival := 0 - for i in 0..ns-1 repeat - d := shoeOrdToNum ELT(s,i) - ival := 10*ival + d - ival - -shoeNumber() == - a := shoeInteger() - if $n>=$sz - then shoeLeafInteger a - else - if $floatok and QENUM($ln,$n)=shoeDOT - then - n:=$n - $n:=$n+1 - if $n<$sz and QENUM($ln,$n)=shoeDOT - then - $n:=n - shoeLeafInteger a - else - w:=shoeInteger1(true) - shoeExponent(a,w) - else shoeLeafInteger a - -shoeExponent(a,w)== - if $n>=$sz - then shoeLeafFloat(a,w,0) - else - n:=$n - c:=QENUM($ln,$n) - if c=shoeEXPONENT1 or c=shoeEXPONENT2 - then - $n:=$n+1 - if $n>=$sz - then - $n:=n - shoeLeafFloat(a,w,0) - else if shoeDigit($ln.$n) - then - e:=shoeInteger() - e:=shoeIntValue e - shoeLeafFloat(a,w,e) - else - c1:=QENUM($ln,$n) - if c1=shoePLUSCOMMENT or c1=shoeMINUSCOMMENT - then - $n:=$n+1 - if $n>=$sz - then - $n:=n - shoeLeafFloat(a,w,0) - else - if shoeDigit($ln.$n) - then - e:=shoeInteger() - e:=shoeIntValue e - shoeLeafFloat(a,w, - (if c1=shoeMINUSCOMMENT then MINUS e else e)) - else - $n:=n - shoeLeafFloat(a,w,0) - else shoeLeafFloat(a,w,0) - -shoeError()== - n:=$n - $n:=$n+1 - SoftShoeError(cons($linepos,n), - CONCAT( '"The character whose number is ", - STRINGIMAGE QENUM($ln,n),'" is not a Boot character")) - shoeLeafError ($ln.n) - -shoeOrdToNum x== DIGIT_-CHAR_-P x - -shoeKeyWord st == GETHASH(st,shoeKeyTable) - -shoeKeyWordP st == not null GETHASH(st,shoeKeyTable) - -shoeMatch(l,i)==shoeSubStringMatch(l,shoeDict,i) - -shoeSubStringMatch (l,d,i)== - h:= QENUM(l, i) - u:=ELT(d,h) - ll:=SIZE l - done:=false - s1:='"" - for j in 0.. SIZE u - 1 while not done repeat - s:=ELT(u,j) - ls:=SIZE s - done:=if ls+i > ll - then false - else - eql:= true - for k in 1..ls-1 while eql repeat - eql:= EQL(QENUM(s,k),QENUM(l,k+i)) - if eql - then - s1:=s - true - else false - s1 - -shoePunctuation c== shoePun.c =1 - -@ -<<scanner.clisp>>= (EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-lexer")) (IMPORT-MODULE "tokens") @@ -1158,6 +624,3 @@ shoePunctuation c== shoePun.c =1 (DEFUN |shoePunctuation| (|c|) (PROG () (RETURN (EQL (ELT |shoePun| |c|) 1)))) -@ - -\end{document} diff --git a/src/boot/strap/tokens.clisp b/src/boot/strap/tokens.clisp new file mode 100644 index 00000000..3ce6a7c8 --- /dev/null +++ b/src/boot/strap/tokens.clisp @@ -0,0 +1,352 @@ +(EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-tokens")) + +(IMPORT-MODULE "initial-env") + +(IN-PACKAGE "BOOTTRAN") + +(DEFPARAMETER |shoeKeyWords| + (LIST (LIST "and" 'AND) (LIST "by" 'BY) (LIST "case" 'CASE) + (LIST "cross" 'CROSS) (LIST "else" 'ELSE) (LIST "for" 'FOR) + (LIST "if" 'IF) (LIST "import" 'IMPORT) (LIST "in" 'IN) + (LIST "is" 'IS) (LIST "isnt" 'ISNT) (LIST "module" 'MODULE) + (LIST "of" 'OF) (LIST "or" 'OR) (LIST "repeat" 'REPEAT) + (LIST "return" 'RETURN) (LIST "structure" 'STRUCTURE) + (LIST "then" 'THEN) (LIST "until" 'UNTIL) + (LIST "where" 'WHERE) (LIST "while" 'WHILE) (LIST "." 'DOT) + (LIST ":" 'COLON) (LIST "::" 'COLON-COLON) (LIST "," 'COMMA) + (LIST ";" 'SEMICOLON) (LIST "*" 'TIMES) (LIST "**" 'POWER) + (LIST "/" 'SLASH) (LIST "+" 'PLUS) (LIST "-" 'MINUS) + (LIST "<" 'LT) (LIST ">" 'GT) (LIST "<=" 'LE) (LIST ">=" 'GE) + (LIST "=" 'SHOEEQ) (LIST "^" 'NOT) (LIST "^=" 'SHOENE) + (LIST ".." 'SEG) (LIST "#" 'LENGTH) (LIST "=>" 'EXIT) + (LIST "->" 'ARROW) (LIST ":=" 'BEC) (LIST "==" 'DEF) + (LIST "==>" 'MDEF) (LIST "<=>" 'TDEF) (LIST "(" 'OPAREN) + (LIST ")" 'CPAREN) (LIST "(|" 'OBRACK) (LIST "|)" 'CBRACK) + (LIST "[" 'OBRACK) (LIST "]" 'CBRACK) (LIST "suchthat" 'BAR) + (LIST "'" 'QUOTE) (LIST "|" 'BAR))) + +(DEFUN |shoeKeyTableCons| () + (PROG (|KeyTable|) + (RETURN + (PROGN + (SETQ |KeyTable| (MAKE-HASHTABLE 'CVEC)) + (LET ((|bfVar#1| |shoeKeyWords|) (|st| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#1|) + (PROGN (SETQ |st| (CAR |bfVar#1|)) NIL)) + (RETURN NIL)) + ('T (HPUT |KeyTable| (CAR |st|) (CADR |st|)))) + (SETQ |bfVar#1| (CDR |bfVar#1|)))) + |KeyTable|)))) + +(DEFPARAMETER |shoeKeyTable| (|shoeKeyTableCons|)) + +(DEFPARAMETER |shoeSPACE| (QENUM " " 0)) + +(DEFPARAMETER |shoeESCAPE| (QENUM "_ " 0)) + +(DEFPARAMETER |shoeLispESCAPE| (QENUM "! " 0)) + +(DEFPARAMETER |shoeSTRINGCHAR| (QENUM "\" " 0)) + +(DEFPARAMETER |shoePLUSCOMMENT| (QENUM "+ " 0)) + +(DEFPARAMETER |shoeMINUSCOMMENT| (QENUM "- " 0)) + +(DEFPARAMETER |shoeDOT| (QENUM ". " 0)) + +(DEFPARAMETER |shoeEXPONENT1| (QENUM "E " 0)) + +(DEFPARAMETER |shoeEXPONENT2| (QENUM "e " 0)) + +(DEFPARAMETER |shoeCLOSEPAREN| (QENUM ") " 0)) + +(DEFPARAMETER |shoeTAB| 9) + +(DEFUN |shoeInsert| (|s| |d|) + (PROG (|v| |k| |n| |u| |h| |l|) + (RETURN + (PROGN + (SETQ |l| (LENGTH |s|)) + (SETQ |h| (QENUM |s| 0)) + (SETQ |u| (ELT |d| |h|)) + (SETQ |n| (LENGTH |u|)) + (SETQ |k| 0) + (LOOP + (COND + ((< (LENGTH (ELT |u| |k|)) |l|) (RETURN NIL)) + (#0='T (SETQ |k| (+ |k| 1))))) + (SETQ |v| (MAKE-VEC (+ |n| 1))) + (LET ((|bfVar#2| (- |k| 1)) (|i| 0)) + (LOOP + (COND + ((> |i| |bfVar#2|) (RETURN NIL)) + (#0# (VEC-SETELT |v| |i| (ELT |u| |i|)))) + (SETQ |i| (+ |i| 1)))) + (VEC-SETELT |v| |k| |s|) + (LET ((|bfVar#3| (- |n| 1)) (|i| |k|)) + (LOOP + (COND + ((> |i| |bfVar#3|) (RETURN NIL)) + (#0# (VEC-SETELT |v| (+ |i| 1) (ELT |u| |i|)))) + (SETQ |i| (+ |i| 1)))) + (VEC-SETELT |d| |h| |v|) + |s|)))) + +(DEFUN |shoeDictCons| () + (PROG (|d| |b| |a| |l|) + (RETURN + (PROGN + (SETQ |l| (HKEYS |shoeKeyTable|)) + (SETQ |d| + (PROGN + (SETQ |a| (MAKE-VEC 256)) + (SETQ |b| (MAKE-VEC 1)) + (VEC-SETELT |b| 0 (MAKE-CVEC 0)) + (LET ((|i| 0)) + (LOOP + (COND + ((> |i| 255) (RETURN NIL)) + (#0='T (VEC-SETELT |a| |i| |b|))) + (SETQ |i| (+ |i| 1)))) + |a|)) + (LET ((|bfVar#4| |l|) (|s| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#4|) + (PROGN (SETQ |s| (CAR |bfVar#4|)) NIL)) + (RETURN NIL)) + (#0# (|shoeInsert| |s| |d|))) + (SETQ |bfVar#4| (CDR |bfVar#4|)))) + |d|)))) + +(DEFPARAMETER |shoeDict| (|shoeDictCons|)) + +(DEFUN |shoePunCons| () + (PROG (|a| |listing|) + (RETURN + (PROGN + (SETQ |listing| (HKEYS |shoeKeyTable|)) + (SETQ |a| (MAKE-BVEC 256)) + (LET ((|i| 0)) + (LOOP + (COND + ((> |i| 255) (RETURN NIL)) + (#0='T (BVEC-SETELT |a| |i| 0))) + (SETQ |i| (+ |i| 1)))) + (LET ((|bfVar#5| |listing|) (|k| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#5|) + (PROGN (SETQ |k| (CAR |bfVar#5|)) NIL)) + (RETURN NIL)) + (#0# + (COND + ((NULL (|shoeStartsId| (ELT |k| 0))) + (BVEC-SETELT |a| (QENUM |k| 0) 1))))) + (SETQ |bfVar#5| (CDR |bfVar#5|)))) + |a|)))) + +(DEFPARAMETER |shoePun| (|shoePunCons|)) + +(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) + (PROG () + (RETURN + (LET ((|bfVar#6| (LIST 'NOT 'LENGTH)) (|i| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#6|) + (PROGN (SETQ |i| (CAR |bfVar#6|)) NIL)) + (RETURN NIL)) + ('T (SETF (GET |i| 'SHOEPRE) 'T))) + (SETQ |bfVar#6| (CDR |bfVar#6|))))))) + +(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) + (PROG () + (RETURN + (LET ((|bfVar#7| + (LIST (LIST 'SHOEEQ '=) (LIST 'TIMES '*) + (LIST 'PLUS '+) (LIST 'IS '|is|) + (LIST 'ISNT '|isnt|) (LIST 'AND '|and|) + (LIST 'OR '|or|) (LIST 'SLASH '/) + (LIST 'POWER '**) (LIST 'MINUS '-) (LIST 'LT '<) + (LIST 'GT '>) (LIST 'LE '<=) (LIST 'GE '>=) + (LIST 'SHOENE '^=))) + (|i| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#7|) + (PROGN (SETQ |i| (CAR |bfVar#7|)) NIL)) + (RETURN NIL)) + ('T (SETF (GET (CAR |i|) 'SHOEINF) (CADR |i|)))) + (SETQ |bfVar#7| (CDR |bfVar#7|))))))) + +(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) + (PROG () + (RETURN + (LET ((|bfVar#8| + (LIST (LIST '+ 0) (LIST '|gcd| 0) (LIST '|lcm| 1) + (LIST 'STRCONC "") (LIST '|strconc| "") + (LIST 'MAX (- 999999)) (LIST 'MIN 999999) + (LIST '* 1) (LIST '|times| 1) (LIST 'CONS NIL) + (LIST 'APPEND NIL) (LIST '|append| NIL) + (LIST 'UNION NIL) (LIST 'UNIONQ NIL) + (LIST '|union| NIL) (LIST 'NCONC NIL) + (LIST '|and| 'T) (LIST '|or| NIL) (LIST 'AND 'T) + (LIST 'OR NIL))) + (|i| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#8|) + (PROGN (SETQ |i| (CAR |bfVar#8|)) NIL)) + (RETURN NIL)) + ('T (SETF (GET (CAR |i|) 'SHOETHETA) (CDR |i|)))) + (SETQ |bfVar#8| (CDR |bfVar#8|))))))) + +(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) + (PROG () + (RETURN + (LET ((|bfVar#9| + (LIST (LIST '|and| 'AND) (LIST '|append| 'APPEND) + (LIST '|apply| 'APPLY) (LIST '|atom| 'ATOM) + (LIST '|car| 'CAR) (LIST '|cdr| 'CDR) + (LIST '|cons| 'CONS) (LIST '|copy| 'COPY) + (LIST '|croak| 'CROAK) (LIST '|drop| 'DROP) + (LIST '|exit| 'EXIT) (LIST '|false| 'NIL) + (LIST '|first| 'CAR) (LIST '|function| 'FUNCTION) + (LIST '|genvar| 'GENVAR) (LIST 'IN 'MEMBER) + (LIST '|is| 'IS) (LIST '|isnt| 'ISNT) + (LIST '|lastNode| 'LAST) (LIST 'LAST '|last|) + (LIST '|list| 'LIST) (LIST '|mkpf| 'MKPF) + (LIST '|nconc| 'NCONC) (LIST '|nil| NIL) + (LIST '|not| 'NULL) (LIST 'NOT 'NULL) + (LIST '|nreverse| 'NREVERSE) (LIST '|null| 'NULL) + (LIST '|or| 'OR) (LIST '|otherwise| 'T) + (LIST 'PAIRP 'CONSP) + (LIST '|removeDuplicates| 'REMDUP) + (LIST '|rest| 'CDR) (LIST '|reverse| 'REVERSE) + (LIST '|setDifference| 'SETDIFFERENCE) + (LIST '|setIntersection| 'INTERSECTION) + (LIST '|setPart| 'SETELT) + (LIST '|setUnion| 'UNION) (LIST '|size| 'SIZE) + (LIST '|strconc| 'CONCAT) + (LIST '|substitute| 'SUBST) (LIST '|take| 'TAKE) + (LIST '|true| 'T) (LIST 'PLUS '+) + (LIST 'MINUS '-) (LIST 'TIMES '*) + (LIST 'POWER 'EXPT) (LIST 'SLASH '/) + (LIST 'LT '<) (LIST 'GT '>) (LIST 'LE '<=) + (LIST 'GE '>=) (LIST 'SHOEEQ 'EQUAL) + (LIST 'SHOENE '/=) (LIST 'T 'T$))) + (|i| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#9|) + (PROGN (SETQ |i| (CAR |bfVar#9|)) NIL)) + (RETURN NIL)) + ('T (SETF (GET (CAR |i|) 'SHOERENAME) (CDR |i|)))) + (SETQ |bfVar#9| (CDR |bfVar#9|))))))) + +(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) + (PROG () + (RETURN + (LET ((|bfVar#10| + (LIST (LIST 'PLUS 'PLUS) (LIST '|and| 'AND) + (LIST '|append| 'APPEND) (LIST '|apply| 'APPLY) + (LIST '|atom| 'ATOM) (LIST '|brace| 'REMDUP) + (LIST '|car| 'CAR) (LIST '|cdr| 'CDR) + (LIST '|cons| 'CONS) (LIST '|copy| 'COPY) + (LIST '|croak| 'CROAK) (LIST '|drop| 'DROP) + (LIST '|exit| 'EXIT) (LIST '|false| 'NIL) + (LIST '|first| 'CAR) (LIST '|genvar| 'GENVAR) + (LIST '|in| '|member|) (LIST '|is| 'IS) + (LIST '|lastNode| 'LASTNODE) (LIST '|list| 'LIST) + (LIST '|mkpf| 'MKPF) (LIST '|nconc| 'NCONC) + (LIST '|nil| 'NIL) (LIST '|not| 'NULL) + (LIST 'NOT 'NULL) (LIST '|nreverse| 'NREVERSE) + (LIST '|null| 'NULL) (LIST '|or| 'OR) + (LIST '|otherwise| 'T) + (LIST '|removeDuplicates| 'REMDUP) + (LIST '|rest| 'CDR) (LIST '|return| 'RETURN) + (LIST '|reverse| 'REVERSE) + (LIST '|setDifference| 'SETDIFFERENCE) + (LIST '|setIntersection| '|intersection|) + (LIST '|setPart| 'SETELT) + (LIST '|setUnion| '|union|) (LIST '|size| 'SIZE) + (LIST '|strconc| 'STRCONC) + (LIST '|substitute| 'MSUBST) + (LIST 'SUBST 'MSUBST) (LIST '|take| 'TAKE) + (LIST '|true| 'T) (LIST '|where| 'WHERE) + (LIST 'TIMES 'TIMES) (LIST 'POWER 'EXPT) + (LIST 'NOT 'NULL) (LIST 'SHOENE 'NEQUAL) + (LIST 'MINUS 'SPADDIFFERENCE) + (LIST 'SLASH 'QUOTIENT) (LIST '= 'EQUAL) + (LIST 'SHOEEQ 'EQUAL) (LIST 'ASSOC '|assoc|) + (LIST 'DELETE '|delete|) (LIST 'GET 'GETL) + (LIST 'INTERSECTION '|intersection|) + (LIST 'LAST '|last|) (LIST 'MEMBER '|member|) + (LIST 'RASSOC '|rassoc|) (LIST 'READ 'VMREAD) + (LIST 'READ-LINE '|read-line|) + (LIST 'REDUCE 'SPADREDUCE) + (LIST 'REMOVE '|remove|) (LIST 'BAR 'SUCHTHAT) + (LIST 'T 'T$) (LIST 'IN '|member|) + (LIST 'UNION '|union|))) + (|i| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#10|) + (PROGN (SETQ |i| (CAR |bfVar#10|)) NIL)) + (RETURN NIL)) + ('T (SETF (GET (CAR |i|) 'OLD-BOOT) (CDR |i|)))) + (SETQ |bfVar#10| (CDR |bfVar#10|))))))) + +(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) + (PROG () + (RETURN + (LET ((|bfVar#11| + (LIST 'LT 'LE 'GT 'GE 'SHOENE 'TIMES 'PLUS 'MINUS + '|function| 'PAIRP)) + (|i| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#11|) + (PROGN (SETQ |i| (CAR |bfVar#11|)) NIL)) + (RETURN NIL)) + ('T (SETF (GET |i| 'RENAME-OK) T))) + (SETQ |bfVar#11| (CDR |bfVar#11|))))))) + +(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) + (PROG () + (RETURN + (LET ((|bfVar#12| + (LIST (LIST '|setName| 0) (LIST '|setLabel| 1) + (LIST '|setLevel| 2) (LIST '|setType| 3) + (LIST '|setVar| 4) (LIST '|setLeaf| 5) + (LIST '|setDef| 6) (LIST '|aGeneral| 4) + (LIST '|aMode| 1) (LIST '|aModeSet| 3) + (LIST '|aTree| 0) (LIST '|aValue| 2) + (LIST '|attributes| 'CADDR) + (LIST '|cacheCount| 'CADDDDR) + (LIST '|cacheName| 'CADR) + (LIST '|cacheReset| 'CADDDR) + (LIST '|cacheType| 'CADDR) (LIST '|env| 'CADDR) + (LIST '|expr| 'CAR) (LIST 'CAR 'CAR) + (LIST '|mmCondition| 'CAADR) (LIST '|mmDC| 'CAAR) + (LIST '|mmImplementation| 'CADADR) + (LIST '|mmSignature| 'CDAR) + (LIST '|mmTarget| 'CADAR) (LIST '|mode| 'CADR) + (LIST '|op| 'CAR) (LIST '|opcode| 'CADR) + (LIST '|opSig| 'CADR) (LIST 'CDR 'CDR) + (LIST '|sig| 'CDDR) (LIST '|source| 'CDR) + (LIST '|streamCode| 'CADDDR) + (LIST '|streamDef| 'CADDR) + (LIST '|streamName| 'CADR) (LIST '|target| 'CAR))) + (|i| NIL)) + (LOOP + (COND + ((OR (ATOM |bfVar#12|) + (PROGN (SETQ |i| (CAR |bfVar#12|)) NIL)) + (RETURN NIL)) + ('T (SETF (GET (CAR |i|) 'SHOESELFUNCTION) (CADR |i|)))) + (SETQ |bfVar#12| (CDR |bfVar#12|))))))) + diff --git a/src/boot/translator.boot.pamphlet b/src/boot/strap/translator.clisp index c66ba1f2..0b849cfc 100644 --- a/src/boot/translator.boot.pamphlet +++ b/src/boot/strap/translator.clisp @@ -1,818 +1,3 @@ -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/translator.boot} Pamphlet} -\author{The Axiom Team} - -\begin{document} -\maketitle - -\begin{abstract} -This file implement various Boot translaters. -\end{abstract} -\eject - -\tableofcontents -\eject - -\section{Entry points to this module} - -The only entry points to this module are: -\begin{itemize} -\item [BOOTTOCL] -\item [BOOTCLAM] -\item [BOOTTOCLC] -\item [BOOTTOMC] -\item [EVAL-BOOT-FILE] -\item [BO] -\item [BOCLAM] -\item [STOUT] -\item [STEVAL] -\item [STTOMC] -\end{itemize} - -Calling other functions defined here, from outside of this module, -may lead to unpredictable results. - - -We assume that we are translating a file called {\bf ``foo.boot''} -and expect to generate a file called {\bf ``foo.clisp''}. - -\section{BOOTTOCLLINES} - -The {\bf BOOTTOCLLINES} function cleans up the function names. -When called during system build from {\bf BOOTTOCL} the {\bf lines} -variable has the value {\bf NIL} and the {\bf fn} variable has the -value {\bf ``foo.boot''}. - -The infn variable is the input file name, {\bf ``foo.boot''}. - -The outfn variable is the output file name, {\bf ``foo.clisp''}. - -Calling {\bf shoeOpenInputFile} will create {\bf ``foo.clisp''} and -return the string ``foo.clisp PRODUCED''. - -<<BOOTTOCLLINES>>= -BOOTTOCLLINES(lines, fn, outfn)== - -- The default floating point number is double-float. - SETQ(_*READ_-DEFAULT_-FLOAT_-FORMAT_*, 'DOUBLE_-FLOAT) - callingPackage := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - infn:=shoeAddbootIfNec fn - result := shoeOpenInputFile(a,infn, - shoeClLines(a,fn,lines,outfn)) - setCurrentPackage callingPackage - result - -@ - -\section{License} - -<<license>>= --- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are --- met: --- --- - Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- - Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in --- the documentation and/or other materials provided with the --- distribution. --- --- - Neither the name of The Numerical ALgorithms Group Ltd. nor the --- names of its contributors may be used to endorse or promote products --- derived from this software without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -@ -<<*>>= -<<license>> - -module '"boot-translator" -import '"includer" -import '"scanner" -import '"pile" -import '"parser" -import '"ast" - -)package "BOOTTRAN" - -+++ True if we are translating code written in Old Boot. -$translatingOldBoot := false - -AxiomCore::%sysInit() == - if cdr ASSOC(Option '"boot", %systemOptions()) = '"old" - then $translatingOldBoot := true - --- Make x, the current package -setCurrentPackage x == - SETQ(_*PACKAGE_*,x) - --- Compiles the input Lisp file designated by lspFileName. -shoeCOMPILE_-FILE lspFileName == - COMPILE_-FILE lspFileName - --- (boottocl "filename") translates the file "filename.boot" to --- the common lisp file "filename.clisp" - -BOOTTOCL(fn, out) == - BOOTTOCLLINES(nil,fn, out) - --- (bootclam "filename") translates the file "filename.boot" to --- the common lisp file "filename.clisp" , producing, for each function --- a hash table to store previously computed values indexed by argument --- list. - -BOOTCLAM(fn, out) == - $bfClamming := true - BOOTCLAMLINES(nil,fn, out) - -BOOTCLAMLINES(lines, fn, out) == - BOOTTOCLLINES(lines, fn, out) - -<<BOOTTOCLLINES>> -shoeClLines(a,fn,lines,outfn)== - if null a - then shoeNotFound fn - else - $GenVarCounter:local := 0 - shoeOpenOutputFile(stream,outfn, - (for line in lines repeat shoeFileLine (line,stream); - shoeFileTrees(shoeTransformStream a,stream))) - outfn - --- (boottoclc "filename") translates the file "filename.boot" to --- the common lisp file "filename.clisp" with the original boot --- code as comments - -BOOTTOCLC(fn, out)==BOOTTOCLCLINES(nil, fn, out) - -BOOTTOCLCLINES(lines, fn, outfn)== - callingPackage := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - infn:=shoeAddbootIfNec fn - result := shoeOpenInputFile(a,infn, - shoeClCLines(a,fn,lines,outfn)) - setCurrentPackage callingPackage - result - - -shoeClCLines(a,fn,lines,outfn)== - if null a - then shoeNotFound fn - else - $GenVarCounter:local := 0 - shoeOpenOutputFile(stream,outfn, - (for line in lines repeat shoeFileLine (line,stream); - shoeFileTrees(shoeTransformToFile(stream, - shoeInclude bAddLineNumber(bRgen a,bIgen 0)),stream))) - outfn - --- (boottomc "filename") translates the file "filename.boot" --- to machine code and loads it one item at a time - -BOOTTOMC fn== - callingPackage := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - $GenVarCounter:local := 0 - infn:=shoeAddbootIfNec fn - result := shoeOpenInputFile(a,infn,shoeMc(a,fn)) - setCurrentPackage callingPackage - result - -shoeMc(a,fn)== - if null a - then shoeNotFound fn - else - shoePCompileTrees shoeTransformStream a - shoeConsole CONCAT(fn,'" COMPILED AND LOADED") - -EVAL_-BOOT_-FILE fn == - b := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - infn:=shoeAddbootIfNec fn - outfn:=CONCAT(shoeRemovebootIfNec fn,'".",_*LISP_-SOURCE_-FILETYPE_*) - shoeOpenInputFile(a,infn,shoeClLines(a,infn,[],outfn)) - setCurrentPackage b - LOAD outfn - --- (boot "filename") translates the file "filename.boot" --- and prints the result at the console - -BO fn== - b := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - $GenVarCounter:local := 0 - infn:=shoeAddbootIfNec fn - shoeOpenInputFile(a,infn,shoeToConsole(a,fn)) - setCurrentPackage b - -BOCLAM fn== - callingPackage := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - $GenVarCounter:local := 0 - $bfClamming:local := true - infn:=shoeAddbootIfNec fn - result := shoeOpenInputFile(a,infn,shoeToConsole(a,fn)) - setCurrentPackage callingPackage - result - -shoeToConsole(a,fn)== - if null a - then shoeNotFound fn - else - shoeConsoleTrees shoeTransformToConsole - shoeInclude bAddLineNumber(bRgen a,bIgen 0) - --- (stout "string") translates the string "string" --- and prints the result at the console - -STOUT string== PSTOUT [string] --- $GenVarCounter:local := 0 --- $bfClamming:local:=false --- shoeConsoleTrees shoeTransformString [string] - -STEVAL string== - callingPackage := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - $GenVarCounter:local := 0 - a:= shoeTransformString [string] - result := - bStreamPackageNull a => nil - fn:=stripm(CAR a,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") - EVAL fn - setCurrentPackage callingPackage - result - --- (sttomc "string") translates the string "string" --- to common lisp, and compiles it. - -STTOMC string== - callingPackage := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - $GenVarCounter:local := 0 - a:= shoeTransformString [string] - result := - bStreamPackageNull a => nil - shoePCompile car a - setCurrentPackage callingPackage - result - - -shoeCompileTrees s== - while not bStreamNull s repeat - shoeCompile car s - s:=cdr s - -shoeCompile fn== - fn is ['DEFUN,name,bv,:body]=> - COMPILE (name,['LAMBDA,bv,:body]) - EVAL fn - -shoeTransform str== - bNext(function shoeTreeConstruct, - bNext(function shoePileInsert, - bNext(function shoeLineToks, str))) - -shoeTransformString s== - shoeTransform shoeInclude bAddLineNumber(s,bIgen 0) -shoeTransformStream s==shoeTransformString bRgen s --- shoeTransform shoeInclude bAddLineNumber(bRgen s,bIgen 0) - -shoeTransformToConsole str== - bNext(function shoeConsoleItem, - bNext(function shoePileInsert, - bNext(function shoeLineToks, str))) - -shoeTransformToFile(fn,str)== - bFileNext(fn, - bNext(function shoePileInsert, - bNext(function shoeLineToks, str))) - -shoeConsoleItem (str)== - dq:=CAR str - shoeConsoleLines shoeDQlines dq - cons(shoeParseTrees dq,CDR str) - -bFileNext(fn,s)==bDelay(function bFileNext1,[fn,s]) - -bFileNext1(fn,s)== - bStreamNull s=> ["nullstream"] - dq:=CAR s - shoeFileLines(shoeDQlines dq,fn) - bAppend(shoeParseTrees dq,bFileNext(fn,cdr s)) - -shoeParseTrees dq== - toklist := dqToList dq - null toklist => [] - shoeOutParse toklist - -shoeTreeConstruct (str)== - cons(shoeParseTrees CAR str,CDR str) - -shoeDQlines dq== - a:= CDAAR shoeLastTokPosn dq - b:= CDAAR shoeFirstTokPosn dq - streamTake (a-b+1,CAR shoeFirstTokPosn dq) - -streamTake(n,s)== - if bStreamNull s - then nil - else if EQL(n,0) - then nil - else cons(car s,streamTake(n-1,cdr s)) - -shoeFileLines (lines,fn) == - shoeFileLine( '" ",fn) - for line in lines repeat shoeFileLine (shoeAddComment line,fn) - shoeFileLine ('" ",fn) - -shoeConsoleLines lines == - shoeConsole '" " - for line in lines repeat shoeConsole shoeAddComment line - shoeConsole '" " - -shoeFileLine(x, stream) == - WRITE_-LINE(x, stream) - x - -shoeFileTrees(s,st)== - while not bStreamNull s repeat - a:=CAR s - if EQCAR (a,"+LINE") - then shoeFileLine(CADR a,st) - else - REALLYPRETTYPRINT(a,st) - TERPRI st - s:=CDR s - - -shoePPtoFile(x, stream) == - SHOENOTPRETTYPRINT(x, stream) - x - -shoeConsoleTrees s == - while not bStreamPackageNull s repeat --- while not bStreamNull s repeat - fn:=stripm(CAR s,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") - REALLYPRETTYPRINT fn - s:=CDR s - -shoeAddComment l== CONCAT('"; ",CAR l) - -++ Generate an import declaration for `op' as equivalent of the -++ foreign signature `sig'. Here, `foreign' operationally means that -++ the entity is from the C language world. -genImportDeclaration(op, sig) == - sig isnt ["Signature", op', m] => coreError '"invalid signature" - m isnt ["Mapping", t, s] => coreError '"invalid function type" - %hasFeature KEYWORD::GCL => - if SYMBOLP s then s := [s] - ["DEFENTRY", op, s, [t, SYMBOL_-NAME op']] - fatalError '"import declaration not implemented for this Lisp" - -shoeOutParse stream == - $inputStream :local:= stream - $stack:local :=nil - $stok:local := nil - $ttok:local := nil - $op:local :=nil - $wheredefs:local:=nil - $typings:local:=nil - $returns:local :=nil - $bpCount:local:=0 - $bpParenCount:local:=0 - bpFirstTok() - found:=CATCH("TRAPPOINT",bpOutItem()) - if found="TRAPPED" - then nil - else if not bStreamNull $inputStream - then - bpGeneralErrorHere() - nil - else if null $stack - then - bpGeneralErrorHere() - nil - else CAR $stack - -bpOutItem()== - bpComma() or bpTrap() - b:=bpPop1() - EQCAR(b,"TUPLE")=> bpPush cdr b - EQCAR(b,"+LINE")=> bpPush [ b ] - b is ["L%T",l,r] and IDENTP l => - bpPush [["DEFPARAMETER",l,r]] - case b of - Module(m) => - bpPush [shoeCompileTimeEvaluation ["PROVIDE", m]] - - Import(m) => - bpPush [["IMPORT-MODULE", m]] - - ImportSignature(x, sig) => - bpPush [genImportDeclaration(x, sig)] - - TypeAlias(t, args, rhs) => - bpPush [["DEFTYPE", t, args, ["QUOTE", rhs]]] - - ConstantDefinition(n, e) => - bpPush [["DEFCONSTANT", n, e]] - - otherwise => - b:=shoeCompTran ["LAMBDA",["x"],b] - bpPush [shoeEVALANDFILEACTQ CADDR b] - ---shoeStartsAt (sz,name,stream)== --- bStreamNull stream => ['nullstream] --- a:=CAAR stream --- if #a<sz --- then shoeStartsAt(sz,name,CDR stream) --- else if SUBSTRING(a,0,sz)=name and (#a>sz and not shoeIdChar(a.sz)) --- then stream --- else shoeStartsAt(sz,name,CDR stream) - ---FC(name,fn)== --- $bfClamming:local:=false --- $GenVarCounter:local := 0 --- infn:=shoeAddbootIfNec fn --- shoeOpenInputFile(a,infn,shoeFindName(fn,name, a)) - ---shoeFindName(fn,name,a)== --- shoeFindAndDoSomething(FUNCTION shoeCompile,fn,name,a) ---shoeTransform1 str== --- bNext(function shoeTreeConstruct, --- streamTake(1, bNext(function shoePileInsert, --- bNext(function shoeLineToks, str)))) - ---BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE(fun,fn,symbol)== --- $bfClamming:local:=false --- infn:=shoeAddbootIfNec NAMESTRING fn --- name:=PNAME symbol --- shoeOpenInputFile(a,infn,shoeFindAndDoSomething(fun,fn,name, a)) - ---shoeFindAndDoSomething(fun,fn,name,a)== --- if null a --- then shoeNotFound fn --- else --- b:=shoeStartsAt(#name,name, shoeInclude --- bAddLineNumber(bRgen a,bIgen 0)) --- if bStreamNull b --- then shoeConsole CONCAT (name,'" not found in ",fn) --- else --- $GenVarCounter:local := 0 --- shoeLoop(fun,shoeTransform1 b) - ---BOOT_-COMPILE_-DEFINITION_-FROM_-FILE(fn,symbol)== --- BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE --- (FUNCTION shoeCompile,fn,symbol) - ---BOOT_-EVAL_-DEFINITION_-FROM_-FILE(fn,symbol)== --- BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE --- (FUNCTION EVAL,fn,symbol) - ---BOOT_-PRINT_-DEFINITION_-FROM_-FILE(fn,symbol)== --- BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE --- (FUNCTION REALLYPRETTYPRINT,fn,symbol) - ---shoeLoop(fun, s)== --- while not bStreamNull s repeat --- FUNCALL(fun, car s) --- s:=cdr s - -shoeAddbootIfNec s==shoeAddStringIfNec('".boot",s) - -shoeRemovebootIfNec s==shoeRemoveStringIfNec('".boot",s) -shoeAddStringIfNec(str,s)== - a:=STRPOS(str,s,0,nil) - if null a - then CONCAT(s,str) - else s - -shoeRemoveStringIfNec(str,s)== - a:=STRPOS(str,s,0,nil) - if null a - then s - else SUBSTRING(s,0,a) - --- DEFUSE prints the definitions not used and the words used and --- not defined in the input file and common lisp. - -DEFUSE fn== - infn:=CONCAT(fn,'".boot") - shoeOpenInputFile(a,infn,shoeDfu(a,fn)) - -shoeDfu(a,fn)== - if null a - then shoeNotFound fn - else - $lispWordTable:local :=MAKE_-HASHTABLE ("EQ") - DO_-SYMBOLS(i(FIND_-PACKAGE "LISP"),HPUT($lispWordTable,i,true)) - $bootDefined:local :=MAKE_-HASHTABLE "EQ" - $bootUsed:local :=MAKE_-HASHTABLE "EQ" - $bootDefinedTwice:local:=nil - $GenVarCounter:local :=0 - $bfClamming:local:=false - shoeDefUse shoeTransformStream a - out:=CONCAT(fn,'".defuse") - shoeOpenOutputFile(stream,out,shoeReport stream) - out - -shoeReport stream== - shoeFileLine('"DEFINED and not USED",stream) - a:=[i for i in HKEYS $bootDefined | not GETHASH(i,$bootUsed)] - bootOut(SSORT a,stream) - shoeFileLine('" ",stream) - shoeFileLine('"DEFINED TWICE",stream) - bootOut(SSORT $bootDefinedTwice,stream) - shoeFileLine('" ",stream) - shoeFileLine('"USED and not DEFINED",stream) - a:=[i for i in HKEYS $bootUsed | - not GETHASH(i,$bootDefined)] - for i in SSORT a repeat - b:=CONCAT(PNAME i,'" is used in ") - bootOutLines( SSORT GETHASH(i,$bootUsed),stream,b) - -shoeDefUse(s)== - while not bStreamPackageNull s repeat - defuse([],CAR s) - s:=CDR s - -defuse(e,x)== - x:=stripm(x,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") - $used:local:=nil - [nee,niens]:= - x is ['DEFUN,name,bv,:body] => [name,['LAMBDA,bv,:body]] - x is ['DEFMACRO,name,bv,:body] => [name,['LAMBDA,bv,:body]] - x is ["EVAL_-WHEN",.,["SETQ",id,exp]]=>[id,exp] - x is ["SETQ",id,exp]=>[id,exp] - ["TOP-LEVEL", x] - if GETHASH(nee,$bootDefined) - then - $bootDefinedTwice:= - nee="TOP-LEVEL"=> $bootDefinedTwice - cons(nee,$bootDefinedTwice) - else HPUT($bootDefined,nee,true) - defuse1 (e,niens) - for i in $used repeat - HPUT($bootUsed,i,cons(nee,GETHASH(i,$bootUsed))) - -defuse1(e,y)== - ATOM y => - IDENTP y => - $used:= - MEMQ(y,e)=>$used - MEMQ(y,$used)=>$used - defusebuiltin y =>$used - UNION([y],$used) - [] - y is ["LAMBDA",a,:b]=> defuse1 (append(unfluidlist a,e),b) - y is ["PROG",a,:b]=> - [dol,ndol]:=defSeparate a - for i in dol repeat - HPUT($bootDefined,i,true) - defuse1 (append(ndol,e),b) - y is ["QUOTE",:a] => [] - y is ["+LINE",:a] => [] - for i in y repeat defuse1(e,i) - -defSeparate x== - if null x - then [[],[]] - else - f:=car x - [x1,x2]:=defSeparate cdr x - if bfBeginsDollar f - then [cons(f,x1),x2] - else [x1,cons(f,x2)] -unfluidlist x== - NULL x => [] - ATOM x=> [x] - x is ["&REST",y]=> [y] - cons(car x,unfluidlist cdr x) - -defusebuiltin x== GETHASH(x,$lispWordTable) - -bootOut (l,outfn)== - for i in l repeat shoeFileLine (CONCAT ('" ",PNAME i),outfn) - -CLESSP(s1,s2)==not(SHOEGREATERP(s1,s2)) -SSORT l == SORT(l,function CLESSP) - -bootOutLines(l,outfn,s)== - if null l - then shoeFileLine(s,outfn) - else - a:=PNAME car l - if #s +#a > 70 - then - shoeFileLine(s,outfn) - bootOutLines(l,outfn,'" ") - else bootOutLines(cdr l,outfn,CONCAT(s,'" ",a)) - - --- (xref "fn") produces a cross reference listing in "fn.xref" --- It contains each name --- used in "fn.boot", together with a list of functions that use it. - -XREF fn== - infn:=CONCAT(fn,'".boot") - shoeOpenInputFile(a,infn,shoeXref(a,fn)) - -shoeXref(a,fn)== - if null a - then shoeNotFound fn - else - $lispWordTable:local :=MAKE_-HASHTABLE ("EQ") - DO_-SYMBOLS(i(FIND_-PACKAGE "LISP"),HPUT($lispWordTable,i,true)) - $bootDefined:local :=MAKE_-HASHTABLE "EQ" - $bootUsed:local :=MAKE_-HASHTABLE "EQ" - $GenVarCounter:local :=0 - $bfClamming:local:=false - shoeDefUse shoeTransformStream a - out:=CONCAT(fn,'".xref") - shoeOpenOutputFile(stream,out,shoeXReport stream) - out - - -shoeXReport stream== - shoeFileLine('"USED and where DEFINED",stream) - c:=SSORT HKEYS $bootUsed - for i in c repeat - a:=CONCAT(PNAME i,'" is used in ") - bootOutLines( SSORT GETHASH(i,$bootUsed),stream,a) - ---FC (name,fn)== shoeGeneralFC(function BOOT,name,fn) - -FBO (name,fn)== shoeGeneralFC(function BO,name,fn) - -FEV(name,fn)== shoeGeneralFC(function EVAL_-BOOT_-FILE,name,fn) - -shoeGeneralFC(f,name,fn)== - $bfClamming:local:=false - $GenVarCounter:local := 0 - infn:=shoeAddbootIfNec fn - a:= shoeOpenInputFile(a,infn,shoeFindName2(fn,name, a)) - filename:= if # name > 8 then SUBSTRING(name,0,8) else name - a => FUNCALL(f, CONCAT('"/tmp/",filename)) - nil - -shoeFindName2(fn,name,a)== - lines:=shoeFindLines(fn,name,a) - lines => - filename:= if # name > 8 then SUBSTRING(name,0,8) else name - filename := CONCAT ('"/tmp/",filename,'".boot") - shoeOpenOutputFile(stream, filename, - for line in lines repeat shoeFileLine (line,stream)) - true - false - -shoeTransform2 str== - bNext(function shoeItem, - streamTake(1, bNext(function shoePileInsert, - bNext(function shoeLineToks, str)))) - -shoeItem (str)== - dq:=CAR str - cons([[CAR line for line in shoeDQlines dq]],CDR str) - ---shoeLines lines == [CAR line for line in lines] - ---shoeFindAndDoSomething2(fun,fn,name,a)== --- if null a --- then shoeNotFound fn --- else --- [lines,b]:=shoePackageStartsAt([],#name,name, shoeInclude --- bAddLineNumber(bRgen a,bIgen 0)) --- if bStreamNull b --- then --- shoeConsole CONCAT (name,'" not found in ",fn) --- [] --- else --- if null lines --- then shoeConsole '")package not found" --- $GenVarCounter:local := 0 --- shoeLoopPackage(fun,shoeTransform2 b,lines) - ---shoeLoopPackage(fun, s,lines)== --- while not bStreamNull s repeat --- FUNCALL(fun, append (reverse lines,car s)) --- s:=cdr s --- true -stripm (x,pk,bt)== - ATOM x => - IDENTP x => - SYMBOL_-PACKAGE x = bt => INTERN(PNAME x,pk) - x - x - CONS(stripm(CAR x,pk,bt),stripm(CDR x,pk,bt)) - -shoePCompile fn== - fn:=stripm(fn,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") - fn is ['DEFUN,name,bv,:body]=> - COMPILE (name,['LAMBDA,bv,:body]) - EVAL fn - -FC(name,fn)== - $GenVarCounter:local := 0 - infn:=shoeAddbootIfNec fn - shoeOpenInputFile(a,infn,shoeFindName(fn,name, a)) - -shoeFindName(fn,name,a)== - lines:=shoeFindLines(fn,name,a) - shoePCompileTrees shoeTransformString lines - -shoePCompileTrees s== - while not bStreamPackageNull s repeat - REALLYPRETTYPRINT shoePCompile car s - s:=cdr s - -bStreamPackageNull s== - a := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - b:=bStreamNull s - setCurrentPackage a - b - -PSTTOMC string== - $GenVarCounter:local := 0 - shoePCompileTrees shoeTransformString string - -BOOTLOOP ()== - a:=READ_-LINE() - #a=0=> - WRITE_-LINE '"Boot Loop; to exit type ] " - BOOTLOOP() - b:=shoePrefix? ('")console",a) - b => - stream:= _*TERMINAL_-IO_* - PSTTOMC bRgen stream - BOOTLOOP() - a.0='"]".0 => nil - PSTTOMC [a] - BOOTLOOP() - -BOOTPO ()== - a:=READ_-LINE() - #a=0=> - WRITE_-LINE '"Boot Loop; to exit type ] " - BOOTPO() - b:=shoePrefix? ('")console",a) - b => - stream:= _*TERMINAL_-IO_* - PSTOUT bRgen stream - BOOTPO() - a.0='"]".0 => nil - PSTOUT [a] - BOOTPO() - -PSTOUT string== - callingPackage := _*PACKAGE_* - IN_-PACKAGE '"BOOTTRAN" - $GenVarCounter:local := 0 - result := shoeConsoleTrees shoeTransformString string - setCurrentPackage callingPackage - result - - -defaultBootToLispFile file == - CONCAT(shoeRemovebootIfNec file,'".clisp") - -translateBootFile(progname, options, file) == - outFile := getOutputPathname(options) - BOOTTOCL(file, ENOUGH_-NAMESTRING outFile) - -compileBootHandler(progname, options, file) == - intFile := BOOTTOCL(file, defaultBootToLispFile file) - intFile => - objFile := compileLispHandler(progname, options, intFile) - DELETE_-FILE intFile - objFile - nil - -associateRequestWithFileType(Option '"translate", '"boot", - function translateBootFile) -associateRequestWithFileType(Option '"compile", '"boot", - function compileBootHandler) -@ - -<<translator.clisp>>= (EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-translator")) (IMPORT-MODULE "includer") @@ -1219,6 +404,44 @@ associateRequestWithFileType(Option '"compile", '"boot", (DEFUN |shoeAddComment| (|l|) (PROG () (RETURN (CONCAT "; " (CAR |l|))))) +(DEFUN |genImportDeclaration| (|op| |sig|) + (PROG (|s| |t| |m| |ISTMP#2| |op'| |ISTMP#1|) + (RETURN + (COND + ((NOT (AND (CONSP |sig|) (EQ (CAR |sig|) '|Signature|) + (PROGN + (SETQ |ISTMP#1| (CDR |sig|)) + (AND (CONSP |ISTMP#1|) + (PROGN + (SETQ |op'| (CAR |ISTMP#1|)) + (SETQ |ISTMP#2| (CDR |ISTMP#1|)) + (AND (CONSP |ISTMP#2|) + (EQ (CDR |ISTMP#2|) NIL) + (PROGN + (SETQ |m| (CAR |ISTMP#2|)) + #0='T))))))) + (|coreError| "invalid signature")) + ((NOT (AND (CONSP |m|) (EQ (CAR |m|) '|Mapping|) + (PROGN + (SETQ |ISTMP#1| (CDR |m|)) + (AND (CONSP |ISTMP#1|) + (PROGN + (SETQ |t| (CAR |ISTMP#1|)) + (SETQ |ISTMP#2| (CDR |ISTMP#1|)) + (AND (CONSP |ISTMP#2|) + (EQ (CDR |ISTMP#2|) NIL) + (PROGN + (SETQ |s| (CAR |ISTMP#2|)) + #0#))))))) + (|coreError| "invalid function type")) + ((|%hasFeature| :GCL) + (PROGN + (COND ((SYMBOLP |s|) (SETQ |s| (LIST |s|)))) + (LIST 'DEFENTRY |op| |s| (LIST |t| (SYMBOL-NAME |op'|))))) + ('T + (|fatalError| + "import declaration not implemented for this Lisp")))))) + (DEFUN |shoeOutParse| (|stream|) (PROG (|$bpParenCount| |$bpCount| |$returns| |$typings| |$wheredefs| |$op| |$ttok| |$stok| |$stack| |$inputStream| |found|) @@ -1280,6 +503,11 @@ associateRequestWithFileType(Option '"compile", '"boot", (|Import| (LET ((|m| (CAR |bfVar#6|))) (|bpPush| (LIST (LIST 'IMPORT-MODULE |m|))))) + (|ImportSignature| + (LET ((|x| (CAR |bfVar#6|)) + (|sig| (CADR |bfVar#6|))) + (|bpPush| + (LIST (|genImportDeclaration| |x| |sig|))))) (|TypeAlias| (LET ((|t| (CAR |bfVar#6|)) (|args| (CADR |bfVar#6|)) @@ -1926,6 +1154,3 @@ associateRequestWithFileType(Option '"compile", '"boot", (|associateRequestWithFileType| (|Option| "compile") "boot" #'|compileBootHandler|)))) -@ - -\end{document} diff --git a/src/boot/tokens.boot b/src/boot/tokens.boot new file mode 100644 index 00000000..a64c6d56 --- /dev/null +++ b/src/boot/tokens.boot @@ -0,0 +1,411 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- All rights reserved. +-- Copyright (C) 2007-2008, Gabriel Dos Reis. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + +module '"boot-tokens" +import '"initial-env" + +)package "BOOTTRAN" + +++ Table of Boot keywords and their token name. +shoeKeyWords := [ _ + ['"and","AND"] , _ + ['"by", "BY" ], _ + ['"case","CASE"] , _ + ['"cross","CROSS"] , _ + ['"else", "ELSE"] , _ + ['"for", "FOR"] , _ + ['"if", "IF"], _ + ['"import", "IMPORT"], _ + ['"in", "IN" ], _ + ['"is", "IS"], _ + ['"isnt", "ISNT"] , _ + ['"module", "MODULE"], _ + ['"of", "OF"] , _ + ['"or", "OR"] , _ + ['"repeat", "REPEAT"] , _ + ['"return", "RETURN"], _ + ['"structure", "STRUCTURE"], _ + ['"then", "THEN"], _ + ['"until", "UNTIL"], _ + ['"where", "WHERE"], _ + ['"while", "WHILE"], _ + ['".", "DOT"], _ + ['":", "COLON"], _ + ['"::", "COLON-COLON"], _ + ['",", "COMMA"], _ + ['";", "SEMICOLON"], _ + ['"*", "TIMES"], _ + ['"**", "POWER"], _ + ['"/", "SLASH"], _ + ['"+", "PLUS"], _ + ['"-", "MINUS"], _ + ['"<", "LT"], _ + ['">", "GT"] , _ + ['"<=","LE" ], _ + ['">=","GE" ], _ + ['"=", "SHOEEQ"], _ + ['"^", "NOT"], _ + ['"^=","SHOENE" ], _ + ['"..","SEG" ], _ + ['"#", "LENGTH"], _ + ['"=>","EXIT" ], _ + ['"->", "ARROW"],_ + ['":=", "BEC"], _ + ['"==", "DEF"], _ + ['"==>","MDEF" ], _ + ['"<=>", "TDEF"], _ + ['"(", "OPAREN"], _ + ['")", "CPAREN"], _ + ['"(|", "OBRACK"], _ + ['"|)", "CBRACK"], _ + ['"[", "OBRACK"], _ + ['"]", "CBRACK"], _ + ['"suchthat","BAR"], _ + ['"'", "QUOTE"], _ + ['"|", "BAR"] ] + + + +shoeKeyTableCons()== + KeyTable:=MAKE_-HASHTABLE("CVEC") + for st in shoeKeyWords repeat + HPUT(KeyTable,CAR st,CADR st) + KeyTable + +shoeKeyTable:=shoeKeyTableCons() + +shoeSPACE := QENUM('" ", 0) + +shoeESCAPE := QENUM('"__ ", 0) +shoeLispESCAPE := QENUM('"! ", 0) + +shoeSTRING_CHAR := QENUM('"_" ", 0) + +shoePLUSCOMMENT := QENUM('"+ ", 0) + +shoeMINUSCOMMENT:= QENUM('"- ", 0) + +shoeDOT := QENUM('". ", 0) + +shoeEXPONENT1 := QENUM('"E ", 0) + +shoeEXPONENT2 := QENUM('"e ", 0) + +shoeCLOSEPAREN := QENUM('") ", 0) + +--shoeCLOSEANGLE := QENUM('"> ", 0) +shoeTAB := 9 + +shoeInsert(s,d) == + l := #s + h := QENUM(s,0) + u := ELT(d,h) + n := #u + k:=0 + while l <= #(ELT(u,k)) repeat + k:=k+1 + v := MAKE_-VEC(n+1) + for i in 0..k-1 repeat VEC_-SETELT(v,i,ELT(u,i)) + VEC_-SETELT(v,k,s) + for i in k..n-1 repeat VEC_-SETELT(v,i+1,ELT(u,i)) + VEC_-SETELT(d,h,v) + s + +shoeDictCons()== + l:= HKEYS shoeKeyTable + d := + a:=MAKE_-VEC(256) + b:=MAKE_-VEC(1) + VEC_-SETELT(b,0,MAKE_-CVEC 0) + for i in 0..255 repeat VEC_-SETELT(a,i,b) + a + for s in l repeat shoeInsert(s,d) + d + +shoeDict:=shoeDictCons() + + +shoePunCons()== + listing := HKEYS shoeKeyTable + a:=MAKE_-BVEC 256 + for i in 0..255 repeat BVEC_-SETELT(a,i,0) + for k in listing repeat + if not shoeStartsId k.0 + then BVEC_-SETELT(a,QENUM(k,0),1) + a + +shoePun:=shoePunCons() + +++ List of prefix operators. +for i in [ _ + "NOT", _ +-- "COLON", _ +-- "SHOEEQ", _ + "LENGTH" _ + ] _ + repeat SETF (GET(i,'SHOEPRE),'T) + +++ List of infix operators. +for i in [ _ + ["SHOEEQ" ,"="], _ + ["TIMES" ,"*"], _ + ["PLUS" ,"+"], _ + ["IS" ,"is"], _ + ["ISNT" ,"isnt"], _ + ["AND" ,"and"], _ + ["OR" ,"or"], _ + ["SLASH" ,"/"], _ + ["POWER" ,"**"], _ + ["MINUS" ,"-"], _ + ["LT" ,"<"], _ + ["GT" ,">"], _ + ["LE" ,"<="], _ + ["GE" ,">="], _ + ["SHOENE" ,"^="] _ + ]_ + repeat SETF (GET(CAR i,'SHOEINF),CADR i) + + +++ List of monoid operations and their neutral elements. +++ Note that `CONS' is not a monoid operations but support +++ right reduction. +for i in [ _ + ["+", 0] , _ + ["gcd", 0] , _ + ["lcm", 1] , _ + ["STRCONC", '""] , _ + ["strconc", '""] , _ + ["MAX", -999999] , _ + ["MIN", 999999] , _ + ["*", 1] , _ + ["times", 1] , _ + ["CONS", NIL] , _ + ["APPEND", NIL] , _ + ["append", NIL] , _ + ["UNION", NIL] , _ + ["UNIONQ", NIL] , _ + ["union", NIL] , _ + ["NCONC", NIL] , _ + ["and", 'T] , _ + ["or", NIL] , _ + ["AND", 'T] , _ + ["OR", NIL] _ + ] + + repeat SETF (GET(CAR i,'SHOETHETA),CDR i) +for i in [ _ + ["and", "AND"] , _ + ["append", "APPEND"] , _ + ["apply", "APPLY"] , _ + ["atom", "ATOM"] , _ + ["car", "CAR"] , _ + ["cdr", "CDR"] , _ + ["cons", "CONS"] , _ + ["copy", "COPY"] , _ + ["croak", "CROAK"] , _ + ["drop", "DROP"] , _ + ["exit", "EXIT"] , _ + ["false", 'NIL] , _ + ["first", "CAR"] , _ + ["function","FUNCTION"] , _ + ["genvar", "GENVAR"] , _ + ["IN", "MEMBER"] , _ + ["is", "IS"] , _ + ["isnt", "ISNT"] , _ + ["lastNode", "LAST"] , _ + ["LAST", "last"] , _ + ["list", "LIST"] , _ +-- ["member", "MEMBER"] , _ + ["mkpf", "MKPF"] , _ + ["nconc", "NCONC"] , _ + ["nil" ,NIL ] , _ + ["not", "NULL"] , _ + ["NOT", "NULL"] , _ + ["nreverse", "NREVERSE"] , _ + ["null", "NULL"] , _ + ["or", "OR"] , _ + ["otherwise", "T"] , _ + ["PAIRP", "CONSP"] , _ + ["removeDuplicates", "REMDUP"] , _ + ["rest", "CDR"] , _ + ["reverse", "REVERSE"] , _ + ["setDifference", "SETDIFFERENCE"] , _ + ["setIntersection", "INTERSECTION"] , _ + ["setPart", "SETELT"] , _ + ["setUnion", "UNION"] , _ + ["size", "SIZE"] , _ + ["strconc", "CONCAT"] , _ + ["substitute", "SUBST"] , _ + ["take", "TAKE"] , _ + ["true", "T"] , _ + ["PLUS", "+"] , _ + ["MINUS", "-"] , _ + ["TIMES", "*"] , _ + ["POWER", "EXPT"] , _ + ["SLASH", "/"] , _ + ["LT", "<"], _ + ["GT", ">"] , _ + ["LE", "<="], _ + ["GE", ">="], _ + ["SHOEEQ", "EQUAL"], _ + ["SHOENE", "/="], _ + ["T", "T$"] _ + ] + repeat SETF (GET(CAR i,'SHOERENAME),CDR i) + +-- For code written in `Old Boot', we would like to warn about +-- the difference in renaming. +for i in [ _ + ["PLUS", "PLUS"], _ + ["and", "AND"], _ + ["append", "APPEND"], _ + ["apply", "APPLY"], _ + ["atom", "ATOM"], _ + ["brace", "REMDUP"], _ + ["car", "CAR"], _ + ["cdr", "CDR"], _ + ["cons", "CONS"], _ + ["copy", "COPY"], _ + ["croak", "CROAK"], _ + ["drop", "DROP"], _ + ["exit", "EXIT"], _ + ["false", "NIL"], _ + ["first", "CAR"], _ + ["genvar", "GENVAR"], _ + ["in", "member"], _ + ["is", "IS"], _ + ["lastNode", "LASTNODE"], _ + ["list", "LIST"], _ + ["mkpf", "MKPF"], _ + ["nconc", "NCONC"], _ + ["nil", "NIL"], _ + ["not", "NULL"], _ + ["NOT", "NULL"], _ + ["nreverse", "NREVERSE"], _ + ["null", "NULL"], _ + ["or", "OR"], _ + ["otherwise", "T"], _ + ["removeDuplicates", "REMDUP"], _ + ["rest", "CDR"], _ + ["return", "RETURN"], _ + ["reverse", "REVERSE"], _ + ["setDifference", "SETDIFFERENCE"], _ + ["setIntersection", "intersection"], _ + ["setPart", "SETELT"], _ + ["setUnion", "union"], _ + ["size", "SIZE"], _ + ["strconc", "STRCONC"], _ + ["substitute", "MSUBST"], _ + ["SUBST", "MSUBST"], _ + ["take", "TAKE"], _ + ["true", "T"], _ + ["where", "WHERE"], _ + ["TIMES", "TIMES"], _ + ["POWER", "EXPT"], _ + ["NOT", "NULL"], _ + ["SHOENE", "NEQUAL"], _ + ["MINUS", "SPADDIFFERENCE"], _ + ["SLASH", "QUOTIENT"], _ + ["=", "EQUAL"], _ + ["SHOEEQ", "EQUAL"], _ + ["ASSOC", "assoc"], _ + ["DELETE", "delete"], _ + ["GET", "GETL"], _ + ["INTERSECTION", "intersection"], _ + ["LAST", "last"], _ + ["MEMBER", "member"], _ + ["RASSOC", "rassoc"], _ + ["READ", "VMREAD"], _ + ["READ-LINE", "read-line"], _ + ["REDUCE", "SPADREDUCE"], _ + ["REMOVE", "remove"], _ + ["BAR", "SUCHTHAT"], _ + ["T", "T$"], _ + ["IN", "member"], _ + ["UNION", "union"]_ + ] + repeat SETF (GET(CAR i,'OLD_-BOOT),CDR i) + +-- The following difference in renaming are verified to be OK. +for i in [ _ + "LT", "LE", _ + "GT", "GE", _ + "SHOENE", _ + "TIMES", "PLUS", _ + "MINUS", "function",_ + "PAIRP" + ] + repeat SETF(GET(i, 'RENAME_-OK), true) + + + +for i in [ _ + ["setName", 0] , _ + ["setLabel", 1] , _ + ["setLevel", 2] , _ + ["setType", 3] , _ + ["setVar", 4] , _ + ["setLeaf", 5] , _ + ["setDef", 6] , _ + ["aGeneral", 4] , _ + ["aMode", 1] , _ + ["aModeSet", 3] , _ + ["aTree", 0] , _ + ["aValue", 2] , _ + ["attributes", "CADDR"] , _ + ["cacheCount", "CADDDDR"] , _ + ["cacheName", "CADR"] , _ + ["cacheReset", "CADDDR"] , _ + ["cacheType", "CADDR"] , _ + ["env", "CADDR"] , _ + ["expr", "CAR"] , _ + ["CAR", "CAR"] , _ + ["mmCondition", "CAADR"] , _ + ["mmDC", "CAAR"] , _ + ["mmImplementation","CADADR"] , _ + ["mmSignature", "CDAR"] , _ + ["mmTarget", "CADAR"] , _ + ["mode", "CADR"] , _ + ["op", "CAR"] , _ + ["opcode", "CADR"] , _ + ["opSig", "CADR"] , _ + ["CDR", "CDR"] , _ + ["sig", "CDDR"] , _ + ["source", "CDR"] , _ + ["streamCode", "CADDDR"] , _ + ["streamDef", "CADDR"] , _ + ["streamName", "CADR"] , _ + ["target", "CAR"] _ + ] _ + repeat SETF (GET(CAR i,'SHOESELFUNCTION),CADR i) diff --git a/src/boot/tokens.boot.pamphlet b/src/boot/tokens.boot.pamphlet deleted file mode 100644 index bb4d7ec2..00000000 --- a/src/boot/tokens.boot.pamphlet +++ /dev/null @@ -1,897 +0,0 @@ -\documentclass{article} -\usepackage{axiom} - -\title{\File{src/boot/tokens.boot} Pamphlet} -\author{The Axiom Team} - -\begin{document} -\maketitle - -\begin{abstract} -\end{abstract} - -\tableofcontents -\eject - - -\section{License} - -<<license>>= --- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. --- All rights reserved. --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions are --- met: --- --- - Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- --- - Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in --- the documentation and/or other materials provided with the --- distribution. --- --- - Neither the name of The Numerical ALgorithms Group Ltd. nor the --- names of its contributors may be used to endorse or promote products --- derived from this software without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS --- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER --- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING --- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS --- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -@ - - -\section{Key words} -\label{sec:boot:key-words} - -The following tokens are reserved as Boot key words: -\begin{center} -\begin{tabular}{lllllll} - \Code{and} & \Code{by} & \Code{case} & - \Code{cross} & \Code{else} & \Code{for} & \Code{if} - \\ - \Code{import} & \Code{in} & \Code{is} & - \Code{isnt} & \Code{module} & \Code{of} & \Code{or} - \\ - \Code{repeat} &\Code{return} & \Code{structure} & - \Code{then} & \Code{until} & \Code{where} & \Code{while} - \\ - \Code{.} & \Code{:} & \Code{::} & - \Code{,} & \Code{;} & \Code{*} & \Code{**} - \\ - \Code{/} & \Code{+} & \Code{-} & - \Code{<} & \Code{>} & \Code{<=} & \Code{>=} - \\ - \Code{=} & \Code{\^} & \verb!\^=! & - \Code{..} & \Code{\#} & \Code{=>} & \Code{:=} - \\ - \Code{==} & \Code{==>} & \Code{(} & - \Code{)} & \Code{[} & \Code{]} & \Code{'} - \\ - \Code{|} -\end{tabular} -\end{center} - - -\section{Prefix operators} -\label{sec:boot:prefix-ops} - -The following key words designate prefix operators -\begin{center} - \begin{tabular}{ll} - \Code{not} & \Code{\#} - \end{tabular} -\end{center} - - -\section{Infix operators} -\label{sec:boot:infix-ops} - -The following key words designate infix operators -\begin{center} - \begin{tabular}{llllll} - \Code{=} & \Code{*} & \Code{+} & \Code{is} & \Code{isnt} & \Code{and} - \\ - \Code{or} & \Code{/} & \Code{**} & \Code{-} & \Code{<} & \Code{>} - \\ - & \Code{<=} & \Code{>=} & \verb!^=! - \end{tabular} -\end{center} - - -\section{Monoid operations and reduction} -\label{sec:boot:monoid-ops} - -Some Boot standard operations are monoid functions, therefore -usable as operand to the reduction functional. We list below -all such Boot standard operations, along with their neutral elements. -\begin{center} - \begin{tabular}{|ll|ll|ll|} - \hline - Operation & Unit & Operation & Unit & Operation & Unit - \\ - \hline - \Code{+} & \Code{0} & - \Code{gdc} & \Code{0} & - \Code{lcm} & \Code{1} - \\ - \Code{STRCONC} & \Code{""} & - \Code{strconc} & \Code{""} & - \Code{MAX} & \Code{-999999} - \\ - \Code{MIN} & \Code{999999} & - \Code{*} & \Code{1} & - \Code{times} & \Code{1} - \\ - \Code{CONS} & \Code{nil} & - \Code{APPEND} & \Code{nil} & - \Code{append} & \Code{nil} - \\ - \Code{UNION} & \Code{nil} & - \Code{UNIONQ} & \Code{nil} & - \Code{union} & \Code{nil} - \\ - \Code{NCONC} & \Code{nil} & - \Code{and} & \Code{true} & - \Code{or} & \Code{false} - \\ - \Code{AND} & \Code{true} & - \Code{OR} & \Code{false} & - \\ - \hline - \end{tabular} -\end{center} - -Note that \Code{CONS} is not a monoid operation; it however supports -right reduction. - - - - -\section{Putting everything together} - -<<*>>= -<<license>> - -module '"boot-tokens" -import '"initial-env" - -)package "BOOTTRAN" - -shoeKeyWords := [ _ - ['"and","AND"] , _ - ['"by", "BY" ], _ - ['"case","CASE"] , _ - ['"cross","CROSS"] , _ - ['"else", "ELSE"] , _ - ['"for", "FOR"] , _ - ['"if", "IF"], _ - ['"import", "IMPORT"], _ - ['"in", "IN" ], _ - ['"is", "IS"], _ - ['"isnt", "ISNT"] , _ - ['"module", "MODULE"], _ - ['"of", "OF"] , _ - ['"or", "OR"] , _ - ['"repeat", "REPEAT"] , _ - ['"return", "RETURN"], _ - ['"structure", "STRUCTURE"], _ - ['"then", "THEN"], _ - ['"until", "UNTIL"], _ - ['"where", "WHERE"], _ - ['"while", "WHILE"], _ - ['".", "DOT"], _ - ['":", "COLON"], _ - ['"::", "COLON-COLON"], _ - ['",", "COMMA"], _ - ['";", "SEMICOLON"], _ - ['"*", "TIMES"], _ - ['"**", "POWER"], _ - ['"/", "SLASH"], _ - ['"+", "PLUS"], _ - ['"-", "MINUS"], _ - ['"<", "LT"], _ - ['">", "GT"] , _ - ['"<=","LE" ], _ - ['">=","GE" ], _ - ['"=", "SHOEEQ"], _ - ['"^", "NOT"], _ - ['"^=","SHOENE" ], _ - ['"..","SEG" ], _ - ['"#", "LENGTH"], _ - ['"=>","EXIT" ], _ - ['"->", "ARROW"],_ - ['":=", "BEC"], _ - ['"==", "DEF"], _ - ['"==>","MDEF" ], _ - ['"<=>", "TDEF"], _ - ['"(", "OPAREN"], _ - ['")", "CPAREN"], _ - ['"(|", "OBRACK"], _ - ['"|)", "CBRACK"], _ - ['"[", "OBRACK"], _ - ['"]", "CBRACK"], _ - ['"suchthat","BAR"], _ - ['"'", "QUOTE"], _ - ['"|", "BAR"] ] - - - -shoeKeyTableCons()== - KeyTable:=MAKE_-HASHTABLE("CVEC") - for st in shoeKeyWords repeat - HPUT(KeyTable,CAR st,CADR st) - KeyTable - -shoeKeyTable:=shoeKeyTableCons() - -shoeSPACE := QENUM('" ", 0) - -shoeESCAPE := QENUM('"__ ", 0) -shoeLispESCAPE := QENUM('"! ", 0) - -shoeSTRING_CHAR := QENUM('"_" ", 0) - -shoePLUSCOMMENT := QENUM('"+ ", 0) - -shoeMINUSCOMMENT:= QENUM('"- ", 0) - -shoeDOT := QENUM('". ", 0) - -shoeEXPONENT1 := QENUM('"E ", 0) - -shoeEXPONENT2 := QENUM('"e ", 0) - -shoeCLOSEPAREN := QENUM('") ", 0) - ---shoeCLOSEANGLE := QENUM('"> ", 0) -shoeTAB := 9 - -shoeInsert(s,d) == - l := #s - h := QENUM(s,0) - u := ELT(d,h) - n := #u - k:=0 - while l <= #(ELT(u,k)) repeat - k:=k+1 - v := MAKE_-VEC(n+1) - for i in 0..k-1 repeat VEC_-SETELT(v,i,ELT(u,i)) - VEC_-SETELT(v,k,s) - for i in k..n-1 repeat VEC_-SETELT(v,i+1,ELT(u,i)) - VEC_-SETELT(d,h,v) - s - -shoeDictCons()== - l:= HKEYS shoeKeyTable - d := - a:=MAKE_-VEC(256) - b:=MAKE_-VEC(1) - VEC_-SETELT(b,0,MAKE_-CVEC 0) - for i in 0..255 repeat VEC_-SETELT(a,i,b) - a - for s in l repeat shoeInsert(s,d) - d - -shoeDict:=shoeDictCons() - - -shoePunCons()== - listing := HKEYS shoeKeyTable - a:=MAKE_-BVEC 256 - for i in 0..255 repeat BVEC_-SETELT(a,i,0) - for k in listing repeat - if not shoeStartsId k.0 - then BVEC_-SETELT(a,QENUM(k,0),1) - a - -shoePun:=shoePunCons() - -for i in [ _ - "NOT", _ --- "COLON", _ --- "SHOEEQ", _ - "LENGTH" _ - ] _ - repeat SETF (GET(i,'SHOEPRE),'T) - -for i in [ _ - ["SHOEEQ" ,"="], _ - ["TIMES" ,"*"], _ - ["PLUS" ,"+"], _ - ["IS" ,"is"], _ - ["ISNT" ,"isnt"], _ - ["AND" ,"and"], _ - ["OR" ,"or"], _ - ["SLASH" ,"/"], _ - ["POWER" ,"**"], _ - ["MINUS" ,"-"], _ - ["LT" ,"<"], _ - ["GT" ,">"], _ - ["LE" ,"<="], _ - ["GE" ,">="], _ - ["SHOENE" ,"^="] _ - ]_ - repeat SETF (GET(CAR i,'SHOEINF),CADR i) - - -for i in [ _ - ["+", 0] , _ - ["gcd", 0] , _ - ["lcm", 1] , _ - ["STRCONC", '""] , _ - ["strconc", '""] , _ - ["MAX", -999999] , _ - ["MIN", 999999] , _ - ["*", 1] , _ - ["times", 1] , _ - ["CONS", NIL] , _ - ["APPEND", NIL] , _ - ["append", NIL] , _ - ["UNION", NIL] , _ - ["UNIONQ", NIL] , _ - ["union", NIL] , _ - ["NCONC", NIL] , _ - ["and", 'T] , _ - ["or", NIL] , _ - ["AND", 'T] , _ - ["OR", NIL] _ - ] - - repeat SETF (GET(CAR i,'SHOETHETA),CDR i) -for i in [ _ - ["and", "AND"] , _ - ["append", "APPEND"] , _ - ["apply", "APPLY"] , _ - ["atom", "ATOM"] , _ - ["car", "CAR"] , _ - ["cdr", "CDR"] , _ - ["cons", "CONS"] , _ - ["copy", "COPY"] , _ - ["croak", "CROAK"] , _ - ["drop", "DROP"] , _ - ["exit", "EXIT"] , _ - ["false", 'NIL] , _ - ["first", "CAR"] , _ - ["function","FUNCTION"] , _ - ["genvar", "GENVAR"] , _ - ["IN", "MEMBER"] , _ - ["is", "IS"] , _ - ["isnt", "ISNT"] , _ - ["lastNode", "LAST"] , _ - ["LAST", "last"] , _ - ["list", "LIST"] , _ --- ["member", "MEMBER"] , _ - ["mkpf", "MKPF"] , _ - ["nconc", "NCONC"] , _ - ["nil" ,NIL ] , _ - ["not", "NULL"] , _ - ["NOT", "NULL"] , _ - ["nreverse", "NREVERSE"] , _ - ["null", "NULL"] , _ - ["or", "OR"] , _ - ["otherwise", "T"] , _ - ["PAIRP", "CONSP"] , _ - ["removeDuplicates", "REMDUP"] , _ - ["rest", "CDR"] , _ - ["reverse", "REVERSE"] , _ - ["setDifference", "SETDIFFERENCE"] , _ - ["setIntersection", "INTERSECTION"] , _ - ["setPart", "SETELT"] , _ - ["setUnion", "UNION"] , _ - ["size", "SIZE"] , _ - ["strconc", "CONCAT"] , _ - ["substitute", "SUBST"] , _ - ["take", "TAKE"] , _ - ["true", "T"] , _ - ["PLUS", "+"] , _ - ["MINUS", "-"] , _ - ["TIMES", "*"] , _ - ["POWER", "EXPT"] , _ - ["SLASH", "/"] , _ - ["LT", "<"], _ - ["GT", ">"] , _ - ["LE", "<="], _ - ["GE", ">="], _ - ["SHOEEQ", "EQUAL"], _ - ["SHOENE", "/="], _ - ["T", "T$"] _ - ] - repeat SETF (GET(CAR i,'SHOERENAME),CDR i) - --- For code written in `Old Boot', we would like to warn about --- the difference in renaming. -for i in [ _ - ["PLUS", "PLUS"], _ - ["and", "AND"], _ - ["append", "APPEND"], _ - ["apply", "APPLY"], _ - ["atom", "ATOM"], _ - ["brace", "REMDUP"], _ - ["car", "CAR"], _ - ["cdr", "CDR"], _ - ["cons", "CONS"], _ - ["copy", "COPY"], _ - ["croak", "CROAK"], _ - ["drop", "DROP"], _ - ["exit", "EXIT"], _ - ["false", "NIL"], _ - ["first", "CAR"], _ - ["genvar", "GENVAR"], _ - ["in", "member"], _ - ["is", "IS"], _ - ["lastNode", "LASTNODE"], _ - ["list", "LIST"], _ - ["mkpf", "MKPF"], _ - ["nconc", "NCONC"], _ - ["nil", "NIL"], _ - ["not", "NULL"], _ - ["NOT", "NULL"], _ - ["nreverse", "NREVERSE"], _ - ["null", "NULL"], _ - ["or", "OR"], _ - ["otherwise", "T"], _ - ["removeDuplicates", "REMDUP"], _ - ["rest", "CDR"], _ - ["return", "RETURN"], _ - ["reverse", "REVERSE"], _ - ["setDifference", "SETDIFFERENCE"], _ - ["setIntersection", "intersection"], _ - ["setPart", "SETELT"], _ - ["setUnion", "union"], _ - ["size", "SIZE"], _ - ["strconc", "STRCONC"], _ - ["substitute", "MSUBST"], _ - ["SUBST", "MSUBST"], _ - ["take", "TAKE"], _ - ["true", "T"], _ - ["where", "WHERE"], _ - ["TIMES", "TIMES"], _ - ["POWER", "EXPT"], _ - ["NOT", "NULL"], _ - ["SHOENE", "NEQUAL"], _ - ["MINUS", "SPADDIFFERENCE"], _ - ["SLASH", "QUOTIENT"], _ - ["=", "EQUAL"], _ - ["SHOEEQ", "EQUAL"], _ - ["ASSOC", "assoc"], _ - ["DELETE", "delete"], _ - ["GET", "GETL"], _ - ["INTERSECTION", "intersection"], _ - ["LAST", "last"], _ - ["MEMBER", "member"], _ - ["RASSOC", "rassoc"], _ - ["READ", "VMREAD"], _ - ["READ-LINE", "read-line"], _ - ["REDUCE", "SPADREDUCE"], _ - ["REMOVE", "remove"], _ - ["BAR", "SUCHTHAT"], _ - ["T", "T$"], _ - ["IN", "member"], _ - ["UNION", "union"]_ - ] - repeat SETF (GET(CAR i,'OLD_-BOOT),CDR i) - --- The following difference in renaming are verified to be OK. -for i in [ _ - "LT", "LE", _ - "GT", "GE", _ - "SHOENE", _ - "TIMES", "PLUS", _ - "MINUS", "function",_ - "PAIRP" - ] - repeat SETF(GET(i, 'RENAME_-OK), true) - - - -for i in [ _ - ["setName", 0] , _ - ["setLabel", 1] , _ - ["setLevel", 2] , _ - ["setType", 3] , _ - ["setVar", 4] , _ - ["setLeaf", 5] , _ - ["setDef", 6] , _ - ["aGeneral", 4] , _ - ["aMode", 1] , _ - ["aModeSet", 3] , _ - ["aTree", 0] , _ - ["aValue", 2] , _ - ["attributes", "CADDR"] , _ - ["cacheCount", "CADDDDR"] , _ - ["cacheName", "CADR"] , _ - ["cacheReset", "CADDDR"] , _ - ["cacheType", "CADDR"] , _ - ["env", "CADDR"] , _ - ["expr", "CAR"] , _ - ["CAR", "CAR"] , _ - ["mmCondition", "CAADR"] , _ - ["mmDC", "CAAR"] , _ - ["mmImplementation","CADADR"] , _ - ["mmSignature", "CDAR"] , _ - ["mmTarget", "CADAR"] , _ - ["mode", "CADR"] , _ - ["op", "CAR"] , _ - ["opcode", "CADR"] , _ - ["opSig", "CADR"] , _ - ["CDR", "CDR"] , _ - ["sig", "CDDR"] , _ - ["source", "CDR"] , _ - ["streamCode", "CADDDR"] , _ - ["streamDef", "CADDR"] , _ - ["streamName", "CADR"] , _ - ["target", "CAR"] _ - ] _ - repeat SETF (GET(CAR i,'SHOESELFUNCTION),CADR i) -@ - -<<tokens.clisp>>= -(EVAL-WHEN (:COMPILE-TOPLEVEL) (PROVIDE "boot-tokens")) - -(IMPORT-MODULE "initial-env") - -(IN-PACKAGE "BOOTTRAN") - -(DEFPARAMETER |shoeKeyWords| - (LIST (LIST "and" 'AND) (LIST "by" 'BY) (LIST "case" 'CASE) - (LIST "cross" 'CROSS) (LIST "else" 'ELSE) (LIST "for" 'FOR) - (LIST "if" 'IF) (LIST "import" 'IMPORT) (LIST "in" 'IN) - (LIST "is" 'IS) (LIST "isnt" 'ISNT) (LIST "module" 'MODULE) - (LIST "of" 'OF) (LIST "or" 'OR) (LIST "repeat" 'REPEAT) - (LIST "return" 'RETURN) (LIST "structure" 'STRUCTURE) - (LIST "then" 'THEN) (LIST "until" 'UNTIL) - (LIST "where" 'WHERE) (LIST "while" 'WHILE) (LIST "." 'DOT) - (LIST ":" 'COLON) (LIST "::" 'COLON-COLON) (LIST "," 'COMMA) - (LIST ";" 'SEMICOLON) (LIST "*" 'TIMES) (LIST "**" 'POWER) - (LIST "/" 'SLASH) (LIST "+" 'PLUS) (LIST "-" 'MINUS) - (LIST "<" 'LT) (LIST ">" 'GT) (LIST "<=" 'LE) (LIST ">=" 'GE) - (LIST "=" 'SHOEEQ) (LIST "^" 'NOT) (LIST "^=" 'SHOENE) - (LIST ".." 'SEG) (LIST "#" 'LENGTH) (LIST "=>" 'EXIT) - (LIST ":=" 'BEC) (LIST "==" 'DEF) (LIST "==>" 'MDEF) - (LIST "<=>" 'TDEF) (LIST "(" 'OPAREN) (LIST ")" 'CPAREN) - (LIST "(|" 'OBRACK) (LIST "|)" 'CBRACK) (LIST "[" 'OBRACK) - (LIST "]" 'CBRACK) (LIST "suchthat" 'BAR) (LIST "'" 'QUOTE) - (LIST "|" 'BAR))) - -(DEFUN |shoeKeyTableCons| () - (PROG (|KeyTable|) - (RETURN - (PROGN - (SETQ |KeyTable| (MAKE-HASHTABLE 'CVEC)) - (LET ((|bfVar#1| |shoeKeyWords|) (|st| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#1|) - (PROGN (SETQ |st| (CAR |bfVar#1|)) NIL)) - (RETURN NIL)) - ('T (HPUT |KeyTable| (CAR |st|) (CADR |st|)))) - (SETQ |bfVar#1| (CDR |bfVar#1|)))) - |KeyTable|)))) - -(DEFPARAMETER |shoeKeyTable| (|shoeKeyTableCons|)) - -(DEFPARAMETER |shoeSPACE| (QENUM " " 0)) - -(DEFPARAMETER |shoeESCAPE| (QENUM "_ " 0)) - -(DEFPARAMETER |shoeLispESCAPE| (QENUM "! " 0)) - -(DEFPARAMETER |shoeSTRINGCHAR| (QENUM "\" " 0)) - -(DEFPARAMETER |shoePLUSCOMMENT| (QENUM "+ " 0)) - -(DEFPARAMETER |shoeMINUSCOMMENT| (QENUM "- " 0)) - -(DEFPARAMETER |shoeDOT| (QENUM ". " 0)) - -(DEFPARAMETER |shoeEXPONENT1| (QENUM "E " 0)) - -(DEFPARAMETER |shoeEXPONENT2| (QENUM "e " 0)) - -(DEFPARAMETER |shoeCLOSEPAREN| (QENUM ") " 0)) - -(DEFPARAMETER |shoeTAB| 9) - -(DEFUN |shoeInsert| (|s| |d|) - (PROG (|v| |k| |n| |u| |h| |l|) - (RETURN - (PROGN - (SETQ |l| (LENGTH |s|)) - (SETQ |h| (QENUM |s| 0)) - (SETQ |u| (ELT |d| |h|)) - (SETQ |n| (LENGTH |u|)) - (SETQ |k| 0) - (LOOP - (COND - ((< (LENGTH (ELT |u| |k|)) |l|) (RETURN NIL)) - (#0='T (SETQ |k| (+ |k| 1))))) - (SETQ |v| (MAKE-VEC (+ |n| 1))) - (LET ((|bfVar#2| (- |k| 1)) (|i| 0)) - (LOOP - (COND - ((> |i| |bfVar#2|) (RETURN NIL)) - (#0# (VEC-SETELT |v| |i| (ELT |u| |i|)))) - (SETQ |i| (+ |i| 1)))) - (VEC-SETELT |v| |k| |s|) - (LET ((|bfVar#3| (- |n| 1)) (|i| |k|)) - (LOOP - (COND - ((> |i| |bfVar#3|) (RETURN NIL)) - (#0# (VEC-SETELT |v| (+ |i| 1) (ELT |u| |i|)))) - (SETQ |i| (+ |i| 1)))) - (VEC-SETELT |d| |h| |v|) - |s|)))) - -(DEFUN |shoeDictCons| () - (PROG (|d| |b| |a| |l|) - (RETURN - (PROGN - (SETQ |l| (HKEYS |shoeKeyTable|)) - (SETQ |d| - (PROGN - (SETQ |a| (MAKE-VEC 256)) - (SETQ |b| (MAKE-VEC 1)) - (VEC-SETELT |b| 0 (MAKE-CVEC 0)) - (LET ((|i| 0)) - (LOOP - (COND - ((> |i| 255) (RETURN NIL)) - (#0='T (VEC-SETELT |a| |i| |b|))) - (SETQ |i| (+ |i| 1)))) - |a|)) - (LET ((|bfVar#4| |l|) (|s| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#4|) - (PROGN (SETQ |s| (CAR |bfVar#4|)) NIL)) - (RETURN NIL)) - (#0# (|shoeInsert| |s| |d|))) - (SETQ |bfVar#4| (CDR |bfVar#4|)))) - |d|)))) - -(DEFPARAMETER |shoeDict| (|shoeDictCons|)) - -(DEFUN |shoePunCons| () - (PROG (|a| |listing|) - (RETURN - (PROGN - (SETQ |listing| (HKEYS |shoeKeyTable|)) - (SETQ |a| (MAKE-BVEC 256)) - (LET ((|i| 0)) - (LOOP - (COND - ((> |i| 255) (RETURN NIL)) - (#0='T (BVEC-SETELT |a| |i| 0))) - (SETQ |i| (+ |i| 1)))) - (LET ((|bfVar#5| |listing|) (|k| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#5|) - (PROGN (SETQ |k| (CAR |bfVar#5|)) NIL)) - (RETURN NIL)) - (#0# - (COND - ((NULL (|shoeStartsId| (ELT |k| 0))) - (BVEC-SETELT |a| (QENUM |k| 0) 1))))) - (SETQ |bfVar#5| (CDR |bfVar#5|)))) - |a|)))) - -(DEFPARAMETER |shoePun| (|shoePunCons|)) - -(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) - (PROG () - (RETURN - (LET ((|bfVar#6| (LIST 'NOT 'LENGTH)) (|i| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#6|) - (PROGN (SETQ |i| (CAR |bfVar#6|)) NIL)) - (RETURN NIL)) - ('T (SETF (GET |i| 'SHOEPRE) 'T))) - (SETQ |bfVar#6| (CDR |bfVar#6|))))))) - -(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) - (PROG () - (RETURN - (LET ((|bfVar#7| - (LIST (LIST 'SHOEEQ '=) (LIST 'TIMES '*) - (LIST 'PLUS '+) (LIST 'IS '|is|) - (LIST 'ISNT '|isnt|) (LIST 'AND '|and|) - (LIST 'OR '|or|) (LIST 'SLASH '/) - (LIST 'POWER '**) (LIST 'MINUS '-) (LIST 'LT '<) - (LIST 'GT '>) (LIST 'LE '<=) (LIST 'GE '>=) - (LIST 'SHOENE '^=))) - (|i| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#7|) - (PROGN (SETQ |i| (CAR |bfVar#7|)) NIL)) - (RETURN NIL)) - ('T (SETF (GET (CAR |i|) 'SHOEINF) (CADR |i|)))) - (SETQ |bfVar#7| (CDR |bfVar#7|))))))) - -(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) - (PROG () - (RETURN - (LET ((|bfVar#8| - (LIST (LIST '+ 0) (LIST '|gcd| 0) (LIST '|lcm| 1) - (LIST 'STRCONC "") (LIST '|strconc| "") - (LIST 'MAX (- 999999)) (LIST 'MIN 999999) - (LIST '* 1) (LIST '|times| 1) (LIST 'CONS NIL) - (LIST 'APPEND NIL) (LIST '|append| NIL) - (LIST 'UNION NIL) (LIST 'UNIONQ NIL) - (LIST '|union| NIL) (LIST 'NCONC NIL) - (LIST '|and| 'T) (LIST '|or| NIL) (LIST 'AND 'T) - (LIST 'OR NIL))) - (|i| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#8|) - (PROGN (SETQ |i| (CAR |bfVar#8|)) NIL)) - (RETURN NIL)) - ('T (SETF (GET (CAR |i|) 'SHOETHETA) (CDR |i|)))) - (SETQ |bfVar#8| (CDR |bfVar#8|))))))) - -(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) - (PROG () - (RETURN - (LET ((|bfVar#9| - (LIST (LIST '|and| 'AND) (LIST '|append| 'APPEND) - (LIST '|apply| 'APPLY) (LIST '|atom| 'ATOM) - (LIST '|car| 'CAR) (LIST '|cdr| 'CDR) - (LIST '|cons| 'CONS) (LIST '|copy| 'COPY) - (LIST '|croak| 'CROAK) (LIST '|drop| 'DROP) - (LIST '|exit| 'EXIT) (LIST '|false| 'NIL) - (LIST '|first| 'CAR) (LIST '|function| 'FUNCTION) - (LIST '|genvar| 'GENVAR) (LIST 'IN 'MEMBER) - (LIST '|is| 'IS) (LIST '|isnt| 'ISNT) - (LIST '|lastNode| 'LAST) (LIST 'LAST '|last|) - (LIST '|list| 'LIST) (LIST '|mkpf| 'MKPF) - (LIST '|nconc| 'NCONC) (LIST '|nil| NIL) - (LIST '|not| 'NULL) (LIST 'NOT 'NULL) - (LIST '|nreverse| 'NREVERSE) (LIST '|null| 'NULL) - (LIST '|or| 'OR) (LIST '|otherwise| 'T) - (LIST 'PAIRP 'CONSP) - (LIST '|removeDuplicates| 'REMDUP) - (LIST '|rest| 'CDR) (LIST '|reverse| 'REVERSE) - (LIST '|setDifference| 'SETDIFFERENCE) - (LIST '|setIntersection| 'INTERSECTION) - (LIST '|setPart| 'SETELT) - (LIST '|setUnion| 'UNION) (LIST '|size| 'SIZE) - (LIST '|strconc| 'CONCAT) - (LIST '|substitute| 'SUBST) (LIST '|take| 'TAKE) - (LIST '|true| 'T) (LIST 'PLUS '+) - (LIST 'MINUS '-) (LIST 'TIMES '*) - (LIST 'POWER 'EXPT) (LIST 'SLASH '/) - (LIST 'LT '<) (LIST 'GT '>) (LIST 'LE '<=) - (LIST 'GE '>=) (LIST 'SHOEEQ 'EQUAL) - (LIST 'SHOENE '/=) (LIST 'T 'T$))) - (|i| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#9|) - (PROGN (SETQ |i| (CAR |bfVar#9|)) NIL)) - (RETURN NIL)) - ('T (SETF (GET (CAR |i|) 'SHOERENAME) (CDR |i|)))) - (SETQ |bfVar#9| (CDR |bfVar#9|))))))) - -(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) - (PROG () - (RETURN - (LET ((|bfVar#10| - (LIST (LIST 'PLUS 'PLUS) (LIST '|and| 'AND) - (LIST '|append| 'APPEND) (LIST '|apply| 'APPLY) - (LIST '|atom| 'ATOM) (LIST '|brace| 'REMDUP) - (LIST '|car| 'CAR) (LIST '|cdr| 'CDR) - (LIST '|cons| 'CONS) (LIST '|copy| 'COPY) - (LIST '|croak| 'CROAK) (LIST '|drop| 'DROP) - (LIST '|exit| 'EXIT) (LIST '|false| 'NIL) - (LIST '|first| 'CAR) (LIST '|genvar| 'GENVAR) - (LIST '|in| '|member|) (LIST '|is| 'IS) - (LIST '|lastNode| 'LASTNODE) (LIST '|list| 'LIST) - (LIST '|mkpf| 'MKPF) (LIST '|nconc| 'NCONC) - (LIST '|nil| 'NIL) (LIST '|not| 'NULL) - (LIST 'NOT 'NULL) (LIST '|nreverse| 'NREVERSE) - (LIST '|null| 'NULL) (LIST '|or| 'OR) - (LIST '|otherwise| 'T) - (LIST '|removeDuplicates| 'REMDUP) - (LIST '|rest| 'CDR) (LIST '|return| 'RETURN) - (LIST '|reverse| 'REVERSE) - (LIST '|setDifference| 'SETDIFFERENCE) - (LIST '|setIntersection| '|intersection|) - (LIST '|setPart| 'SETELT) - (LIST '|setUnion| '|union|) (LIST '|size| 'SIZE) - (LIST '|strconc| 'STRCONC) - (LIST '|substitute| 'MSUBST) - (LIST 'SUBST 'MSUBST) (LIST '|take| 'TAKE) - (LIST '|true| 'T) (LIST '|where| 'WHERE) - (LIST 'TIMES 'TIMES) (LIST 'POWER 'EXPT) - (LIST 'NOT 'NULL) (LIST 'SHOENE 'NEQUAL) - (LIST 'MINUS 'SPADDIFFERENCE) - (LIST 'SLASH 'QUOTIENT) (LIST '= 'EQUAL) - (LIST 'SHOEEQ 'EQUAL) (LIST 'ASSOC '|assoc|) - (LIST 'DELETE '|delete|) (LIST 'GET 'GETL) - (LIST 'INTERSECTION '|intersection|) - (LIST 'LAST '|last|) (LIST 'MEMBER '|member|) - (LIST 'RASSOC '|rassoc|) (LIST 'READ 'VMREAD) - (LIST 'READ-LINE '|read-line|) - (LIST 'REDUCE 'SPADREDUCE) - (LIST 'REMOVE '|remove|) (LIST 'BAR 'SUCHTHAT) - (LIST 'T 'T$) (LIST 'IN '|member|) - (LIST 'UNION '|union|))) - (|i| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#10|) - (PROGN (SETQ |i| (CAR |bfVar#10|)) NIL)) - (RETURN NIL)) - ('T (SETF (GET (CAR |i|) 'OLD-BOOT) (CDR |i|)))) - (SETQ |bfVar#10| (CDR |bfVar#10|))))))) - -(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) - (PROG () - (RETURN - (LET ((|bfVar#11| - (LIST 'LT 'LE 'GT 'GE 'SHOENE 'TIMES 'PLUS 'MINUS - '|function| 'PAIRP)) - (|i| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#11|) - (PROGN (SETQ |i| (CAR |bfVar#11|)) NIL)) - (RETURN NIL)) - ('T (SETF (GET |i| 'RENAME-OK) T))) - (SETQ |bfVar#11| (CDR |bfVar#11|))))))) - -(EVAL-WHEN (:EXECUTE :LOAD-TOPLEVEL) - (PROG () - (RETURN - (LET ((|bfVar#12| - (LIST (LIST '|setName| 0) (LIST '|setLabel| 1) - (LIST '|setLevel| 2) (LIST '|setType| 3) - (LIST '|setVar| 4) (LIST '|setLeaf| 5) - (LIST '|setDef| 6) (LIST '|aGeneral| 4) - (LIST '|aMode| 1) (LIST '|aModeSet| 3) - (LIST '|aTree| 0) (LIST '|aValue| 2) - (LIST '|attributes| 'CADDR) - (LIST '|cacheCount| 'CADDDDR) - (LIST '|cacheName| 'CADR) - (LIST '|cacheReset| 'CADDDR) - (LIST '|cacheType| 'CADDR) (LIST '|env| 'CADDR) - (LIST '|expr| 'CAR) (LIST 'CAR 'CAR) - (LIST '|mmCondition| 'CAADR) (LIST '|mmDC| 'CAAR) - (LIST '|mmImplementation| 'CADADR) - (LIST '|mmSignature| 'CDAR) - (LIST '|mmTarget| 'CADAR) (LIST '|mode| 'CADR) - (LIST '|op| 'CAR) (LIST '|opcode| 'CADR) - (LIST '|opSig| 'CADR) (LIST 'CDR 'CDR) - (LIST '|sig| 'CDDR) (LIST '|source| 'CDR) - (LIST '|streamCode| 'CADDDR) - (LIST '|streamDef| 'CADDR) - (LIST '|streamName| 'CADR) (LIST '|target| 'CAR))) - (|i| NIL)) - (LOOP - (COND - ((OR (ATOM |bfVar#12|) - (PROGN (SETQ |i| (CAR |bfVar#12|)) NIL)) - (RETURN NIL)) - ('T (SETF (GET (CAR |i|) 'SHOESELFUNCTION) (CADR |i|)))) - (SETQ |bfVar#12| (CDR |bfVar#12|))))))) - -@ -\eject - -\section*{Acknowledgment} -Gabriel Dos Reis contributed initial documentation of this pamphlet. - -\end{document} diff --git a/src/boot/translator.boot b/src/boot/translator.boot new file mode 100644 index 00000000..0fc79fa0 --- /dev/null +++ b/src/boot/translator.boot @@ -0,0 +1,751 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- All rights reserved. +-- Copyright (C) 2007-2008, Gabriel Dos Reis. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + + +module '"boot-translator" +import '"includer" +import '"scanner" +import '"pile" +import '"parser" +import '"ast" + +)package "BOOTTRAN" + ++++ True if we are translating code written in Old Boot. +$translatingOldBoot := false + +AxiomCore::%sysInit() == + if cdr ASSOC(Option '"boot", %systemOptions()) = '"old" + then $translatingOldBoot := true + +-- Make x, the current package +setCurrentPackage x == + SETQ(_*PACKAGE_*,x) + +-- Compiles the input Lisp file designated by lspFileName. +shoeCOMPILE_-FILE lspFileName == + COMPILE_-FILE lspFileName + +-- (boottocl "filename") translates the file "filename.boot" to +-- the common lisp file "filename.clisp" + +BOOTTOCL(fn, out) == + BOOTTOCLLINES(nil,fn, out) + +-- (bootclam "filename") translates the file "filename.boot" to +-- the common lisp file "filename.clisp" , producing, for each function +-- a hash table to store previously computed values indexed by argument +-- list. + +BOOTCLAM(fn, out) == + $bfClamming := true + BOOTCLAMLINES(nil,fn, out) + +BOOTCLAMLINES(lines, fn, out) == + BOOTTOCLLINES(lines, fn, out) + +BOOTTOCLLINES(lines, fn, outfn)== + -- The default floating point number is double-float. + SETQ(_*READ_-DEFAULT_-FLOAT_-FORMAT_*, 'DOUBLE_-FLOAT) + callingPackage := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + infn:=shoeAddbootIfNec fn + result := shoeOpenInputFile(a,infn, + shoeClLines(a,fn,lines,outfn)) + setCurrentPackage callingPackage + result + +shoeClLines(a,fn,lines,outfn)== + if null a + then shoeNotFound fn + else + $GenVarCounter:local := 0 + shoeOpenOutputFile(stream,outfn, + (for line in lines repeat shoeFileLine (line,stream); + shoeFileTrees(shoeTransformStream a,stream))) + outfn + +-- (boottoclc "filename") translates the file "filename.boot" to +-- the common lisp file "filename.clisp" with the original boot +-- code as comments + +BOOTTOCLC(fn, out)==BOOTTOCLCLINES(nil, fn, out) + +BOOTTOCLCLINES(lines, fn, outfn)== + callingPackage := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + infn:=shoeAddbootIfNec fn + result := shoeOpenInputFile(a,infn, + shoeClCLines(a,fn,lines,outfn)) + setCurrentPackage callingPackage + result + + +shoeClCLines(a,fn,lines,outfn)== + if null a + then shoeNotFound fn + else + $GenVarCounter:local := 0 + shoeOpenOutputFile(stream,outfn, + (for line in lines repeat shoeFileLine (line,stream); + shoeFileTrees(shoeTransformToFile(stream, + shoeInclude bAddLineNumber(bRgen a,bIgen 0)),stream))) + outfn + +-- (boottomc "filename") translates the file "filename.boot" +-- to machine code and loads it one item at a time + +BOOTTOMC fn== + callingPackage := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + $GenVarCounter:local := 0 + infn:=shoeAddbootIfNec fn + result := shoeOpenInputFile(a,infn,shoeMc(a,fn)) + setCurrentPackage callingPackage + result + +shoeMc(a,fn)== + if null a + then shoeNotFound fn + else + shoePCompileTrees shoeTransformStream a + shoeConsole CONCAT(fn,'" COMPILED AND LOADED") + +EVAL_-BOOT_-FILE fn == + b := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + infn:=shoeAddbootIfNec fn + outfn:=CONCAT(shoeRemovebootIfNec fn,'".",_*LISP_-SOURCE_-FILETYPE_*) + shoeOpenInputFile(a,infn,shoeClLines(a,infn,[],outfn)) + setCurrentPackage b + LOAD outfn + +-- (boot "filename") translates the file "filename.boot" +-- and prints the result at the console + +BO fn== + b := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + $GenVarCounter:local := 0 + infn:=shoeAddbootIfNec fn + shoeOpenInputFile(a,infn,shoeToConsole(a,fn)) + setCurrentPackage b + +BOCLAM fn== + callingPackage := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + $GenVarCounter:local := 0 + $bfClamming:local := true + infn:=shoeAddbootIfNec fn + result := shoeOpenInputFile(a,infn,shoeToConsole(a,fn)) + setCurrentPackage callingPackage + result + +shoeToConsole(a,fn)== + if null a + then shoeNotFound fn + else + shoeConsoleTrees shoeTransformToConsole + shoeInclude bAddLineNumber(bRgen a,bIgen 0) + +-- (stout "string") translates the string "string" +-- and prints the result at the console + +STOUT string== PSTOUT [string] +-- $GenVarCounter:local := 0 +-- $bfClamming:local:=false +-- shoeConsoleTrees shoeTransformString [string] + +STEVAL string== + callingPackage := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + $GenVarCounter:local := 0 + a:= shoeTransformString [string] + result := + bStreamPackageNull a => nil + fn:=stripm(CAR a,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") + EVAL fn + setCurrentPackage callingPackage + result + +-- (sttomc "string") translates the string "string" +-- to common lisp, and compiles it. + +STTOMC string== + callingPackage := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + $GenVarCounter:local := 0 + a:= shoeTransformString [string] + result := + bStreamPackageNull a => nil + shoePCompile car a + setCurrentPackage callingPackage + result + + +shoeCompileTrees s== + while not bStreamNull s repeat + shoeCompile car s + s:=cdr s + +shoeCompile fn== + fn is ['DEFUN,name,bv,:body]=> + COMPILE (name,['LAMBDA,bv,:body]) + EVAL fn + +shoeTransform str== + bNext(function shoeTreeConstruct, + bNext(function shoePileInsert, + bNext(function shoeLineToks, str))) + +shoeTransformString s== + shoeTransform shoeInclude bAddLineNumber(s,bIgen 0) +shoeTransformStream s==shoeTransformString bRgen s +-- shoeTransform shoeInclude bAddLineNumber(bRgen s,bIgen 0) + +shoeTransformToConsole str== + bNext(function shoeConsoleItem, + bNext(function shoePileInsert, + bNext(function shoeLineToks, str))) + +shoeTransformToFile(fn,str)== + bFileNext(fn, + bNext(function shoePileInsert, + bNext(function shoeLineToks, str))) + +shoeConsoleItem (str)== + dq:=CAR str + shoeConsoleLines shoeDQlines dq + cons(shoeParseTrees dq,CDR str) + +bFileNext(fn,s)==bDelay(function bFileNext1,[fn,s]) + +bFileNext1(fn,s)== + bStreamNull s=> ["nullstream"] + dq:=CAR s + shoeFileLines(shoeDQlines dq,fn) + bAppend(shoeParseTrees dq,bFileNext(fn,cdr s)) + +shoeParseTrees dq== + toklist := dqToList dq + null toklist => [] + shoeOutParse toklist + +shoeTreeConstruct (str)== + cons(shoeParseTrees CAR str,CDR str) + +shoeDQlines dq== + a:= CDAAR shoeLastTokPosn dq + b:= CDAAR shoeFirstTokPosn dq + streamTake (a-b+1,CAR shoeFirstTokPosn dq) + +streamTake(n,s)== + if bStreamNull s + then nil + else if EQL(n,0) + then nil + else cons(car s,streamTake(n-1,cdr s)) + +shoeFileLines (lines,fn) == + shoeFileLine( '" ",fn) + for line in lines repeat shoeFileLine (shoeAddComment line,fn) + shoeFileLine ('" ",fn) + +shoeConsoleLines lines == + shoeConsole '" " + for line in lines repeat shoeConsole shoeAddComment line + shoeConsole '" " + +shoeFileLine(x, stream) == + WRITE_-LINE(x, stream) + x + +shoeFileTrees(s,st)== + while not bStreamNull s repeat + a:=CAR s + if EQCAR (a,"+LINE") + then shoeFileLine(CADR a,st) + else + REALLYPRETTYPRINT(a,st) + TERPRI st + s:=CDR s + + +shoePPtoFile(x, stream) == + SHOENOTPRETTYPRINT(x, stream) + x + +shoeConsoleTrees s == + while not bStreamPackageNull s repeat +-- while not bStreamNull s repeat + fn:=stripm(CAR s,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") + REALLYPRETTYPRINT fn + s:=CDR s + +shoeAddComment l== CONCAT('"; ",CAR l) + +++ Generate an import declaration for `op' as equivalent of the +++ foreign signature `sig'. Here, `foreign' operationally means that +++ the entity is from the C language world. +genImportDeclaration(op, sig) == + sig isnt ["Signature", op', m] => coreError '"invalid signature" + m isnt ["Mapping", t, s] => coreError '"invalid function type" + %hasFeature KEYWORD::GCL => + if SYMBOLP s then s := [s] + ["DEFENTRY", op, s, [t, SYMBOL_-NAME op']] + fatalError '"import declaration not implemented for this Lisp" + +shoeOutParse stream == + $inputStream :local:= stream + $stack:local :=nil + $stok:local := nil + $ttok:local := nil + $op:local :=nil + $wheredefs:local:=nil + $typings:local:=nil + $returns:local :=nil + $bpCount:local:=0 + $bpParenCount:local:=0 + bpFirstTok() + found:=CATCH("TRAPPOINT",bpOutItem()) + if found="TRAPPED" + then nil + else if not bStreamNull $inputStream + then + bpGeneralErrorHere() + nil + else if null $stack + then + bpGeneralErrorHere() + nil + else CAR $stack + +bpOutItem()== + bpComma() or bpTrap() + b:=bpPop1() + EQCAR(b,"TUPLE")=> bpPush cdr b + EQCAR(b,"+LINE")=> bpPush [ b ] + b is ["L%T",l,r] and IDENTP l => + bpPush [["DEFPARAMETER",l,r]] + case b of + Module(m) => + bpPush [shoeCompileTimeEvaluation ["PROVIDE", m]] + + Import(m) => + bpPush [["IMPORT-MODULE", m]] + + ImportSignature(x, sig) => + bpPush [genImportDeclaration(x, sig)] + + TypeAlias(t, args, rhs) => + bpPush [["DEFTYPE", t, args, ["QUOTE", rhs]]] + + ConstantDefinition(n, e) => + bpPush [["DEFCONSTANT", n, e]] + + otherwise => + b:=shoeCompTran ["LAMBDA",["x"],b] + bpPush [shoeEVALANDFILEACTQ CADDR b] + +--shoeStartsAt (sz,name,stream)== +-- bStreamNull stream => ['nullstream] +-- a:=CAAR stream +-- if #a<sz +-- then shoeStartsAt(sz,name,CDR stream) +-- else if SUBSTRING(a,0,sz)=name and (#a>sz and not shoeIdChar(a.sz)) +-- then stream +-- else shoeStartsAt(sz,name,CDR stream) + +--FC(name,fn)== +-- $bfClamming:local:=false +-- $GenVarCounter:local := 0 +-- infn:=shoeAddbootIfNec fn +-- shoeOpenInputFile(a,infn,shoeFindName(fn,name, a)) + +--shoeFindName(fn,name,a)== +-- shoeFindAndDoSomething(FUNCTION shoeCompile,fn,name,a) +--shoeTransform1 str== +-- bNext(function shoeTreeConstruct, +-- streamTake(1, bNext(function shoePileInsert, +-- bNext(function shoeLineToks, str)))) + +--BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE(fun,fn,symbol)== +-- $bfClamming:local:=false +-- infn:=shoeAddbootIfNec NAMESTRING fn +-- name:=PNAME symbol +-- shoeOpenInputFile(a,infn,shoeFindAndDoSomething(fun,fn,name, a)) + +--shoeFindAndDoSomething(fun,fn,name,a)== +-- if null a +-- then shoeNotFound fn +-- else +-- b:=shoeStartsAt(#name,name, shoeInclude +-- bAddLineNumber(bRgen a,bIgen 0)) +-- if bStreamNull b +-- then shoeConsole CONCAT (name,'" not found in ",fn) +-- else +-- $GenVarCounter:local := 0 +-- shoeLoop(fun,shoeTransform1 b) + +--BOOT_-COMPILE_-DEFINITION_-FROM_-FILE(fn,symbol)== +-- BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE +-- (FUNCTION shoeCompile,fn,symbol) + +--BOOT_-EVAL_-DEFINITION_-FROM_-FILE(fn,symbol)== +-- BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE +-- (FUNCTION EVAL,fn,symbol) + +--BOOT_-PRINT_-DEFINITION_-FROM_-FILE(fn,symbol)== +-- BOOT_-DO_-SOMETHING_-TO_-DEFINITION_-FROM_-FILE +-- (FUNCTION REALLYPRETTYPRINT,fn,symbol) + +--shoeLoop(fun, s)== +-- while not bStreamNull s repeat +-- FUNCALL(fun, car s) +-- s:=cdr s + +shoeAddbootIfNec s==shoeAddStringIfNec('".boot",s) + +shoeRemovebootIfNec s==shoeRemoveStringIfNec('".boot",s) +shoeAddStringIfNec(str,s)== + a:=STRPOS(str,s,0,nil) + if null a + then CONCAT(s,str) + else s + +shoeRemoveStringIfNec(str,s)== + a:=STRPOS(str,s,0,nil) + if null a + then s + else SUBSTRING(s,0,a) + +-- DEFUSE prints the definitions not used and the words used and +-- not defined in the input file and common lisp. + +DEFUSE fn== + infn:=CONCAT(fn,'".boot") + shoeOpenInputFile(a,infn,shoeDfu(a,fn)) + +shoeDfu(a,fn)== + if null a + then shoeNotFound fn + else + $lispWordTable:local :=MAKE_-HASHTABLE ("EQ") + DO_-SYMBOLS(i(FIND_-PACKAGE "LISP"),HPUT($lispWordTable,i,true)) + $bootDefined:local :=MAKE_-HASHTABLE "EQ" + $bootUsed:local :=MAKE_-HASHTABLE "EQ" + $bootDefinedTwice:local:=nil + $GenVarCounter:local :=0 + $bfClamming:local:=false + shoeDefUse shoeTransformStream a + out:=CONCAT(fn,'".defuse") + shoeOpenOutputFile(stream,out,shoeReport stream) + out + +shoeReport stream== + shoeFileLine('"DEFINED and not USED",stream) + a:=[i for i in HKEYS $bootDefined | not GETHASH(i,$bootUsed)] + bootOut(SSORT a,stream) + shoeFileLine('" ",stream) + shoeFileLine('"DEFINED TWICE",stream) + bootOut(SSORT $bootDefinedTwice,stream) + shoeFileLine('" ",stream) + shoeFileLine('"USED and not DEFINED",stream) + a:=[i for i in HKEYS $bootUsed | + not GETHASH(i,$bootDefined)] + for i in SSORT a repeat + b:=CONCAT(PNAME i,'" is used in ") + bootOutLines( SSORT GETHASH(i,$bootUsed),stream,b) + +shoeDefUse(s)== + while not bStreamPackageNull s repeat + defuse([],CAR s) + s:=CDR s + +defuse(e,x)== + x:=stripm(x,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") + $used:local:=nil + [nee,niens]:= + x is ['DEFUN,name,bv,:body] => [name,['LAMBDA,bv,:body]] + x is ['DEFMACRO,name,bv,:body] => [name,['LAMBDA,bv,:body]] + x is ["EVAL_-WHEN",.,["SETQ",id,exp]]=>[id,exp] + x is ["SETQ",id,exp]=>[id,exp] + ["TOP-LEVEL", x] + if GETHASH(nee,$bootDefined) + then + $bootDefinedTwice:= + nee="TOP-LEVEL"=> $bootDefinedTwice + cons(nee,$bootDefinedTwice) + else HPUT($bootDefined,nee,true) + defuse1 (e,niens) + for i in $used repeat + HPUT($bootUsed,i,cons(nee,GETHASH(i,$bootUsed))) + +defuse1(e,y)== + ATOM y => + IDENTP y => + $used:= + MEMQ(y,e)=>$used + MEMQ(y,$used)=>$used + defusebuiltin y =>$used + UNION([y],$used) + [] + y is ["LAMBDA",a,:b]=> defuse1 (append(unfluidlist a,e),b) + y is ["PROG",a,:b]=> + [dol,ndol]:=defSeparate a + for i in dol repeat + HPUT($bootDefined,i,true) + defuse1 (append(ndol,e),b) + y is ["QUOTE",:a] => [] + y is ["+LINE",:a] => [] + for i in y repeat defuse1(e,i) + +defSeparate x== + if null x + then [[],[]] + else + f:=car x + [x1,x2]:=defSeparate cdr x + if bfBeginsDollar f + then [cons(f,x1),x2] + else [x1,cons(f,x2)] +unfluidlist x== + NULL x => [] + ATOM x=> [x] + x is ["&REST",y]=> [y] + cons(car x,unfluidlist cdr x) + +defusebuiltin x== GETHASH(x,$lispWordTable) + +bootOut (l,outfn)== + for i in l repeat shoeFileLine (CONCAT ('" ",PNAME i),outfn) + +CLESSP(s1,s2)==not(SHOEGREATERP(s1,s2)) +SSORT l == SORT(l,function CLESSP) + +bootOutLines(l,outfn,s)== + if null l + then shoeFileLine(s,outfn) + else + a:=PNAME car l + if #s +#a > 70 + then + shoeFileLine(s,outfn) + bootOutLines(l,outfn,'" ") + else bootOutLines(cdr l,outfn,CONCAT(s,'" ",a)) + + +-- (xref "fn") produces a cross reference listing in "fn.xref" +-- It contains each name +-- used in "fn.boot", together with a list of functions that use it. + +XREF fn== + infn:=CONCAT(fn,'".boot") + shoeOpenInputFile(a,infn,shoeXref(a,fn)) + +shoeXref(a,fn)== + if null a + then shoeNotFound fn + else + $lispWordTable:local :=MAKE_-HASHTABLE ("EQ") + DO_-SYMBOLS(i(FIND_-PACKAGE "LISP"),HPUT($lispWordTable,i,true)) + $bootDefined:local :=MAKE_-HASHTABLE "EQ" + $bootUsed:local :=MAKE_-HASHTABLE "EQ" + $GenVarCounter:local :=0 + $bfClamming:local:=false + shoeDefUse shoeTransformStream a + out:=CONCAT(fn,'".xref") + shoeOpenOutputFile(stream,out,shoeXReport stream) + out + + +shoeXReport stream== + shoeFileLine('"USED and where DEFINED",stream) + c:=SSORT HKEYS $bootUsed + for i in c repeat + a:=CONCAT(PNAME i,'" is used in ") + bootOutLines( SSORT GETHASH(i,$bootUsed),stream,a) + +--FC (name,fn)== shoeGeneralFC(function BOOT,name,fn) + +FBO (name,fn)== shoeGeneralFC(function BO,name,fn) + +FEV(name,fn)== shoeGeneralFC(function EVAL_-BOOT_-FILE,name,fn) + +shoeGeneralFC(f,name,fn)== + $bfClamming:local:=false + $GenVarCounter:local := 0 + infn:=shoeAddbootIfNec fn + a:= shoeOpenInputFile(a,infn,shoeFindName2(fn,name, a)) + filename:= if # name > 8 then SUBSTRING(name,0,8) else name + a => FUNCALL(f, CONCAT('"/tmp/",filename)) + nil + +shoeFindName2(fn,name,a)== + lines:=shoeFindLines(fn,name,a) + lines => + filename:= if # name > 8 then SUBSTRING(name,0,8) else name + filename := CONCAT ('"/tmp/",filename,'".boot") + shoeOpenOutputFile(stream, filename, + for line in lines repeat shoeFileLine (line,stream)) + true + false + +shoeTransform2 str== + bNext(function shoeItem, + streamTake(1, bNext(function shoePileInsert, + bNext(function shoeLineToks, str)))) + +shoeItem (str)== + dq:=CAR str + cons([[CAR line for line in shoeDQlines dq]],CDR str) + +--shoeLines lines == [CAR line for line in lines] + +--shoeFindAndDoSomething2(fun,fn,name,a)== +-- if null a +-- then shoeNotFound fn +-- else +-- [lines,b]:=shoePackageStartsAt([],#name,name, shoeInclude +-- bAddLineNumber(bRgen a,bIgen 0)) +-- if bStreamNull b +-- then +-- shoeConsole CONCAT (name,'" not found in ",fn) +-- [] +-- else +-- if null lines +-- then shoeConsole '")package not found" +-- $GenVarCounter:local := 0 +-- shoeLoopPackage(fun,shoeTransform2 b,lines) + +--shoeLoopPackage(fun, s,lines)== +-- while not bStreamNull s repeat +-- FUNCALL(fun, append (reverse lines,car s)) +-- s:=cdr s +-- true +stripm (x,pk,bt)== + ATOM x => + IDENTP x => + SYMBOL_-PACKAGE x = bt => INTERN(PNAME x,pk) + x + x + CONS(stripm(CAR x,pk,bt),stripm(CDR x,pk,bt)) + +shoePCompile fn== + fn:=stripm(fn,_*PACKAGE_*,FIND_-PACKAGE '"BOOTTRAN") + fn is ['DEFUN,name,bv,:body]=> + COMPILE (name,['LAMBDA,bv,:body]) + EVAL fn + +FC(name,fn)== + $GenVarCounter:local := 0 + infn:=shoeAddbootIfNec fn + shoeOpenInputFile(a,infn,shoeFindName(fn,name, a)) + +shoeFindName(fn,name,a)== + lines:=shoeFindLines(fn,name,a) + shoePCompileTrees shoeTransformString lines + +shoePCompileTrees s== + while not bStreamPackageNull s repeat + REALLYPRETTYPRINT shoePCompile car s + s:=cdr s + +bStreamPackageNull s== + a := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + b:=bStreamNull s + setCurrentPackage a + b + +PSTTOMC string== + $GenVarCounter:local := 0 + shoePCompileTrees shoeTransformString string + +BOOTLOOP ()== + a:=READ_-LINE() + #a=0=> + WRITE_-LINE '"Boot Loop; to exit type ] " + BOOTLOOP() + b:=shoePrefix? ('")console",a) + b => + stream:= _*TERMINAL_-IO_* + PSTTOMC bRgen stream + BOOTLOOP() + a.0='"]".0 => nil + PSTTOMC [a] + BOOTLOOP() + +BOOTPO ()== + a:=READ_-LINE() + #a=0=> + WRITE_-LINE '"Boot Loop; to exit type ] " + BOOTPO() + b:=shoePrefix? ('")console",a) + b => + stream:= _*TERMINAL_-IO_* + PSTOUT bRgen stream + BOOTPO() + a.0='"]".0 => nil + PSTOUT [a] + BOOTPO() + +PSTOUT string== + callingPackage := _*PACKAGE_* + IN_-PACKAGE '"BOOTTRAN" + $GenVarCounter:local := 0 + result := shoeConsoleTrees shoeTransformString string + setCurrentPackage callingPackage + result + + +defaultBootToLispFile file == + CONCAT(shoeRemovebootIfNec file,'".clisp") + +translateBootFile(progname, options, file) == + outFile := getOutputPathname(options) + BOOTTOCL(file, ENOUGH_-NAMESTRING outFile) + +compileBootHandler(progname, options, file) == + intFile := BOOTTOCL(file, defaultBootToLispFile file) + intFile => + objFile := compileLispHandler(progname, options, intFile) + DELETE_-FILE intFile + objFile + nil + +associateRequestWithFileType(Option '"translate", '"boot", + function translateBootFile) +associateRequestWithFileType(Option '"compile", '"boot", + function compileBootHandler) |