E.8 MONEY: A Macro Illustrating Sections

We mentioned earlier in this appendix that macros can be used to create data structures and to populate them with values statically. Production applications contain significant static data used for captions, help systems, and error messages. Often such data are most conveniently accessed if they are organized as elements in arrays or other complex data structures. In addition, such data may need to be reformulated for various natural languages to support program versions to be used internationally.

High-level languages have come to provide some capability to populate such structures statically i.e., at compile time rather than at runtime. We now present an approach for packaging such data as "parallel arrays" in interrelated object file sections using the assembler.

Consider a hypothetical company that wishes to develop its check-writing software with an eye toward support of multiple currencies and natural languages. It is relatively easy to change from the n,nnn.nn convention for writing values with numerals in English-speaking countries to the n.nnn,nn convention in German-speaking countries; indeed, current versions of spreadsheet programs like Microsoft Excel do this with an easily changed setting. By convention, however, a check also contains the amount "spelled out" in words, but the currency will differ (and sometimes also the way one counts in a natural language):

 One thousand four hundred twenty two and 37/100 US dollars One thousand four hundred twenty two and 37/100 UK pounds 

Let us outline a universal algorithm (requiring a country-specific static data structure) to construct such phrases.

Essentially, solving this problem proceeds in the reverse of the way we first learned to count. We will start with some suitable largest value (here, 1000 for simplicity). Imagine that the following data structure somehow already exists:

 valu[ ]    text[ ]   phrase   1000       o >    one thousand    900       o >    nine hundred    ...     20       o >    twenty     19       o >    nineteen    ...      2       o >    two      1       o >    one 

where the text[ ] column contains address pointers. It is not difficult to propose having corresponding populated data structures for French, German, etc., although the number of rows might differ for each because most every language "counts" idiosyncratically.

Suppose we are given an amount (i.e., a number), a unit of currency, and the word and in the natural language. The following algorithm written in a BASIC-like pseudocode will suffice:

 rest = amount FOR i = 0 STEP +1 UNTIL rest < 1     IF    valu[i] <= rest     THEN  PRINT AS STRING FROM text[i]           rest = rest   valu[i]     END IF NEXT i PRINT AS STRING and PRINT AS FRACTION rest PRINT AS STRING SINGULAR_PLURAL( unit, INT(amount) ) 

We ignore small details such as capitalization, commas, and spaces. The algorithm simply passes down through the tabular data structure using successive subtraction. The use of FROM implies that array text[ ] contains addresses, not the strings themselves.

How can the required data structure with parallel arrays valu[ ] and text[ ] be constructed in a language-independent way? The values will be, say, quad words. The address pointers can also be quad words. The stringz directive might be appropriate for the phrases, since we may suppose that the terminating NUL code can be used by PRINT AS STRING to detect the end of any phrase being processed.

We introduce a macro that references three object file sections and uses the special assembler symbol @, which takes on a different unique value for every macro call:

 .macro  money      AMT, PHRASE         .section   WORDS         T\@ = .                 // Current location counter         stringz    "\PHRASE"    // Null byte at end         .section   VALUES         data8      \AMT         // Numerical amount         .section   WHERE         data8      T\@          // Unique address pointer .endm 

If this macro is invoked over and over, a different unique symbol beginning with T will be generated each time and given a value of the particular location counter offset from the beginning of program section WORDS where the first character of each corresponding counting-scheme phrase has been placed. The linker will add a base address to all such offsets when it establishes a final virtual address for every program section.

We thus produce three parallel arrays: quad word values, address pointers, and variable-length strings. The arrays for a particular natural language and national currency could be set up with an assembly language module of the following form:

         .title    USDOLLARS         .include  "money.s" // The money macro definition // Define sections         .data         .align 8         .section  VALUES, "a", "progbits" valu:         .section  WHERE, "a", "progbits" text:         .section  WORDS, "a", "progbits" // Define all the phrases // (insert new ones at top if monetary inflation occurs)         money     1000, "one thousand "         money     900, "nine hundred " // etc.         money     100, "one hundred "         money     90, "ninety " // etc.         money     20, "twenty "         money     19, "nineteen " // etc.         money     2, "two "         money     1, "one "         .end 

The order of occurrence of the various invocations of the money macro, specifying ever-smaller amounts, produces the ordered data structure. The resulting object module would be linked with the main program, the latter being written in any convenient programming language.



ItaniumR Architecture for Programmers. Understanding 64-Bit Processors and EPIC Principles
ItaniumR Architecture for Programmers. Understanding 64-Bit Processors and EPIC Principles
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net