Notes on Code Translation Using the CodeGeneration Package
This help page describes special features and limitations common to all the functions in the CodeGeneration package. The following description contains references to various options available with the CodeGeneration functions. For more information, see the CodeGenerationOptions help page.
Translation of Names
Translation of Language Constructs
Translation of Types
Automatic Type Deduction
Translation of Return Statements and Implicit Returns
Translation of Functions
Translation of Arrays
Optimization and Other Transformations of Maple Code
In general, names used in the input code are preserved in the output. The supplied translators perform some checks to ensure that input names meet the standards for identifiers in the target language, but these checks are necessarily not thorough, so the use of names which correspond to target language keywords may produce unexpected results.
The names of the result and the return variable (in situations where a newly generated return variable is needed) can be specified using the resultname and returnvariablename options.
CodeGeneration recognizes the following special names: Pi, gamma, Catalan, true, false.
Support for modules is limited. Some target languages do not have a construct that is similar to the Maple module; in these cases, a module is translated to the closest equivalent. Type analysis and deduction for modules is less reliable than for procedures. In particular, type assertions in module local and export declarations are not always applied in the analysis of the instantiated locals and exports.
Translation of repetition statements is not fully supported. CodeGeneration cannot translate for-in loops. It can translate for loops and while loops but not loops with conditions involving both for and while simultaneously.
Support for the try statement and the operator form of the if statement is not available for all target languages.
There is limited support for the translation of multiple assignments. The left-hand side and right-hand side must be expression sequences containing the same number of elements. For target languages that do not support simultaneous assignments, a sequence of assignment statements is generated, using the order in which the elements appear in the expression sequences.
The CodeGeneration package recognizes the following Maple types: numeric, float, sfloat, and integer. The first three types are considered equivalent by CodeGeneration and are translated into a floating-point type. CodeGeneration also recognizes Maple Array and rtable types, where the element type is one of the basic types listed above. Any of the types described here can be used in variable declarations, including ones provided through the declare option.
The CodeGeneration package accepts type declarations containing the types positive, negative, nonpositive, nonnegative, and extended_numeric. However, these are considered equivalent to numeric and are translated into the same floating-point type in the target language. Types posint, negint, nonnegint, and nonposint are also accepted and are considered equivalent to integer.
The CodeGeneration package recognizes Maple objects having other types in limited contexts. Rational numbers are converted into a ratio of floating-point numbers. Strings are recognized within error statements and certain function calls. Boolean types occurring within selection and repetition statements are also recognized. However, these types are not generally recognized by CodeGeneration.
If a type name appearing in a variable declaration is not recognized, one of the known types is automatically assigned, and a warning message is issued. The new type is deduced from the context if possible; otherwise, the default type is given.
The CodeGeneration functions check that operations involving different types can be translated into the target language. If the types are not compatible, then an explicit coercion of one type to another is generated when possible. If the types cannot be resolved, an attempt is still made to translate the input and a warning message is issued.
Explicit conversions between single-precision and double-precision floats are not performed. This may be a concern when translating to languages that do not support automatic conversion of one floating-point type to another.
CodeGeneration attempts to deduce the type of any untyped variable by examining the context in which it appears. For example, if an integer is assigned to an untyped variable, then the variable is assumed to have the same type. If the type of a variable cannot be deduced, then it is assigned the default type.
Type deduction is not performed on global variables. The reason is that the scope of such a variable is beyond that of the code fragment being translated, so the code fragment contains insufficient information to deduce the variable's type.
The capabilities of the type deduction system are limited. Consequently, you may see unexpected results. For example, untyped variables are assigned types as the Maple statements are analyzed, and no backtracking is performed to correct earlier assumptions. In the following example, the first assignment gives x an integer type, though the second assignment implies that x should have a floating-point type.
x = 1;
x = (int) 0.20e1;
There are several options that allow you to control the behavior of the type deduction system or to disable it (in which case all untyped variables get the default type). These options include coercetypes, declare, deducetypes and defaulttype.
The return type of a procedure is deduced if it is not declared by the user. If more than one return statement is present, then the types of all objects returned must be compatible. If a single return statement contains a sequence of two or more objects, then the sequence is translated into an array.
Implicit returns in Maple procedures are recognized in some situations. When necessary, the value returned is assigned to an automatically generated return variable. Conversion of implicit returns to explicit returns can be turned off by specifying the option deducereturn=false.
In some languages, arrays cannot be returned directly. In these cases, an array is copied to an automatically generated return variable. This variable is then considered an output parameter of the function and it is added to the parameter list. The expandarrays option can be used to control how the array copy is translated. Note that CodeGeneration does not have full support for translation of return statements involving arrays; you may have to modify the generated code in some cases.
The name of the automatically generated return variable can be specified using the returnvariablename option.
Unless noted otherwise in the detailed help page for a specific translator, all CodeGeneration translators recognize the following functions: sin, cos, tan, csc, sec, cot, arcsin, arccos, arctan, arccsc, arcsec, arccot, sinh, cosh, tanh, csch, sech, coth, arcsinh, arccosh, arctanh, arccsch, arcsech, arccoth, abs, exp, ln, log, log10, sqrt, round, trunc, signum, sign, max, min, irem, mod, modp, mods, evalf, evalhf, print, printf. Function names that are not recognized are translated unchanged.
There is partial support for translation of the following functions, as only limited argument types are recognized: eval, iquo.
Each function is translated to the closest available equivalent, either in the target language itself or in standard external libraries. When a direct equivalent is not available, CodeGeneration either constructs an equivalent through a concise combination of functions available in the target language or issues an error. For example, the inverse hyperbolic trigonometric functions, such as arcsinh are translated to expressions in terms of logarithms and square root functions.
The eval function is recognized, but its argument is translated as is, with no evaluation taking place. A call to evalf and evalhf is translated simply as a conversion to float operation in the target language; no special significance is given to the setting of Digits and no distinction is made between hardware and software floats in the target language.
In this section, the term array is used in the general sense, to refer to a data structure indexed by one or more integers. The term Maple Array is used when referring to the Maple Array data structure. The term rtable refers to a Maple rtable data structure and includes Array plus the Matrix and Vector structures.
The CodeGeneration functions can translate Maple Arrays and rtables into target-language arrays. However, the type analysis and deduction capabilities with respect to arrays are very limited. For example, CodeGeneration cannot deduce the overall type of an array based on information about individual elements. Type coercions and assignments involving arrays are not fully supported. CodeGeneration does not recognize sets.
The CodeGeneration functions can analyze some rtable type declarations and constructors within procedures. Data types, dimensions and ranges are recognized, but most options are ignored. The only initializer accepted is a list. Dimensions and ranges must have integer values; there is currently no support for constructors specified with non-integer dimensions (for example, Vector(n), where n is a procedure parameter). Indices are renumbered for compatibility with the target language when required.
For best performance, it is recommended that you declare the types and ranges for all arrays, either by providing the types in parameter, local and global declarations within a procedure or by using the declare option.
When the input is a Maple Array or rtable, an element-wise assignment of the input values to a target-language array is generated. However, only the initialized elements of the input object are included in the assignments. It is assumed that you will add code to the target-language output for initializing the array if necessary.
In certain situations, lists are translated to arrays. Lists with an arbitrary level of nesting can be translated to multidimensional arrays in the target language, but only if all sublists match in length. If lists are used as initializers, the dimensions must match declared dimensions. If a list occurs in an unrecognized context, it is translated unchanged.
Copying of one array to another is translated into element-wise assignments, when the target language has no built-in support for array copying. The expandarrays=false option can be used to suppress this behavior. In this case, a simple assignment of one array name to another is generated, and you must modify the target code as required.
The optimize option is used to specify optimization of the code.
If the optimization is requested, then the CodeGeneration functions accomplish this by calling either codegen[optimize] or a stronger, internal optimizer. For more details, see the optimize option on the CodeGenerationOptions help page. The user can get greater control over the optimization process by calling codegen[optimize] on its own instead of using the optimize option.
The optimize option is designed to be used with procedures and computation sequences; it has no effect when the input is a module.
The codegen package provides many other functions that transform Maple code. These functions were originally intended to work with the codegen[C](deprecated) and codegen[fortran](deprecated) functions but they are equally suitable for preprocessing Maple code before translating with the CodeGeneration functions.
Translation using the CodeGeneration functions can often require a large amount of execution time and memory. Usually, the Maple code provided for translation is analyzed as a whole and goes through several transformations to ensure the most accurate translation possible. However, it is possible to significantly reduce the resources required for translating computation sequences by using the reduceanalysis option. In this case, the computation sequence is analyzed one assignment at a time, rather than as a complete sequence. Note that this option does not apply to procedures and modules.
Internally, the CodeGeneration functions work on an inert representation (see ToInert and FromInert) of the Maple input. The CodeGeneration package attempts to recover the original Maple expression that triggered the message to return a detailed error or warning message. When this is not possible, a general description of the problem encountered is generated, along with the inert representation if appropriate.
When an error occurs, more information about the source of the error can be obtained through userinfo statements, by changing the value of infolevel[CodeGeneration].
Download Help Document