Introduction to Gentran
=======================

Original Authors Barbara Gates and Paul Wang

Gentran is a powerful generator of foreign language code. Currently it can generate FORTRAN, 'C', and RATFOR code from Maxima language code. Gentran can translate mathematical expressions, iteration loops, conditional branching statements, data type information, function definitions, matrtices and arrays, and more.

Functions for Gentran
=====================

 -- Function: gentran (STMT1, STMT2, ... , STMTN , [F1, F2, ... , FM])
     Translates each stmt into formatted code in the target language. A substantial subset of expressions and statements in the Maxima programming language can be translated directly into numerical code. The gentran command translates Maxima statements or procedure definitions into code in the target language (gentranlang: fortran, c, or ratfor). Expressions may optionally be given to Maxima for evaluation prior to translation.

     stmt1, stmt2, ... , stmtn is a sequence of one or more statements, each of which is any Maxima user level expression, (simple, group, or block) statement, or procedure definition that can be translated into the target language.

     [f1, f2, ... , fm] is an optional list of output files to which translated output will be written. They can be any of the following:

     string = the name of an output file in quotes

     true (no quotes) = the terminal

     false = the current output file(s)

     all = all files currently open for output by gentran

     If the files are not open they will be opened; if they are open, output will be appended to them. Filenames are given as quoted strings. If the optional variable genoutpath (string, including the final /) default false is set, it will be prepended to the output file names. If the output file list is omitted, output will be written to the current output, generally the terminal. gentran returns (a list of) the name(s) of file(s) to which code was written.

 -- Function: gentranout (F1, F2, ... , FN)

     Gentran maintains a list of files currently open for output by gentran commands only. gentranout inserts each file name represented by f1, f2,... , fn into that list and opens each one for output. It also resets the current output file(s) to include all files in f1, f2, ... , fn. gentranout returns the list of files represented by f1, f2, ... , fn; i.e., the current output file(s) after the command has been executed.

 -- Function: gentranshut (F1, F2, ... , FN)

     gentranshut creates a list of file names from f1, f2, ... , fn, deletes each from the output file list, and closes the corresponding files. If (all of) the current output file(s) are closed, then the current output file is reset to the terminal. gentranshut returns (a list of) the current output file(s) after the command has been executed. gentranshut(all) will close all gentran output files.

 -- Function: gentranpush (F1, F2, ... , FN)

     gentranpush pushes the file list onto the output stack. Each file in the list that is not already open for output is opened at this time. The current output file is reset to this new element on the top of the stack.

 -- Function: gentranpop (F1, F2, ... , FN)

     gentranpop deletes the top-most occurrence of the single element containing the file name(s) represented by f1, f2, ... , fn from the output stack. Files whose names have been completely removed from the output stack are closed. The current output file is reset to the (new) element on the top of the output stack. gentranpop returns the current output file(s) after this command has been executed.

 -- Function: gentranin (F1, F2, ... , FN, [F1,F2, ... , FM])

     gentranin processes mixed-language template files consisting of active parts (delimited by <<...>>) containing Maxima statements, including calls to gentran, and passive parts, assumed to contain statements in the target language (including comments), which are transcribed verbatim. Input files are processed sequentially and the results appended to the output. The presence of >> in passive parts of the file (except for in comments) is interpreted as an end-of-file and terminates processing of that file. The optional list of output files [f1,f2, ... , fm] each receive a copy of the entire output. All filespecs are quoted strings. Input files may be given as (quoted string) filenames, which will be located by Maxima file_search. The optional variable geninpath (default false ) must be a list of quoted strings describing the paths to be searched for the input files. If it is set, that list replaces the standard Maxima search paths.

     Active parts may contain any number of Maxima expressions and statements. They are not copied directly to the output. Instead, they are given to Maxima for evaluation. All output generated by each evaluation is sent to the output file(s). Returned values are only printed on the terminal. Active parts will most likely contain calls to gentran to generate code. This means that the result of processing a template file will be the original template file with all active parts replaced by generated code. If [f1, f2, ... , fm] is not supplied, then generated code is simply written to the current output file(s). However, if it is given, then the current output file is temporarily overridden. Generated code is written to each file represented by f1, f2, ... , fn for this command only. Files which were open prior to the call to gentranin will remain open after the call, and files which did not exist prior to the call will be created, opened, written to, and closed. The output file stack will be exactly the same both before and after the call. gentranin returns (to the terminal) the name(s) of (all) file(s) written to by this command.

 -- Function: gentraninshut ()

     A cleanup function to close input files in case where gentranin hung due to error in template.

 -- Function: tempvar (TYPE)

     Generates temporary variable names by concatenating tempvarname (default 't) with sequence numbers. If type is non-false, e.g. "real*8" the corresponding type is assigned to the variable in the gentran symbol table, which may be used to generate declarations depending on the setting of the gendecs flag. It is the users responsibility to make sure temporary variable names do not conflict with the main program.

 -- Function: markvar (VNAME)

     markvar "marks" variable name vname to indicate that it currently holds a significant value.

 -- Function: unmarkvar (VNAME)

     unmarkvar "unmarks" variable name vname to indicate that it no longer holds a significant value.

 -- Function: markedvarp (VNAME)

     markedvarp tests whether the variable name vname is currently marked.

 -- Function: gendecs (NAME)

     The gendecs command can be called any time the gendecs flag is switched off to retrieve all type declarations from Gentran's symbol table for the given subprogram name (or the "current" subprogram if false is given as its argument).

 -- Function: gentran_on (SW)

     Turns on the mode switch sw.

 -- Function: gentran_off (SW)

     Turns the given switch, sw, off.

Gentran Mode Switches
=====================

 -- Option variable: fortran
 -- Option variable: ratfor
 -- Option variable: c
     Default: off

     These mode switches change the default mode of Maxima from evaluation to translation. They can be turned on and off with the gentran commands gentran_on and gentran_off. Each time a new Maxima session is started up, the system is in evaluation mode. It prints a prompt on the user's terminal screen and waits for an expression or statement to be entered. It then proceeds to evaluate the expression, prints a new prompt, and waits for the user to enter another expression or statement. This mode can be changed to translation mode by turning on either the fortran, ratfor or c switches. After one of these switches is turned on and until it is turned off, every expression or statement entered by the user is translated into the corresponding language just as if it had been given as an argument to the gentran command. Each of the special functions that can be used from within a call to gentran can be used at the top level until the switch is turned off.

 -- Option variable: gendecs
     Default: on

     When the gendecs switch is turned on, gentran generates type declarations whenever possible. When gendecs is switched off, type declarations are not generated. Instead, type information is stored in gentran's symbol table but is not retrieved in the form of declarations unless and until either the gendecs command is called or the gendecs flag is switched back. Note: Generated declarations may often be placed in an inappropriate place (e.g. in the middle of executable fortran code). Therefore the gendecs flag is turned off during processing of templates by gentranin.

Gentran Option Variables
========================

 -- Option variable: gentranlang
     Default: fortran

     Selects the target numerical language. Currently, gentranlang must be fortran, ratfor, or c. Note that symbols entered in Maxima are case-sensitive. gentranlang should not be set to FORTRAN, RATFOR or C.

 -- Option variable: fortlinelen
     default: 72

     Maximum number of characters printed on each line of generated FORTRAN code.

 -- Option variable: minfortlinelen
     Default: 40

     Minimum number of characters printed on each line of generated FORTRAN code.

 -- Option variable: fortcurrind
     Default: 0

     Number of blank spaces printed at the beginning of each line of generated FORTRAN code (after column 6).

 -- Option variable: ratlinelen
     Default: 80

     Maximum number of characters printed on each line of generated Ratfor code.

 -- Option variable: clinelen
     Default: 80

     Maximum number of characters printed on each line of generated 'C' code.

 -- Option variable: minclinelen
     Default: 40

     Minimum number of characters printed on each line of generated 'C' code.

 -- Option variable: ccurind
     Default: 0

     Number of blank spaces printed at the beginning of each line of generated'C' code.

 -- Option variable: tablen
     Default: 4

     Number of blank spaces printed for each new level of indentation. (Automatic indentation can be turned off by setting this variable to 0.)

 -- Option variable: genfloat
     Default: false

     When set to true (or any non-false value), causes integers in generated numerical code to be converted to floating point numbers, except in the following places: array subscripts, exponents, and initial, final, and step values in do-loops. An exception (for compatibility with Macsyma 2.4) is that numbers in exponentials (with base %e only) are double-floated even when genfloat is false.

 -- Option variable: dblfloat
     Default: false If dblfloat is set to true, floating point numbers in gentran output in implementations (such as Windows Maxima under CLISP) in which float and double-float are the same will be printed as *.d0. In implementations in which float and double-float are different, floats will be coerced to double-float before being printed.

 -- Option variable: gentranseg
     Default: true

 -- Option variable: maxexpprintlen
     Default: 800

     When gentranseg is true (or any non-false value), causes Gentran to "segment" large expressions into subexpressions of manageable size. The segmentation facility generates a sequence of assignment statements, each of which assigns a subexpression to an automatically generated temporary variable name. This sequence is generated in such a way that temporary variables are re-used as soon as possible, thereby keeping the number of automatically generated variables to a minimum. The maximum allowable expression size can be controlled by setting the maxexpprintlen variable to the maximum number of characters allowed in an expression printed in the target numerical language (excluding spaces and other whitespace characters automatically printed by the formatter). When the segmentation routine generates temporary variables, it places type declarations in the symbol table for those variables if possible. It uses the following rules to determine their type:

     1. If the type of the variable to which the large expression is being assigned is already known (i.e., has been declared by the user via a TYPE form), then the temporary variables will be declared to be of that same type. 2. If the global variable tempvartype has a non-false value, then the temporary variables are declared to be of that type. 3. Otherwise, the variables are not declared unless implicit has been set to true.

 -- Option variable: gentranopt
     Default: false

     When set to true (or any non-false value), causes Gentran to replace each block of straightline code by an optimized sequence of assignments obtained from the Maxima optimize command. (The optimize command takes an expression and replaces common subexpressions by temporary variable names. It returns the resulting assignment statement, preceded by common-subexpression-to-temporary-variable assignments.

 -- Option variable: tempvarname
     Default: 't

     Name used as the prefix when generating temporary variable names.

 -- Option variable: optimvarname
     default: 'u

     is the preface used to generate temporary file names produced by the optimizer when gentranopt is true. When both gentranseg and gentranopt are true, the optimizer generates temporary file names using optimvarname while the segmentation routine uses tempvarname preventing conflict.

 -- Option variable: tempvarnum
     Default: 0

     Number appended onto tempvarname to create a temporary variable name. If the temporary variable name resulting from appending tempvarnum onto the end of tempvarname has already been generated and still holds a useful value or has a different type than requested, then the number is incremented until one is found that was not previously generated or does not still hold a significant value or a different type.

 -- Option variable: tempvartype
     Default: false

     Target language variable type (e.g., INTEGER, REAL*8, FLOAT, etc.) used as a default for automatically generated variables whose type cannot be determined otherwise. If tempvartype is false, then generated temporary variables whose type cannot be determined are not automatically declared.

 -- Option variable: implicit
     Default: false

     If implicit is set to true temporary variables are assigned their implicit type according to Fortran rules based on the initial letter of the name. If gendecs is on, this results in printed type declarations.

 -- Option variable: gentranparser
     Default: false

     If gentranparser is set to true Maxima forms input to gentran will be parsed and an error will be produced if an expression cannot be translated. Otherwise, untranslatable expressions may generate anomalous output, sometimes containing explicit calls to Maxima functions.

 -- Option variable: genstmtno
     Default: 25000

     Number used when a statement number must be generated. Note: it is the user's responsibility to make sure this number will not clash with statement numbers in template files.

 -- Option variable: genstmtincr
     Default: 1

     number by which genstmtno is incremented each time a new statement number is generated.

 -- Option variable: usefortcomplex
     Default: false

     If usefortcomplex is true, real numbers in expressions declared to be complex by type(complex,...) will be printed in Fortran complex number format (realpart,0.0). This is a purely syntactic device and does not carry out any complex calculations.

Gentran Evaluation Forms
========================

The following special functions can be included in Maxima statements which are to be translated by the gentran command to indicate that they are to be partially or fully evaluated by Maxima before being translated into numerical code. Note that these functions have the described effect only when supplied in arguments to the gentran command.

 -- Function: eval (EXP)

     Where exp is any Maxima expression or statement which, after evaluation by Maxima, results in an expression that can be translated by gentran into the target language. When eval is called from an argument that is to be translated, it tells gentran to give the expression to Maxima for evaluation first, and then to translate the result of that evaluation.

 -- Function: rsetq (VAR, EXP)

     Where var is any Maxima variable, matrix or array element, and exp is any Maxima expression which, after evaluation by Maxima results in an expression that can be translated by Gentran into the target language. This is equivalent to VAR : EVAL(EXP) ;

 -- Function: lsetq (var, exp)

     Where var is any Maxima user level matrix or array element with indices which, after evaluation by Maxima, will result in expressions that can be translated by Gentran, and exp is any Maxima user level expression that can be translated into the target language. This is equivalent to var[eval(s1), eval(s2), ...]: exp where S1, S2, ... are indices.

 -- Function: lrsetq (var, exp)

     Where var is any Maxima matrix or array element with indices which, after evaluation by Maxima, will result in expressions that can be translated by Gentran; and exp is any user level expression which, after evaluation, will result in an expression that can be translated by Gentran into the target language. This is equivalent to var[eval(s1), eval(s2), ...]: eval(exp);.

 -- Function: type (type,v1...vn)

     Places information in the gentran symbol table to assign type to variables v1...vn. This may result in type declarations printed by gentran depending on the setting of gendecs. type must be called from within gentran and does not evaluate its arguments unless eval() is used.

 -- Function: literal (arg1, arg2, ... , argn)

     where arg1, arg2, ... , argn is an argument list containing one or more arg's, each of which either is, or evaluates to, an atom. The atoms tab and cr have special meanings. arg's are not evaluated unless given as arguments to eval. This function call is replaced by the character sequence resulting from concatenation of the given atoms. Double quotes are stripped from all string type arg's, and each occurrence of the reserved atom tab or cr is replaced by a tab to the current level of indentation, or an end-of-line character.