home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / sql / sqlddl.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  41.6 KB  |  1,369 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --token.ada
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. with TEXT_IO;
  5.   use TEXT_IO;
  6.  
  7. package TOKEN_INPUT is
  8.  
  9.   type INPUT_STREAM is private;
  10.  
  11.   package INTEGER_IO is new TEXT_IO.INTEGER_IO(INTEGER);
  12.     use INTEGER_IO;
  13.  
  14.   function CREATE_STREAM(CARD_LENGTH : POSITIVE) return INPUT_STREAM;
  15.  
  16.   procedure SET_STREAM(STREAM : INPUT_STREAM);
  17.  
  18.   procedure OPEN_INPUT(STREAM : INPUT_STREAM;
  19.                        NAME   : STRING);
  20.  
  21.   procedure OPEN_INPUT(NAME : STRING);
  22.  
  23.   procedure CLOSE_INPUT(STREAM : INPUT_STREAM);
  24.  
  25.   procedure CLOSE_INPUT;
  26.  
  27.   procedure GET_STRING(STREAM : in  INPUT_STREAM;
  28.                        STR    : out STRING;
  29.                        LAST   : out NATURAL);
  30.  
  31.   procedure GET_STRING(STR  : out STRING;
  32.                        LAST : out NATURAL);
  33.  
  34.   function GET_INTEGER(STREAM : INPUT_STREAM) return INTEGER;
  35.  
  36.   function GET_INTEGER return INTEGER;
  37.  
  38.   procedure GOBBLE(STREAM : INPUT_STREAM;
  39.                    STR    : STRING);
  40.  
  41.   procedure GOBBLE(STR : STRING);
  42.  
  43. private
  44.  
  45.   type INPUT_RECORD(CARD_LENGTH : POSITIVE) is
  46.     record
  47.       BUFFER : STRING(1..CARD_LENGTH);
  48.       FILE   : FILE_TYPE;
  49.       NEXT   : POSITIVE := 1;
  50.       LAST   : NATURAL := 0;
  51.     end record;
  52.  
  53.   type INPUT_STREAM is access INPUT_RECORD;
  54.  
  55. end TOKEN_INPUT;
  56.  
  57. package body TOKEN_INPUT is
  58.  
  59.   DEFAULT_STREAM : INPUT_STREAM;
  60.  
  61.   function CREATE_STREAM(CARD_LENGTH : POSITIVE) return INPUT_STREAM is
  62.   begin
  63.     return new INPUT_RECORD(CARD_LENGTH);
  64.   end CREATE_STREAM;
  65.  
  66.   procedure SET_STREAM(STREAM : INPUT_STREAM) is
  67.   begin
  68.     DEFAULT_STREAM := STREAM;
  69.   end SET_STREAM;
  70.  
  71.   procedure OPEN_INPUT(STREAM : INPUT_STREAM;
  72.                        NAME   : STRING) is
  73.   begin
  74.     OPEN(STREAM.FILE,IN_FILE,NAME);
  75.   end OPEN_INPUT;
  76.  
  77.   procedure OPEN_INPUT(NAME : STRING) is
  78.   begin
  79.     OPEN_INPUT(DEFAULT_STREAM,NAME);
  80.   end OPEN_INPUT;
  81.  
  82.   procedure CLOSE_INPUT(STREAM : INPUT_STREAM) is
  83.   begin
  84.     CLOSE(STREAM.FILE);
  85.   end CLOSE_INPUT;
  86.  
  87.   procedure CLOSE_INPUT is
  88.   begin
  89.     CLOSE_INPUT(DEFAULT_STREAM);
  90.   end CLOSE_INPUT;
  91.  
  92.   function ALPHABETIC(C : CHARACTER) return BOOLEAN is
  93.   begin
  94.     return C in 'A'..'Z' or else C in 'a'..'z' or else C = '_';
  95.   end ALPHABETIC;
  96.  
  97.   function NUMERIC(C : CHARACTER) return BOOLEAN is
  98.   begin
  99.     return C in '0'..'9' or else C = '_';
  100.   end NUMERIC;
  101.  
  102.   function WHITESPACE(C : CHARACTER) return BOOLEAN is
  103.   begin
  104.     return C = ' ' or else C = ASCII.HT;
  105.   end WHITESPACE;
  106.  
  107.   procedure NEXT_LINE(STREAM : INPUT_STREAM) is
  108.   begin
  109.     loop
  110.       GET_LINE(STREAM.FILE,STREAM.BUFFER,STREAM.LAST);
  111.       exit when STREAM.LAST >= 2 and then STREAM.BUFFER(1..2) /= "--";
  112.       exit when STREAM.LAST = 1;
  113.     end loop;
  114.     STREAM.NEXT := 1;
  115.   end NEXT_LINE;
  116.  
  117.   procedure NEXT_TOKEN(STREAM : INPUT_STREAM) is
  118.   begin
  119.     loop
  120.       if STREAM.NEXT > STREAM.LAST then
  121.         NEXT_LINE(STREAM);
  122.       end if;
  123.       if STREAM.BUFFER(STREAM.NEXT) = '-' and then
  124.           STREAM.NEXT < STREAM.LAST and then
  125.           STREAM.BUFFER(STREAM.NEXT+1) = '-' then
  126.         NEXT_LINE(STREAM);
  127.       end if;
  128.       exit when not WHITESPACE(STREAM.BUFFER(STREAM.NEXT));
  129.       STREAM.NEXT := STREAM.NEXT + 1;
  130.     end loop;
  131.   end NEXT_TOKEN;
  132.  
  133.   function TOKEN_END(STREAM : INPUT_STREAM) return POSITIVE is
  134.     C   : CHARACTER;
  135.     PTR : POSITIVE;
  136.   begin
  137.     NEXT_TOKEN(STREAM);
  138.     PTR := STREAM.NEXT;
  139.     while PTR <= STREAM.LAST loop
  140.       C := STREAM.BUFFER(PTR);
  141.       exit when WHITESPACE(C);
  142.       case STREAM.BUFFER(STREAM.NEXT) is
  143.         when 'A'..'Z' | 'a'..'z' =>
  144.           exit when not ALPHABETIC(C) and then not NUMERIC(C);
  145.         when '0'..'9' | '-' | '+' =>
  146.           exit when not NUMERIC(C);
  147.         when others =>
  148.           exit when ALPHABETIC(C) or else NUMERIC(C);
  149.       end case;
  150.       PTR := PTR + 1;
  151.     end loop;
  152.     return PTR - 1;
  153.   end TOKEN_END;
  154.  
  155.   procedure GET_STRING(STREAM : in  INPUT_STREAM;
  156.                        STR    : out STRING;
  157.                        LAST   : out NATURAL) is
  158.     TOKEND,
  159.     TLAST : POSITIVE;
  160.   begin
  161.     TOKEND := TOKEN_END(STREAM);
  162.     TLAST := STR'FIRST + TOKEND - STREAM.NEXT;
  163.     STR(STR'FIRST..TLAST) := STREAM.BUFFER(STREAM.NEXT..TOKEND);
  164.     LAST := TLAST;
  165.     STREAM.NEXT := TOKEND + 1;
  166.   end GET_STRING;
  167.  
  168.   procedure GET_STRING(STR  : out STRING;
  169.                        LAST : out NATURAL) is
  170.   begin
  171.     GET_STRING(DEFAULT_STREAM,STR,LAST);
  172.   end GET_STRING;
  173.  
  174.   function GET_INTEGER(STREAM : INPUT_STREAM) return INTEGER is
  175.     TOKEND : POSITIVE;
  176.     INT,
  177.     LAST   : INTEGER;
  178.   begin
  179.     TOKEND := TOKEN_END(STREAM);
  180.     GET(STREAM.BUFFER(STREAM.NEXT..TOKEND),INT,LAST);
  181.     STREAM.NEXT := TOKEND + 1;
  182.     return INT;
  183.   end GET_INTEGER;
  184.  
  185.   function GET_INTEGER return INTEGER is
  186.   begin
  187.     return GET_INTEGER(DEFAULT_STREAM);
  188.   end GET_INTEGER;
  189.  
  190.   procedure GOBBLE(STREAM : INPUT_STREAM;
  191.                    STR    : STRING) is
  192.     S    : STRING(1..STREAM.CARD_LENGTH);
  193.     LAST : INTEGER;
  194.   begin
  195.     GET_STRING(STREAM,S,LAST);
  196.     if S(1..LAST) /= STR then
  197.       raise CONSTRAINT_ERROR;
  198.     end if;
  199.   end GOBBLE;
  200.  
  201.   procedure GOBBLE(STR : STRING) is
  202.   begin
  203.     GOBBLE(DEFAULT_STREAM,STR);
  204.   end GOBBLE;
  205.  
  206. end TOKEN_INPUT;
  207. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  208. --txtprt.ada
  209. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  210. with TEXT_IO;
  211.   use TEXT_IO;
  212.  
  213. package TEXT_PRINT is
  214.  
  215.   type LINE_TYPE is limited private;
  216.  
  217.   type BREAK_TYPE is (BREAK, NO_BREAK);
  218.  
  219.   type PHANTOM_TYPE is private;
  220.  
  221.   procedure CREATE_LINE(LINE : in out LINE_TYPE; LENGTH : in POSITIVE);
  222.  
  223.   procedure SET_LINE(LINE : in LINE_TYPE);
  224.  
  225.   function CURRENT_LINE return LINE_TYPE;
  226.  
  227.   procedure SET_INDENT(LINE   : in LINE_TYPE; INDENT : in NATURAL);
  228.   procedure SET_INDENT(INDENT : in NATURAL);
  229.  
  230.   procedure SET_CONTINUATION_INDENT(LINE   : in LINE_TYPE;
  231.                                     INDENT : in INTEGER);
  232.   procedure SET_CONTINUATION_INDENT(INDENT : in INTEGER);
  233.  
  234.   function MAKE_PHANTOM(S : STRING) return PHANTOM_TYPE;
  235.  
  236.   procedure SET_PHANTOMS(LINE         : in LINE_TYPE;
  237.                          START_PHANTOM,
  238.                          END_PHANTOM  : in PHANTOM_TYPE);
  239.  
  240.   procedure SET_PHANTOMS(START_PHANTOM, END_PHANTOM : in PHANTOM_TYPE);
  241.  
  242.   procedure PRINT(FILE : in FILE_TYPE;
  243.                   LINE : in LINE_TYPE;
  244.                   ITEM : in STRING;
  245.                   BRK  : in BREAK_TYPE := BREAK);
  246.   procedure PRINT(FILE : in FILE_TYPE;
  247.                   ITEM : in STRING;
  248.                   BRK  : in BREAK_TYPE := BREAK);
  249.   procedure PRINT(LINE : in LINE_TYPE;
  250.                   ITEM : in STRING;
  251.                   BRK  : in BREAK_TYPE := BREAK);
  252.   procedure PRINT(ITEM : in STRING;
  253.                   BRK  : in BREAK_TYPE := BREAK);
  254.  
  255.   procedure PRINT_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE);
  256.   procedure PRINT_LINE(FILE : in FILE_TYPE);
  257.   procedure PRINT_LINE(LINE : in LINE_TYPE);
  258.   procedure PRINT_LINE;
  259.  
  260.   procedure BLANK_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE);
  261.   procedure BLANK_LINE(FILE : in FILE_TYPE);
  262.   procedure BLANK_LINE(LINE : in LINE_TYPE);
  263.   procedure BLANK_LINE;
  264.  
  265.   generic
  266.     type NUM is range <>;
  267.   package INTEGER_PRINT is
  268.  
  269.     procedure PRINT(FILE : in FILE_TYPE;
  270.                     LINE : in LINE_TYPE;
  271.                     ITEM : in NUM;
  272.                     BRK  : in BREAK_TYPE := BREAK);
  273.     procedure PRINT(FILE : in FILE_TYPE;
  274.                     ITEM : in NUM;
  275.                     BRK  : in BREAK_TYPE := BREAK);
  276.     procedure PRINT(LINE : in LINE_TYPE;
  277.                     ITEM : in NUM;
  278.                     BRK  : in BREAK_TYPE := BREAK);
  279.     procedure PRINT(ITEM : in NUM;
  280.                     BRK  : in BREAK_TYPE := BREAK);
  281.  
  282.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM);
  283.  
  284.   end INTEGER_PRINT;
  285.  
  286.   generic
  287.     type NUM is digits <>;
  288.   package FLOAT_PRINT is
  289.  
  290.     procedure PRINT(FILE : in FILE_TYPE;
  291.                     LINE : in LINE_TYPE;
  292.                     ITEM : in NUM;
  293.                     BRK  : in BREAK_TYPE := BREAK);
  294.     procedure PRINT(FILE : in FILE_TYPE;
  295.                     ITEM : in NUM;
  296.                     BRK  : in BREAK_TYPE := BREAK);
  297.     procedure PRINT(LINE : in LINE_TYPE;
  298.                     ITEM : in NUM;
  299.                     BRK  : in BREAK_TYPE := BREAK);
  300.     procedure PRINT(ITEM : in NUM;
  301.                     BRK  : in BREAK_TYPE := BREAK);
  302.  
  303.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM);
  304.  
  305.   end FLOAT_PRINT;
  306.  
  307.   NULL_PHANTOM : constant PHANTOM_TYPE;
  308.  
  309.   LAYOUT_ERROR : exception renames TEXT_IO.LAYOUT_ERROR;
  310.  
  311. private
  312.  
  313.   type PHANTOM_TYPE is access STRING;
  314.  
  315.   type LINE_REC(LENGTH : INTEGER) is
  316.     record
  317.       USED_YET            : BOOLEAN := FALSE;
  318.       INDENT              : INTEGER := 0;
  319.       CONTINUATION_INDENT : INTEGER := 2;
  320.       BREAK               : INTEGER := 1;
  321.       INDEX               : INTEGER := 1;
  322.       DATA                : STRING(1..LENGTH);
  323.       START_PHANTOM,
  324.       END_PHANTOM         : PHANTOM_TYPE := NULL_PHANTOM;
  325.     end record;
  326.  
  327.   type LINE_TYPE is access LINE_REC;
  328.  
  329.   NULL_PHANTOM : constant PHANTOM_TYPE := new STRING'("");
  330.  
  331. end TEXT_PRINT;
  332.  
  333. package body TEXT_PRINT is
  334.  
  335.   DEFAULT_LINE : LINE_TYPE;
  336.  
  337.   procedure CREATE_LINE(LINE : in out LINE_TYPE; LENGTH : in POSITIVE) is
  338.   begin
  339.     LINE := new LINE_REC(LENGTH);
  340.   end CREATE_LINE;
  341.  
  342.   procedure SET_LINE(LINE : in LINE_TYPE) is
  343.   begin
  344.     DEFAULT_LINE := LINE;
  345.   end SET_LINE;
  346.  
  347.   function CURRENT_LINE return LINE_TYPE is
  348.   begin
  349.     return DEFAULT_LINE;
  350.   end CURRENT_LINE;
  351.  
  352.   procedure SET_INDENT(LINE   : in LINE_TYPE; INDENT : in NATURAL) is
  353.   begin
  354.     if INDENT >= LINE.LENGTH then
  355.       raise LAYOUT_ERROR;
  356.     end if;
  357.     if LINE.INDEX = LINE.INDENT + 1 then
  358.       for I in 1..INDENT loop
  359.         LINE.DATA(I) := ' ';
  360.       end loop;
  361.       LINE.INDEX := INDENT + 1;
  362.     end if;
  363.     LINE.INDENT := INDENT;
  364.   end SET_INDENT;
  365.  
  366.   procedure SET_INDENT(INDENT : in NATURAL) is
  367.   begin
  368.     SET_INDENT(DEFAULT_LINE,INDENT);
  369.   end SET_INDENT;
  370.  
  371.   procedure SET_CONTINUATION_INDENT(LINE   : in LINE_TYPE;
  372.                                     INDENT : in INTEGER) is
  373.   begin
  374.     if LINE.INDENT + INDENT >= LINE.LENGTH or else LINE.INDENT + INDENT < 0
  375.         then
  376.       raise LAYOUT_ERROR;
  377.     end if;
  378.     LINE.CONTINUATION_INDENT := INDENT;
  379.   end SET_CONTINUATION_INDENT;
  380.  
  381.   procedure SET_CONTINUATION_INDENT(INDENT : in INTEGER) is
  382.   begin
  383.     SET_CONTINUATION_INDENT(DEFAULT_LINE,INDENT);
  384.   end SET_CONTINUATION_INDENT;
  385.  
  386.   function MAKE_PHANTOM(S : STRING) return PHANTOM_TYPE is
  387.   begin
  388.     return new STRING'(S);
  389.   end MAKE_PHANTOM;
  390.  
  391.   procedure SET_PHANTOMS(LINE         : in LINE_TYPE;
  392.                          START_PHANTOM,
  393.                          END_PHANTOM  : in PHANTOM_TYPE) is
  394.   begin
  395.     LINE.START_PHANTOM := START_PHANTOM;
  396.     LINE.END_PHANTOM := END_PHANTOM;
  397.   end SET_PHANTOMS;
  398.  
  399.   procedure SET_PHANTOMS(START_PHANTOM, END_PHANTOM : in PHANTOM_TYPE) is
  400.   begin
  401.     SET_PHANTOMS(DEFAULT_LINE,START_PHANTOM,END_PHANTOM);
  402.   end SET_PHANTOMS;
  403.  
  404.   procedure PRINT(FILE : in FILE_TYPE;
  405.                   LINE : in LINE_TYPE;
  406.                   ITEM : in STRING;
  407.                   BRK  : BREAK_TYPE := BREAK) is
  408.     NEW_BREAK, NEW_INDEX : INTEGER;
  409.   begin
  410.     if LINE.INDEX + ITEM'LENGTH + LINE.END_PHANTOM'LENGTH > LINE.LENGTH + 1
  411.         then
  412.       if LINE.INDENT + LINE.CONTINUATION_INDENT + LINE.START_PHANTOM'LENGTH +
  413.           LINE.INDEX - LINE.BREAK + ITEM'LENGTH > LINE.LENGTH then
  414.         raise LAYOUT_ERROR;
  415.       end if;
  416.       if ITEM = " " and then LINE.END_PHANTOM.all = "" then
  417.         return;
  418.       end if;
  419.       PUT_LINE(FILE,LINE.DATA(1..LINE.BREAK-1) & LINE.END_PHANTOM.all);
  420.       for I in 1..LINE.INDENT + LINE.CONTINUATION_INDENT loop
  421.         LINE.DATA(I) := ' ';
  422.       end loop;
  423.       NEW_BREAK := LINE.INDENT + LINE.CONTINUATION_INDENT + 1;
  424.       NEW_INDEX := NEW_BREAK + LINE.START_PHANTOM'LENGTH +
  425.           LINE.INDEX - LINE.BREAK;
  426.       LINE.DATA(NEW_BREAK..NEW_INDEX) := LINE.START_PHANTOM.all &
  427.           LINE.DATA(LINE.BREAK..LINE.INDEX);
  428.       LINE.BREAK := NEW_BREAK;
  429.       LINE.INDEX := NEW_INDEX;
  430.     end if;
  431.     NEW_INDEX := LINE.INDEX + ITEM'LENGTH;
  432.     LINE.DATA(LINE.INDEX..NEW_INDEX-1) := ITEM;
  433.     LINE.INDEX := NEW_INDEX;
  434.     if BRK = BREAK then
  435.       LINE.BREAK := NEW_INDEX;
  436.     end if;
  437.     LINE.USED_YET := TRUE;
  438.   end PRINT;
  439.  
  440.   procedure PRINT(FILE : in FILE_TYPE;
  441.                   ITEM : in STRING;
  442.                   BRK  : in BREAK_TYPE := BREAK) is
  443.   begin
  444.     PRINT(FILE,DEFAULT_LINE,ITEM,BRK);
  445.   end PRINT;
  446.  
  447.   procedure PRINT(LINE : in LINE_TYPE;
  448.                   ITEM : in STRING;
  449.                   BRK  : in BREAK_TYPE := BREAK) is
  450.   begin
  451.     PRINT(CURRENT_OUTPUT,LINE,ITEM,BRK);
  452.   end PRINT;
  453.  
  454.   procedure PRINT(ITEM : in STRING; BRK : in BREAK_TYPE := BREAK) is
  455.   begin
  456.     PRINT(CURRENT_OUTPUT,DEFAULT_LINE,ITEM,BRK);
  457.   end PRINT;
  458.  
  459.   procedure PRINT_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE) is
  460.   begin
  461.     if LINE.INDEX /= LINE.INDENT + 1 then
  462.       PUT_LINE(FILE,LINE.DATA(1..LINE.INDEX-1));
  463.     end if;
  464.     for I in 1..LINE.INDENT loop
  465.       LINE.DATA(I) := ' ';
  466.     end loop;
  467.     LINE.INDEX := LINE.INDENT + 1;
  468.     LINE.BREAK := LINE.INDEX;
  469.   end PRINT_LINE;
  470.  
  471.   procedure PRINT_LINE(FILE : in FILE_TYPE) is
  472.   begin
  473.     PRINT_LINE(FILE,DEFAULT_LINE);
  474.   end PRINT_LINE;
  475.  
  476.   procedure PRINT_LINE(LINE : in LINE_TYPE) is
  477.   begin
  478.     PRINT_LINE(CURRENT_OUTPUT,LINE);
  479.   end PRINT_LINE;
  480.  
  481.   procedure PRINT_LINE is
  482.   begin
  483.     PRINT_LINE(CURRENT_OUTPUT,DEFAULT_LINE);
  484.   end PRINT_LINE;
  485.  
  486.   procedure BLANK_LINE(FILE : in FILE_TYPE; LINE : in LINE_TYPE) is
  487.   begin
  488.     if LINE.USED_YET then
  489.       NEW_LINE(FILE);
  490.     end if;
  491.   end BLANK_LINE;
  492.  
  493.   procedure BLANK_LINE(FILE : in FILE_TYPE) is
  494.   begin
  495.     BLANK_LINE(FILE,DEFAULT_LINE);
  496.   end BLANK_LINE;
  497.  
  498.   procedure BLANK_LINE(LINE : in LINE_TYPE) is
  499.   begin
  500.     BLANK_LINE(CURRENT_OUTPUT,LINE);
  501.   end BLANK_LINE;
  502.  
  503.   procedure BLANK_LINE is
  504.   begin
  505.     BLANK_LINE(CURRENT_OUTPUT,DEFAULT_LINE);
  506.   end BLANK_LINE;
  507.  
  508.   package body INTEGER_PRINT is
  509.  
  510.     procedure PRINT(FILE : in FILE_TYPE;
  511.                     LINE : in LINE_TYPE;
  512.                     ITEM : in NUM;
  513.                     BRK  : in BREAK_TYPE := BREAK) is
  514.       S : STRING(1..NUM'WIDTH);
  515.       L : NATURAL;
  516.     begin
  517.       PRINT(S,L,ITEM);
  518.       PRINT(FILE,LINE,S(1..L),BRK);
  519.     end PRINT;
  520.  
  521.     procedure PRINT(FILE : in FILE_TYPE;
  522.                     ITEM : in NUM;
  523.                     BRK  : in BREAK_TYPE := BREAK) is
  524.     begin
  525.       PRINT(FILE,DEFAULT_LINE,ITEM,BRK);
  526.     end PRINT;
  527.  
  528.     procedure PRINT(LINE : in LINE_TYPE;
  529.                     ITEM : in NUM;
  530.                     BRK  : in BREAK_TYPE := BREAK) is
  531.     begin
  532.       PRINT(CURRENT_OUTPUT,LINE,ITEM,BRK);
  533.     end PRINT;
  534.  
  535.     procedure PRINT(ITEM : in NUM;
  536.                     BRK  : in BREAK_TYPE := BREAK) is
  537.     begin
  538.       PRINT(CURRENT_OUTPUT,DEFAULT_LINE,ITEM,BRK);
  539.     end PRINT;
  540.  
  541.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM) is
  542.       S : constant STRING := NUM'IMAGE(ITEM);
  543.       F : NATURAL := S'FIRST; -- Bug in DG Compiler -- S'FIRST /= 1 ! ! ! ! ! !
  544.       L : NATURAL;
  545.     begin
  546.       if S(F) = ' ' then
  547.         F := F + 1;
  548.       end if;
  549.       if TO'LENGTH < S'LAST - F + 1 then
  550.         raise LAYOUT_ERROR;
  551.       end if;
  552.       L := TO'FIRST + S'LAST - F;
  553.       TO(TO'FIRST..L) := S(F..S'LAST);
  554.       LAST := L;
  555.     end PRINT;
  556.  
  557.   end INTEGER_PRINT;
  558.  
  559.   package body FLOAT_PRINT is
  560.  
  561.     package NUM_IO is new FLOAT_IO(NUM);
  562.       use NUM_IO;
  563.  
  564.     procedure PRINT(FILE : in FILE_TYPE;
  565.                     LINE : in LINE_TYPE;
  566.                     ITEM : in NUM;
  567.                     BRK  : in BREAK_TYPE := BREAK) is
  568.       S : STRING(1..DEFAULT_FORE + DEFAULT_AFT + DEFAULT_EXP + 2);
  569.       L : NATURAL;
  570.     begin
  571.       PRINT(S,L,ITEM);
  572.       PRINT(FILE,LINE,S(1..L),BRK);
  573.     end PRINT;
  574.  
  575.     procedure PRINT(FILE : in FILE_TYPE;
  576.                     ITEM : in NUM;
  577.                     BRK  : in BREAK_TYPE := BREAK) is
  578.     begin
  579.       PRINT(FILE,DEFAULT_LINE,ITEM,BRK);
  580.     end PRINT;
  581.  
  582.     procedure PRINT(LINE : in LINE_TYPE;
  583.                     ITEM : in NUM;
  584.                     BRK  : in BREAK_TYPE := BREAK) is
  585.     begin
  586.       PRINT(CURRENT_OUTPUT,LINE,ITEM,BRK);
  587.     end PRINT;
  588.  
  589.     procedure PRINT(ITEM : in NUM;
  590.                     BRK  : in BREAK_TYPE := BREAK) is
  591.     begin
  592.       PRINT(CURRENT_OUTPUT,DEFAULT_LINE,ITEM,BRK);
  593.     end PRINT;
  594.  
  595.     procedure PRINT(TO : out STRING; LAST : out NATURAL; ITEM : in NUM) is
  596.       S         : STRING(1..DEFAULT_FORE + DEFAULT_AFT + DEFAULT_EXP + 2);
  597.       EXP       : INTEGER;
  598.       E_INDEX   : NATURAL := S'LAST - DEFAULT_EXP;
  599.       DOT_INDEX : NATURAL := DEFAULT_FORE + 1;
  600.       L         : NATURAL := 0;
  601.     begin
  602.       PUT(S,ITEM);
  603.       EXP := INTEGER'VALUE(S(E_INDEX+1..S'LAST));
  604.       if EXP >= 0 and then EXP <= DEFAULT_AFT-1 then
  605.         S(DOT_INDEX..DOT_INDEX+EXP-1) := S(DOT_INDEX+1..DOT_INDEX+EXP);
  606.         S(DOT_INDEX+EXP) := '.';
  607.         for I in E_INDEX..S'LAST loop
  608.           S(I) := ' ';
  609.         end loop;
  610.       end if;
  611.       for I in reverse 1..E_INDEX-1 loop
  612.         exit when S(I) /= '0' or else S(I-1) = '.';
  613.         S(I) := ' ';
  614.       end loop;
  615.       for I in S'RANGE loop
  616.         if S(I) /= ' ' then
  617.           L := L + 1;
  618.           TO(L) := S(I);
  619.         end if;
  620.       end loop;
  621.       LAST := L;
  622.     exception
  623.       when CONSTRAINT_ERROR =>
  624.         raise LAYOUT_ERROR;
  625.     end PRINT;
  626.  
  627.   end FLOAT_PRINT;
  628.  
  629. end TEXT_PRINT;
  630. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  631. --ddldefs.ada
  632. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  633. package DDL_DEFINITIONS is
  634.  
  635.   type TYPE_TYPE is (SUB_TYPE, REC_ORD, ENUMERATION, INT_EGER, FL_OAT,
  636.       STR_ING);
  637.  
  638.   type TYPE_NAME_STRING is new STRING;
  639.   type TYPE_NAME        is access TYPE_NAME_STRING;
  640.  
  641.   type TYPE_DESCRIPTOR(TY_PE : TYPE_TYPE);
  642.   type ACCESS_TYPE_DESCRIPTOR is access TYPE_DESCRIPTOR;
  643.  
  644.   subtype ACCESS_SUBTYPE_DESCRIPTOR     is ACCESS_TYPE_DESCRIPTOR(SUB_TYPE);
  645.   subtype ACCESS_RECORD_DESCRIPTOR      is ACCESS_TYPE_DESCRIPTOR(REC_ORD);
  646.   subtype ACCESS_ENUMERATION_DESCRIPTOR is ACCESS_TYPE_DESCRIPTOR(ENUMERATION);
  647.   subtype ACCESS_INTEGER_DESCRIPTOR     is ACCESS_TYPE_DESCRIPTOR(INT_EGER);
  648.   subtype ACCESS_FLOAT_DESCRIPTOR       is ACCESS_TYPE_DESCRIPTOR(FL_OAT);
  649.   subtype ACCESS_STRING_DESCRIPTOR      is ACCESS_TYPE_DESCRIPTOR(STR_ING);
  650.  
  651.   type COMPONENT_NAME_STRING is new STRING;
  652.   type COMPONENT_NAME        is access COMPONENT_NAME_STRING;
  653.  
  654.   type COMPONENT_DESCRIPTOR;
  655.   type ACCESS_COMPONENT_DESCRIPTOR is access COMPONENT_DESCRIPTOR;
  656.  
  657.   type COMPONENT_DESCRIPTOR is
  658.     record
  659.       NEXT_COMPONENT,
  660.       PREVIOUS_COMPONENT : ACCESS_COMPONENT_DESCRIPTOR;
  661.       NAME               : COMPONENT_NAME;
  662.       TY_PE,
  663.       PARENT_RECORD      : ACCESS_TYPE_DESCRIPTOR;
  664.     end record;
  665.  
  666.   type SUBRECORD_INDICATOR is new BOOLEAN;
  667.  
  668.   type LITERAL_DESCRIPTOR;
  669.   type ACCESS_LITERAL_DESCRIPTOR is access LITERAL_DESCRIPTOR;
  670.  
  671.   type ENUMERATION_NAME_STRING is new STRING;
  672.   type ENUMERATION_NAME        is access ENUMERATION_NAME_STRING;
  673.  
  674.   type ENUMERATION_POS is new NATURAL;
  675.  
  676.   type LITERAL_DESCRIPTOR is
  677.     record
  678.       NEXT_LITERAL,
  679.       PREVIOUS_LITERAL : ACCESS_LITERAL_DESCRIPTOR;
  680.       NAME             : ENUMERATION_NAME;
  681.       POS              : ENUMERATION_POS;
  682.       PARENT_TYPE      : ACCESS_TYPE_DESCRIPTOR;
  683.     end record;
  684.  
  685.   type STRING_LENGTH is new NATURAL;
  686.  
  687.   type TYPE_DESCRIPTOR(TY_PE : TYPE_TYPE) is
  688.     record
  689.       NAME         : TYPE_NAME;
  690.       NEXT_TYPE,
  691.       PREVIOUS_TYPE,
  692.       FIRST_SUBTYPE,
  693.       LAST_SUBTYPE : ACCESS_TYPE_DESCRIPTOR;
  694.       case TY_PE is
  695.         when SUB_TYPE =>
  696.           PARENT_TYPE,
  697.           TOP_TYPE,
  698.           NEXT_SUBTYPE,
  699.           PREVIOUS_SUBTYPE : ACCESS_TYPE_DESCRIPTOR;
  700.         when REC_ORD =>
  701.           FIRST_COMPONENT,
  702.           LAST_COMPONENT   : ACCESS_COMPONENT_DESCRIPTOR;
  703.           IS_SUBRECORD     : SUBRECORD_INDICATOR := FALSE;
  704.         when ENUMERATION =>
  705.           FIRST_LITERAL,
  706.           LAST_LITERAL     : ACCESS_LITERAL_DESCRIPTOR;
  707.           LAST_POS         : ENUMERATION_POS := 0;
  708.           MAX_LENGTH       : NATURAL := 0;
  709.         when INT_EGER | FL_OAT =>
  710.           null;
  711.         when STR_ING =>
  712.           LENGTH : STRING_LENGTH;
  713.       end case;
  714.     end record;
  715.  
  716. end DDL_DEFINITIONS;
  717. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  718. --listutil.ada
  719. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  720. with DDL_DEFINITIONS;
  721.   use DDL_DEFINITIONS;
  722.  
  723. package LIST_UTILITIES is
  724.  
  725.   function FIRST_TYPE_DESCRIPTOR return ACCESS_TYPE_DESCRIPTOR;
  726.  
  727.   function FIND_TYPE_DESCRIPTOR(NAME : TYPE_NAME_STRING)
  728.       return ACCESS_TYPE_DESCRIPTOR;
  729.  
  730.   procedure ADD_TYPE(T : ACCESS_TYPE_DESCRIPTOR);
  731.  
  732.   procedure ADD_SUBTYPE(PARENT : ACCESS_TYPE_DESCRIPTOR;
  733.                         CHILD  : ACCESS_SUBTYPE_DESCRIPTOR);
  734.  
  735.   procedure ADD_LITERAL(PARENT : ACCESS_ENUMERATION_DESCRIPTOR;
  736.                         CHILD  : ACCESS_LITERAL_DESCRIPTOR);
  737.  
  738.   procedure ADD_COMPONENT(PARENT : ACCESS_RECORD_DESCRIPTOR;
  739.                           CHILD  : ACCESS_COMPONENT_DESCRIPTOR);
  740.  
  741. end LIST_UTILITIES;
  742.  
  743. package body LIST_UTILITIES is
  744.  
  745.   TYPE_DESCRIPTOR_0,                          -- type listhead -- first & last
  746.   TYPE_DESCRIPTOR_9 : ACCESS_TYPE_DESCRIPTOR; --  type descriptors
  747.  
  748.   function FIRST_TYPE_DESCRIPTOR return ACCESS_TYPE_DESCRIPTOR is
  749.   begin
  750.     return TYPE_DESCRIPTOR_0;
  751.   end FIRST_TYPE_DESCRIPTOR;
  752.  
  753.   function FIND_TYPE_DESCRIPTOR(NAME : TYPE_NAME_STRING)
  754.       return ACCESS_TYPE_DESCRIPTOR is
  755.     T : ACCESS_TYPE_DESCRIPTOR := TYPE_DESCRIPTOR_0;
  756.   begin
  757.     while T.NAME.all /= NAME loop
  758.       T := T.NEXT_TYPE; -- CONSTRAINT_ERROR if non-existent type name
  759.     end loop;
  760.     return T;
  761.   end FIND_TYPE_DESCRIPTOR;
  762.  
  763.   procedure ADD_TYPE(T : ACCESS_TYPE_DESCRIPTOR) is
  764.   begin
  765.     if TYPE_DESCRIPTOR_9 = null then
  766.       TYPE_DESCRIPTOR_0 := T;
  767.     else
  768.       TYPE_DESCRIPTOR_9.NEXT_TYPE := T;
  769.     end if;
  770.     T.PREVIOUS_TYPE := TYPE_DESCRIPTOR_9;
  771.     TYPE_DESCRIPTOR_9 := T;
  772.     T.NEXT_TYPE := null;
  773.   end ADD_TYPE;
  774.  
  775.   procedure ADD_SUBTYPE(PARENT : ACCESS_TYPE_DESCRIPTOR;
  776.                         CHILD  : ACCESS_SUBTYPE_DESCRIPTOR) is
  777.   begin
  778.     if PARENT.LAST_SUBTYPE = null then
  779.       PARENT.FIRST_SUBTYPE := CHILD;
  780.     else
  781.       PARENT.LAST_SUBTYPE.NEXT_SUBTYPE := CHILD;
  782.     end if;
  783.     CHILD.PREVIOUS_SUBTYPE := PARENT.LAST_SUBTYPE;
  784.     PARENT.LAST_SUBTYPE := CHILD;
  785.     CHILD.NEXT_SUBTYPE := null;
  786.     CHILD.PARENT_TYPE := PARENT;
  787.   end ADD_SUBTYPE;
  788.  
  789.   procedure ADD_LITERAL(PARENT : ACCESS_ENUMERATION_DESCRIPTOR;
  790.                         CHILD  : ACCESS_LITERAL_DESCRIPTOR) is
  791.   begin
  792.     if PARENT.LAST_LITERAL = null then
  793.       PARENT.FIRST_LITERAL := CHILD;
  794.     else
  795.       PARENT.LAST_LITERAL.NEXT_LITERAL := CHILD;
  796.     end if;
  797.     CHILD.PREVIOUS_LITERAL := PARENT.LAST_LITERAL;
  798.     PARENT.LAST_LITERAL := CHILD;
  799.     CHILD.NEXT_LITERAL := null;
  800.     CHILD.PARENT_TYPE := PARENT;
  801.   end ADD_LITERAL;
  802.  
  803.   procedure ADD_COMPONENT(PARENT : ACCESS_RECORD_DESCRIPTOR;
  804.                           CHILD  : ACCESS_COMPONENT_DESCRIPTOR) is
  805.   begin
  806.     if PARENT.LAST_COMPONENT = null then
  807.       PARENT.FIRST_COMPONENT := CHILD;
  808.     else
  809.       PARENT.LAST_COMPONENT.NEXT_COMPONENT := CHILD;
  810.     end if;
  811.     CHILD.PREVIOUS_COMPONENT := PARENT.LAST_COMPONENT;
  812.     PARENT.LAST_COMPONENT := CHILD;
  813.     CHILD.NEXT_COMPONENT := null;
  814.     CHILD.PARENT_RECORD := PARENT;
  815.   end ADD_COMPONENT;
  816.  
  817. end LIST_UTILITIES;
  818. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  819. --readddl.ada
  820. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  821. with DDL_DEFINITIONS, LIST_UTILITIES, TOKEN_INPUT;
  822.   use DDL_DEFINITIONS, LIST_UTILITIES, TOKEN_INPUT;
  823.  
  824. package READ_DDL is
  825.  
  826.   procedure SCAN_DDL(PACKAGE_NAME : out STRING;
  827.                      LAST         : out POSITIVE);
  828.  
  829. end READ_DDL;
  830.  
  831. package body READ_DDL is
  832.  
  833.   procedure PROCESS_DERIVED_TYPE(NEW_NAME : TYPE_NAME) is
  834.     KEYWORD  : STRING(1..7);
  835.     LAST     : POSITIVE;
  836.     STR_LAST : STRING_LENGTH;
  837.   begin
  838.     GET_STRING(KEYWORD,LAST);
  839.     if KEYWORD(1..LAST) = "INTEGER" then
  840.       ADD_TYPE ( new TYPE_DESCRIPTOR'(TY_PE => INT_EGER, NAME => NEW_NAME,
  841.           others => null) );
  842.       GOBBLE(";");
  843.     elsif KEYWORD(1..LAST) = "FLOAT" then
  844.       ADD_TYPE ( new TYPE_DESCRIPTOR'(TY_PE => FL_OAT,   NAME => NEW_NAME,
  845.           others => null) );
  846.       GOBBLE(";");
  847.     elsif KEYWORD(1..LAST) = "STRING" then
  848.       GOBBLE("("); GOBBLE("1"); GOBBLE("..");
  849.       STR_LAST := STRING_LENGTH(GET_INTEGER);
  850.       ADD_TYPE ( new TYPE_DESCRIPTOR'(TY_PE => STR_ING,  NAME => NEW_NAME,
  851.           LENGTH => STR_LAST, others => null) );
  852.       GOBBLE(");");
  853.     else
  854.       raise CONSTRAINT_ERROR; -- unrecognized type keyword
  855.     end if;
  856.   end PROCESS_DERIVED_TYPE;
  857.  
  858.   procedure PROCESS_ENUMERATION_TYPE(NEW_NAME : TYPE_NAME) is
  859.     PARENT    : ACCESS_ENUMERATION_DESCRIPTOR;
  860.     LITERAL   : ENUMERATION_NAME_STRING(1..80);
  861.     LAST      : POSITIVE;
  862.     DELIMITER : STRING(1..2);
  863.   begin
  864.     PARENT := new TYPE_DESCRIPTOR'(TY_PE => ENUMERATION, NAME => NEW_NAME,
  865.         LAST_POS => 0, MAX_LENGTH => 0, FIRST_LITERAL | LAST_LITERAL => null,
  866.         others => null);
  867.     ADD_TYPE(PARENT);
  868.     loop
  869.       GET_STRING(STRING(LITERAL),LAST);
  870.       PARENT.LAST_POS := PARENT.LAST_POS + 1;
  871.       if LAST > PARENT.MAX_LENGTH then
  872.         PARENT.MAX_LENGTH := LAST;
  873.       end if;
  874.       ADD_LITERAL ( PARENT, new LITERAL_DESCRIPTOR'(
  875.           NAME => new ENUMERATION_NAME_STRING'(LITERAL(1..LAST)),
  876.           POS  => PARENT.LAST_POS, PARENT_TYPE => PARENT, others => null) );
  877.       GET_STRING(DELIMITER,LAST);
  878.       if DELIMITER(1..LAST) = ");" then
  879.         exit;
  880.       elsif DELIMITER(1..LAST) /= "," then
  881.         raise CONSTRAINT_ERROR; -- invalid enumeration literal list
  882.       end if;
  883.     end loop;
  884.   end PROCESS_ENUMERATION_TYPE;
  885.  
  886.   procedure PROCESS_RECORD_TYPE(NEW_NAME : TYPE_NAME) is
  887.     FIELD_TYPE_NAME : TYPE_NAME_STRING(1..80);
  888.     FIELD_NAME      : COMPONENT_NAME_STRING(1..80);
  889.     FIELD_TYPE      : ACCESS_TYPE_DESCRIPTOR;
  890.     PARENT          : ACCESS_RECORD_DESCRIPTOR;
  891.     FIELD_TYPE_LAST,
  892.     FIELD_LAST      : POSITIVE;
  893.   begin
  894.     PARENT := new TYPE_DESCRIPTOR'(TY_PE => REC_ORD, NAME => NEW_NAME,
  895.         IS_SUBRECORD => FALSE, FIRST_COMPONENT | LAST_COMPONENT => null,
  896.         others => null);
  897.     ADD_TYPE(PARENT);
  898.     loop
  899.       GET_STRING(STRING(FIELD_NAME),FIELD_LAST);
  900.       if FIELD_NAME(1..FIELD_LAST) = "end" then
  901.         GOBBLE("record"); GOBBLE(";");
  902.         exit;
  903.       end if;
  904.       GOBBLE(":");
  905.       GET_STRING(STRING(FIELD_TYPE_NAME),FIELD_TYPE_LAST);
  906.       FIELD_TYPE := FIND_TYPE_DESCRIPTOR(FIELD_TYPE_NAME(1..FIELD_TYPE_LAST));
  907.       if FIELD_TYPE.TY_PE = REC_ORD then
  908.         FIELD_TYPE.IS_SUBRECORD := TRUE;
  909.       end if;
  910.       ADD_COMPONENT ( PARENT, new COMPONENT_DESCRIPTOR' (
  911.           NAME  => new COMPONENT_NAME_STRING'(FIELD_NAME(1..FIELD_LAST)),
  912.           TY_PE => FIELD_TYPE, PARENT_RECORD => PARENT, others => null ) );
  913.       GOBBLE(";");
  914.     end loop;
  915.   end PROCESS_RECORD_TYPE;
  916.  
  917.   procedure PROCESS_TYPE is
  918.     NAME_STRING    : TYPE_NAME_STRING(1..80);
  919.     NAME           : TYPE_NAME;
  920.     LAST           : POSITIVE;
  921.     TYPE_INDICATOR : STRING(1..6);
  922.   begin
  923.     GET_STRING(STRING(NAME_STRING),LAST);
  924.     NAME := new TYPE_NAME_STRING'(NAME_STRING(1..LAST));
  925.     GOBBLE("is");
  926.     GET_STRING(TYPE_INDICATOR,LAST);
  927.     if TYPE_INDICATOR(1..LAST) = "(" then
  928.       PROCESS_ENUMERATION_TYPE(NAME);
  929.     elsif TYPE_INDICATOR(1..LAST) = "new" then
  930.       PROCESS_DERIVED_TYPE(NAME);
  931.     elsif TYPE_INDICATOR(1..LAST) = "record" then
  932.       PROCESS_RECORD_TYPE(NAME);
  933.     else
  934.       raise CONSTRAINT_ERROR; -- unrecognized type keyword/indicator
  935.     end if;
  936.   end PROCESS_TYPE;
  937.  
  938.   procedure PROCESS_SUBTYPE is
  939.     CHILD_NAME,
  940.     PARENT_NAME       : TYPE_NAME_STRING(1..80);
  941.     CHILD_LAST,
  942.     PARENT_LAST       : POSITIVE;
  943.     PARENT_DESCRIPTOR : ACCESS_TYPE_DESCRIPTOR;
  944.     CHILD_DESCRIPTOR  : ACCESS_SUBTYPE_DESCRIPTOR;
  945.   begin
  946.     GET_STRING(STRING(CHILD_NAME),CHILD_LAST);
  947.     GOBBLE("is");
  948.     GET_STRING(STRING(PARENT_NAME),PARENT_LAST);
  949.     GOBBLE(";");
  950.     PARENT_DESCRIPTOR := FIND_TYPE_DESCRIPTOR(PARENT_NAME(1..PARENT_LAST));
  951.     CHILD_DESCRIPTOR := new TYPE_DESCRIPTOR' (
  952.         TY_PE  => SUB_TYPE,
  953.         NAME   => new TYPE_NAME_STRING'(CHILD_NAME(1..CHILD_LAST)),
  954.         others => null );
  955.     ADD_TYPE(CHILD_DESCRIPTOR);
  956.     ADD_SUBTYPE(PARENT_DESCRIPTOR, CHILD_DESCRIPTOR);
  957.     if PARENT_DESCRIPTOR.TY_PE = SUB_TYPE then
  958.       CHILD_DESCRIPTOR.TOP_TYPE := PARENT_DESCRIPTOR.TOP_TYPE;
  959.     else
  960.       CHILD_DESCRIPTOR.TOP_TYPE := PARENT_DESCRIPTOR;
  961.     end if;
  962.   end PROCESS_SUBTYPE;
  963.  
  964.   procedure SCAN_DDL(PACKAGE_NAME : out STRING;
  965.                      LAST         : out POSITIVE) is
  966.     KEYWORD : STRING(1..7);
  967.     KLAST   : POSITIVE;
  968.   begin
  969.     GOBBLE("package");
  970.     GET_STRING(PACKAGE_NAME,LAST);
  971.     GOBBLE("is");
  972.     loop
  973.       GET_STRING(KEYWORD,KLAST);
  974.       if KEYWORD(1..KLAST) = "type" then
  975.         PROCESS_TYPE;
  976.       elsif KEYWORD(1..KLAST) = "subtype" then
  977.         PROCESS_SUBTYPE;
  978.       elsif KEYWORD(1..KLAST) = "end" then
  979.         exit;
  980.       else
  981.         raise CONSTRAINT_ERROR; -- unrecognized keyword
  982.       end if;
  983.     end loop;
  984.   end SCAN_DDL;
  985.  
  986. end READ_DDL;
  987. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  988. --showddl.ada
  989. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  990. with DDL_DEFINITIONS, TEXT_PRINT;
  991.   use DDL_DEFINITIONS, TEXT_PRINT;
  992.  
  993. package SHOW_DDL is
  994.  
  995.   package INT_PRINT is new INTEGER_PRINT(INTEGER);
  996.     use INT_PRINT;
  997.  
  998.   procedure DISPLAY_DDL(PACKAGE_NAME : STRING);
  999.  
  1000.   procedure PRINT_ENUMERATION_LITERALS(L : ACCESS_LITERAL_DESCRIPTOR);
  1001.  
  1002.   function MAX_COMPONENT_NAME_LENGTH(C : ACCESS_COMPONENT_DESCRIPTOR) return
  1003.       NATURAL;
  1004.  
  1005. end SHOW_DDL;
  1006.  
  1007. with DDL_DEFINITIONS, LIST_UTILITIES, TEXT_PRINT;
  1008.   use DDL_DEFINITIONS, LIST_UTILITIES, TEXT_PRINT;
  1009.  
  1010. package body SHOW_DDL is
  1011.  
  1012.   procedure SHOW_SUBTYPE_TREE(T : ACCESS_TYPE_DESCRIPTOR; LEVEL : NATURAL) is
  1013.   begin
  1014.     if T /= null then
  1015.       PRINT("-- ",NO_BREAK);
  1016.       for I in 1..LEVEL loop
  1017.         PRINT("  ",NO_BREAK);
  1018.       end loop;
  1019.       PRINT(STRING(T.NAME.all)); PRINT_LINE;
  1020.       SHOW_SUBTYPE_TREE(T.FIRST_SUBTYPE,LEVEL+1);
  1021.       if T.TY_PE = SUB_TYPE then
  1022.         SHOW_SUBTYPE_TREE(T.NEXT_SUBTYPE,LEVEL);
  1023.       end if;
  1024.     end if;
  1025.   end SHOW_SUBTYPE_TREE;
  1026.  
  1027.   procedure SHOW_SUBTYPES is
  1028.     CURRENT_TYPE : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1029.   begin
  1030.     PRINT("-- subtype tree"); PRINT_LINE; BLANK_LINE;
  1031.     while CURRENT_TYPE /= null loop
  1032.       if CURRENT_TYPE.TY_PE /= SUB_TYPE then
  1033.         SHOW_SUBTYPE_TREE(CURRENT_TYPE,0);
  1034.         BLANK_LINE;
  1035.       end if;
  1036.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1037.     end loop;
  1038.   end SHOW_SUBTYPES;
  1039.  
  1040.   function BLANK_LINE_FOLLOWS(T : ACCESS_TYPE_DESCRIPTOR) return BOOLEAN is
  1041.   begin
  1042.     if T.TY_PE = REC_ORD or else T.NEXT_TYPE = null then
  1043.       return TRUE;
  1044.     elsif T.NEXT_TYPE.TY_PE /= SUB_TYPE then
  1045.       case T.TY_PE is
  1046.         when INT_EGER | FL_OAT | STR_ING =>
  1047.           if T.TY_PE /= T.NEXT_TYPE.TY_PE or else
  1048.               ( T.NEXT_TYPE.NEXT_TYPE /= null and then
  1049.                   T.NEXT_TYPE.NEXT_TYPE.TY_PE = SUB_TYPE ) then
  1050.             return TRUE;
  1051.           end if;
  1052.         when others =>
  1053.           return TRUE;
  1054.       end case;
  1055.     end if;
  1056.     return FALSE;
  1057.   end BLANK_LINE_FOLLOWS;
  1058.  
  1059.   function MAX_TYPE_NAME_LENGTH(T : ACCESS_TYPE_DESCRIPTOR) return NATURAL is
  1060.     LENGTH : NATURAL := 0;
  1061.     Q      : ACCESS_TYPE_DESCRIPTOR := T;
  1062.   begin
  1063.     while Q /= null loop
  1064.       if Q.NAME'LAST > LENGTH then
  1065.         LENGTH := Q.NAME'LAST;
  1066.       end if;
  1067.       exit when BLANK_LINE_FOLLOWS(Q);
  1068.       Q := Q.NEXT_TYPE;
  1069.     end loop;
  1070.     return LENGTH;
  1071.   end MAX_TYPE_NAME_LENGTH;
  1072.  
  1073.   function MAX_COMPONENT_NAME_LENGTH(C : ACCESS_COMPONENT_DESCRIPTOR) return
  1074.       NATURAL is
  1075.     LENGTH : NATURAL := 0;
  1076.     D      : ACCESS_COMPONENT_DESCRIPTOR := C;
  1077.   begin
  1078.     while D /= null loop
  1079.       if D.NAME'LAST > LENGTH then
  1080.         LENGTH := D.NAME'LAST;
  1081.       end if;
  1082.       D := D.NEXT_COMPONENT;
  1083.     end loop;
  1084.     return LENGTH;
  1085.   end MAX_COMPONENT_NAME_LENGTH;
  1086.  
  1087.   procedure PRINT_TYPE_IS(T      : ACCESS_TYPE_DESCRIPTOR;
  1088.                           LENGTH : NATURAL) is
  1089.   begin
  1090.     if T.TY_PE = SUB_TYPE then
  1091.       PRINT("subtype ",NO_BREAK);
  1092.     else
  1093.       PRINT("type ",NO_BREAK);
  1094.     end if;
  1095.     PRINT(STRING(T.NAME.all),NO_BREAK);
  1096.     if T.TY_PE = SUB_TYPE or else T.NEXT_TYPE = null or else
  1097.         T.NEXT_TYPE.TY_PE /= SUB_TYPE then
  1098.       for I in 1..LENGTH-T.NAME'LAST loop
  1099.         PRINT(" ",NO_BREAK);
  1100.       end loop;
  1101.     end if;
  1102.     PRINT(" is",NO_BREAK);
  1103.   end PRINT_TYPE_IS;
  1104.  
  1105.   procedure PRINT_ENUMERATION_LITERALS(L : ACCESS_LITERAL_DESCRIPTOR) is
  1106.             M : ACCESS_LITERAL_DESCRIPTOR := L;
  1107.   begin
  1108.     loop
  1109.       PRINT(STRING(M.NAME.all),NO_BREAK);
  1110.       M := M.NEXT_LITERAL;
  1111.       if M = null then
  1112.         exit;
  1113.       else
  1114.         PRINT(",");
  1115.       end if;
  1116.     end loop;
  1117.   end PRINT_ENUMERATION_LITERALS;
  1118.  
  1119.   procedure PRINT_RECORD_COMPONENTS(C : ACCESS_COMPONENT_DESCRIPTOR) is
  1120.     D : ACCESS_COMPONENT_DESCRIPTOR := C;
  1121.     LENGTH : NATURAL := MAX_COMPONENT_NAME_LENGTH(D);
  1122.   begin
  1123.     while D /= null loop
  1124.       PRINT(STRING(D.NAME.all),NO_BREAK);
  1125.       for I in 1..LENGTH-D.NAME'LAST loop
  1126.         PRINT(" ",NO_BREAK);
  1127.       end loop;
  1128.       PRINT(" : " & STRING(D.TY_PE.NAME.all) & ";"); PRINT_LINE;
  1129.       D := D.NEXT_COMPONENT;
  1130.     end loop;
  1131.   end PRINT_RECORD_COMPONENTS;
  1132.  
  1133.   procedure SHOW_SOURCE is
  1134.     CURRENT_TYPE : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1135.     NAME_LENGTH  : NATURAL := MAX_TYPE_NAME_LENGTH(CURRENT_TYPE);
  1136.   begin
  1137.     while CURRENT_TYPE /= null loop
  1138.       PRINT_TYPE_IS(CURRENT_TYPE,NAME_LENGTH);
  1139.       case CURRENT_TYPE.TY_PE is
  1140.         when SUB_TYPE =>
  1141.           PRINT(" ",NO_BREAK);
  1142.           PRINT(STRING(CURRENT_TYPE.PARENT_TYPE.NAME.all),NO_BREAK);
  1143.         when REC_ORD =>
  1144.           PRINT_LINE; PRINT("  record"); PRINT_LINE; SET_INDENT(6);
  1145.           PRINT_RECORD_COMPONENTS(CURRENT_TYPE.FIRST_COMPONENT);
  1146.           SET_INDENT(2); PRINT("  end record");
  1147.         when ENUMERATION =>
  1148.           PRINT(" (",NO_BREAK);
  1149.           PRINT_ENUMERATION_LITERALS(CURRENT_TYPE.FIRST_LITERAL);
  1150.           PRINT(")",NO_BREAK);
  1151.         when INT_EGER =>
  1152.           PRINT(" new INTEGER",NO_BREAK);
  1153.         when FL_OAT =>
  1154.           PRINT(" new FLOAT",NO_BREAK);
  1155.         when STR_ING =>
  1156.           PRINT(" new STRING(1..",NO_BREAK);
  1157.           PRINT(INTEGER(CURRENT_TYPE.LENGTH),NO_BREAK);
  1158.           PRINT(")",NO_BREAK);
  1159.       end case;
  1160.       PRINT(";"); PRINT_LINE;
  1161.       if BLANK_LINE_FOLLOWS(CURRENT_TYPE) then
  1162.         BLANK_LINE;
  1163.         NAME_LENGTH := MAX_TYPE_NAME_LENGTH(CURRENT_TYPE.NEXT_TYPE);
  1164.       end if;
  1165.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1166.     end loop;
  1167.   end SHOW_SOURCE;
  1168.  
  1169.   procedure DISPLAY_DDL(PACKAGE_NAME : STRING) is
  1170.   begin
  1171.     SET_INDENT(0); SET_CONTINUATION_INDENT(2);
  1172.     PRINT("package " & PACKAGE_NAME & " is"); PRINT_LINE; BLANK_LINE;
  1173.     SET_INDENT(2);
  1174.     SHOW_SUBTYPES;
  1175.     SHOW_SOURCE;
  1176.     SET_INDENT(0);
  1177.     PRINT("end " & PACKAGE_NAME & ";"); PRINT_LINE;
  1178.   end DISPLAY_DDL;
  1179.  
  1180. end SHOW_DDL;
  1181. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1182. --simddl.ada
  1183. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1184. package SIMPLE_DDL is
  1185.  
  1186.   procedure GENERATE_SIMPLE_DDL;
  1187.  
  1188. end SIMPLE_DDL;
  1189.  
  1190. with DDL_DEFINITIONS, LIST_UTILITIES, SHOW_DDL, TEXT_PRINT;
  1191.   use DDL_DEFINITIONS, LIST_UTILITIES, SHOW_DDL, TEXT_PRINT;
  1192.  
  1193. package body SIMPLE_DDL is
  1194.  
  1195.   use SHOW_DDL.INT_PRINT;
  1196.  
  1197.   procedure PRINT_FIELDS(C : ACCESS_COMPONENT_DESCRIPTOR) is
  1198.     D : ACCESS_COMPONENT_DESCRIPTOR := C;
  1199.     T : ACCESS_TYPE_DESCRIPTOR;
  1200.   begin
  1201.     while D /= null loop
  1202.       T := D.TY_PE;
  1203.       if T.TY_PE = SUB_TYPE then
  1204.         T := T.TOP_TYPE;
  1205.       end if;
  1206.       case T.TY_PE is
  1207.         when SUB_TYPE =>
  1208.           raise PROGRAM_ERROR; -- internal error due to if above
  1209.         when REC_ORD =>
  1210.           PRINT_FIELDS(T.FIRST_COMPONENT);
  1211.         when ENUMERATION =>
  1212.           PRINT("FIELD " & STRING(D.NAME.all) & " STRING ",NO_BREAK);
  1213.           PRINT(T.MAX_LENGTH + ENUMERATION_POS'IMAGE(T.LAST_POS)'LENGTH - 1);
  1214.           PRINT_LINE;
  1215.         when INT_EGER =>
  1216.           PRINT("FIELD " & STRING(D.NAME.all) & " INTEGER 6"); PRINT_LINE;
  1217.         when FL_OAT =>
  1218.           PRINT("FIELD " & STRING(D.NAME.all) & " FLOAT 7"); PRINT_LINE;
  1219.         when STR_ING =>
  1220.           PRINT("FIELD " & STRING(D.NAME.all) & " STRING ",NO_BREAK);
  1221.           PRINT(INTEGER(T.LENGTH)); PRINT_LINE;
  1222.       end case;
  1223.       D := D.NEXT_COMPONENT;
  1224.     end loop;
  1225.   end PRINT_FIELDS;
  1226.  
  1227.   procedure GENERATE_SIMPLE_DDL is
  1228.     CURRENT_TYPE : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1229.   begin
  1230.     SET_INDENT(0); SET_CONTINUATION_INDENT(2);
  1231.     while CURRENT_TYPE /= null loop
  1232.       if CURRENT_TYPE.TY_PE = REC_ORD and then
  1233.           CURRENT_TYPE.IS_SUBRECORD = FALSE then
  1234.         PRINT("TABLE " & STRING(CURRENT_TYPE.NAME.all)); PRINT_LINE;
  1235.         BLANK_LINE;
  1236.         PRINT_FIELDS(CURRENT_TYPE.FIRST_COMPONENT);
  1237.         BLANK_LINE;
  1238.       end if;
  1239.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1240.     end loop;
  1241.     PRINT("END"); PRINT_LINE;
  1242.   end GENERATE_SIMPLE_DDL;
  1243.  
  1244. end SIMPLE_DDL;
  1245. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1246. --damesddl.ada
  1247. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1248. package DAMES_DDL is
  1249.  
  1250.   procedure GENERATE_DAMES_DDL;
  1251.  
  1252. end DAMES_DDL;
  1253.  
  1254. with DDL_DEFINITIONS, LIST_UTILITIES, SHOW_DDL, TEXT_PRINT;
  1255.   use DDL_DEFINITIONS, LIST_UTILITIES, SHOW_DDL, TEXT_PRINT;
  1256.  
  1257. package body DAMES_DDL is
  1258.  
  1259.   use SHOW_DDL.INT_PRINT;
  1260.  
  1261.   START_PHANTOM : constant PHANTOM_TYPE := MAKE_PHANTOM("""");
  1262.   END_PHANTOM   : constant PHANTOM_TYPE := MAKE_PHANTOM(""" &");
  1263.  
  1264.   procedure PRINT_FIELD_NAME(C          : in     ACCESS_COMPONENT_DESCRIPTOR;
  1265.                              FIRST_TIME : in out BOOLEAN;
  1266.                              SEPARATOR  : in     STRING) is
  1267.   begin
  1268.     if FIRST_TIME then
  1269.       FIRST_TIME := FALSE;
  1270.     else
  1271.       PRINT(SEPARATOR & """ &"); PRINT_LINE;
  1272.     end if;
  1273.     PRINT("""" & STRING(C.NAME.all),NO_BREAK);
  1274.   end PRINT_FIELD_NAME;
  1275.  
  1276.   procedure PRINT_FIELDS(C          : ACCESS_COMPONENT_DESCRIPTOR;
  1277.                          FIRST_TIME : BOOLEAN := TRUE;
  1278.                          SEPARATOR  : STRING  := ";") is
  1279.     D  : ACCESS_COMPONENT_DESCRIPTOR := C;
  1280.     T  : ACCESS_TYPE_DESCRIPTOR;
  1281.     FT : BOOLEAN := FIRST_TIME;
  1282.   begin
  1283.     while D /= null loop
  1284.       T := D.TY_PE;
  1285.       if T.TY_PE = SUB_TYPE then
  1286.         T := T.TOP_TYPE;
  1287.       end if;
  1288.       case T.TY_PE is
  1289.         when SUB_TYPE =>
  1290.           raise PROGRAM_ERROR; -- internal error due to if above
  1291.         when REC_ORD =>
  1292.           if D.PARENT_RECORD.IS_SUBRECORD = TRUE then
  1293.             PRINT_FIELDS(T.FIRST_COMPONENT,FT,SEPARATOR); FT := FALSE;
  1294.           else
  1295.             PRINT_FIELD_NAME(D,FT,SEPARATOR); PRINT(" "" &"); PRINT_LINE;
  1296.             SET_INDENT(5);
  1297.             PRINT_FIELDS(T.FIRST_COMPONENT,TRUE,",");
  1298.             SET_INDENT(3);
  1299.           end if;
  1300.         when ENUMERATION =>
  1301.           PRINT_FIELD_NAME(D,FT,SEPARATOR); PRINT(" (",NO_BREAK);
  1302.           PRINT_ENUMERATION_LITERALS(T.FIRST_LITERAL); PRINT(")",NO_BREAK);
  1303.         when INT_EGER =>
  1304.           PRINT_FIELD_NAME(D,FT,SEPARATOR); PRINT(" INTEGER");
  1305.         when FL_OAT =>
  1306.           PRINT_FIELD_NAME(D,FT,SEPARATOR); PRINT(" FLOAT");
  1307.         when STR_ING =>
  1308.           PRINT_FIELD_NAME(D,FT,SEPARATOR); PRINT(" STRING 1..",NO_BREAK);
  1309.           PRINT(INTEGER(T.LENGTH));
  1310.       end case;
  1311.       D := D.NEXT_COMPONENT;
  1312.     end loop;
  1313.   end PRINT_FIELDS;
  1314.  
  1315.   procedure GENERATE_DAMES_DDL is
  1316.     CURRENT_TYPE : ACCESS_TYPE_DESCRIPTOR := FIRST_TYPE_DESCRIPTOR;
  1317.     FIRST_TIME   : BOOLEAN := TRUE;
  1318.   begin
  1319.     SET_CONTINUATION_INDENT(2); SET_PHANTOMS(START_PHANTOM,END_PHANTOM);
  1320.     while CURRENT_TYPE /= null loop
  1321.       if CURRENT_TYPE.TY_PE = REC_ORD and then
  1322.           CURRENT_TYPE.IS_SUBRECORD = FALSE then
  1323.         if FIRST_TIME then
  1324.           FIRST_TIME := FALSE;
  1325.         else
  1326.           BLANK_LINE;
  1327.         end if;
  1328.         SET_INDENT(2);
  1329.         PRINT("DEFINE_TABLE(""" & STRING(CURRENT_TYPE.NAME.all) & """,");
  1330.         PRINT_LINE; SET_INDENT(3);
  1331.         PRINT_FIELDS(CURRENT_TYPE.FIRST_COMPONENT);
  1332.         PRINT(""");"); PRINT_LINE;
  1333.       end if;
  1334.       CURRENT_TYPE := CURRENT_TYPE.NEXT_TYPE;
  1335.     end loop;
  1336.     SET_INDENT(0); SET_PHANTOMS(NULL_PHANTOM,NULL_PHANTOM);
  1337.   end GENERATE_DAMES_DDL;
  1338.  
  1339. end DAMES_DDL;
  1340. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1341. --main.ada
  1342. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1343. with DAMES_DDL, READ_DDL, SHOW_DDL, SIMPLE_DDL, TEXT_IO, TEXT_PRINT,
  1344.     TOKEN_INPUT;
  1345.   use DAMES_DDL, READ_DDL, SHOW_DDL, SIMPLE_DDL, TEXT_IO, TEXT_PRINT,
  1346.       TOKEN_INPUT;
  1347.  
  1348. procedure MAIN is
  1349.  
  1350.   LINE         : LINE_TYPE;
  1351.   PACKAGE_NAME : STRING(1..80);
  1352.   LAST         : NATURAL;
  1353.  
  1354.   procedure PRINT_RULE is
  1355.   begin
  1356.     PRINT("---------------------------------------" &
  1357.           "---------------------------------------"); PRINT_LINE;
  1358.   end PRINT_RULE;
  1359.  
  1360. begin
  1361.   SET_STREAM(CREATE_STREAM(80)); OPEN_INPUT("BOATS.ADA");
  1362.   CREATE_LINE(LINE,79); SET_LINE(LINE);
  1363.   SCAN_DDL(PACKAGE_NAME,LAST);
  1364.   DISPLAY_DDL(PACKAGE_NAME(1..LAST)); PRINT_RULE;
  1365.   GENERATE_SIMPLE_DDL; PRINT_RULE;
  1366.   GENERATE_DAMES_DDL;
  1367.   CLOSE_INPUT;
  1368. end MAIN;
  1369.