Convert Boot Code to Other Languages

Boot code to SPAD

I would like to convert boot code to SPAD because:

  1. It would help to remove reliance on Lisp code and therefore allow more parallel code.
  2. It would help me to modify the compiler code as a first stage help to convert the library code to other languages.

I managed to compile this boot code to an Abstract Syntax Tree (AST) I then wrote a code generator to write AST back to boot code. This code was different from the original (because the AST does not store format information) but when I compiled to Lisp the code generated was identical - all lines (except those starting with ';') were identical.

So I am sure my AST contains all the information from the boot files.

Its then not difficult to generate SPAD or Aldor or any other language from this AST. But the problems are:

  1. How to handle global variables, especially dynamic variables. I think each function would have to have an additional parameter to pass around the runtime values of these dynamic variables.
  2. The boot 'where' keyword seems to hold inner functions and variables. How should inner functions be converted to SPAD? SPAD has lambdas but can SPAD lambda capture variables (closures)?
  3. The native Lisp code would have to be translated by hand, to handle input/output to console, files and database (which would be different for each language).

Since I now have confidence in the AST I can now go on to generate SPAD from the AST. I have started this in this file but this is work in progress and I still have a lot more to do on this.

Perhaps another option would be to just translate boot to SPAD manually but that's hard because Boot/Lisp passes everything around in global variables whereas well written SPAD should encapsulate information in domains. This means you cant just translate one function at a time and check if it works before going on to the next.

I think it would be hard to change one function at a time because all these functions are linked by lots of global variables.

I suspect it would only be possible to untangle all that mess if you have a very deep understanding of the interpreter and of boot. Since I would like to remove boot code I would rather not spend a lot of time learning about it.

One thing that I can easily do, since I have an AST, is generate tables showing which functions use which variables and another showing which variables are used in which functions. But I think it would take more knowledge than I have to untangle them. I might even be able to infer which variables only get assigned to one type (int,float,string..) so that they could be assigned those types in SPAD. However many boot variables could be polymorphic or complicated list structures.

> But how do you generate static
> type language from a dynamic type language?

I mapped functions in boot to functions in SPAD. For convenience I just put them in packages one for each boot file

Variables in boot can map to variables which are instances of SExpression. This instance of SExpression can have have common lisp functions like '+' defined. At runtime this function would add if its a number and fail if its not. So its checking the type dynamically at runtime - just like boot/lisp.

Manual Preformatting

In order to get the boot code to compile it is first necessary to make a few minor manual changes to the code. It is easy to know where these changes are required because the Eclipse IDE will indicate with red error markings. However it is tedious making these changes so I have put prefromatted interpreter boot code here.

Changes:

if-then-else

if-then-else must be on 1 line or if a then
b
else
c

Keywords

Other

FunctionDef [x] == changed to FunctionDef([x])==

unary int

-1 changed to (-1)

open ended segment

parenthesis must be added around start if not int or ID

[i for i in (index+1)..]

Examples

Boot SPAD Notes
a := b a : MExpression := b where: MExpression is an implemetation of SExpression with some operations defined on it.
a := b + c a : MExpression := b + c for example '+' would be defined if this instance of MExpression is a number.
[x,y] := b x : MExpression:= b.1
y : MExpression:= b.2
assumes 'b' is a list with 2 elements

List handling:

For an introduction to list handling in boot see page here.

If we knew the types then we could translate like this:

Boot SPAD Notes
x := [a, b]
x :=  [a, b] 
This assumes a and b are the same type '%' so x will have type List %
x := [a, :b]
x := concat(a,b) 
concat: (S, %) -> %
if a is Integer and b is List Integer then x will be List Integer.
x := [a, :b, c]
   

but in general all types are SExpression so we need a way to handle colon ':':

Boot SPAD Notes
x := [a, b]
 
 
x := [a, :b]
 
 
x := [a, :b, c]
   

Is Keyword

For an introduction to 'is' keyword in boot see page here.

Some structures like 'is' seem especially difficult to convert to SPAD because the syntax and the semantics seem intertwined, or perhaps I should say the compile-time and run-time code are interdependent. So, in the example below, we are binding and assigning the variables 'a' and 'b' but this depends on run-time (match function).

Boot SPAD
x is [a, :b] => b
( checkMatch:Boolean := match(x,[a@Symbol, colon@Symbol,b@Symbol])
  if checkMatch then
    a := x.1
    b := CDR x
  checkMatch 
) => b 
   

 

Boot SPAD
   
   
   

 

Boot SPAD
   
   
   

 

Boot SPAD
   
   
   

Compiling

/* rules for indentation
* ---------------------
* newline(indent) inserted after every declaration
* newline(indent) inserted after every statement in block
*
* should these be before?
*/

 


metadata block
see also:
Correspondence about this page

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.