#define X_APP 1
#include <stdio.h>
#define SUPPRESS_DATA 1
#define P_mktuple(op, alt, count, T) P_mktuple_inner(op, alt, count, T, #op, __FILE__, __LINE__)
extern int P_mktuple_inner(int op, int alt, int count, int T[], const char *opname, const char *file, const int line);

#include "colorsep.h"
#define AST_idx_mask 0x7FFFFFFU
#define AST_type_shift 27U
#define AST_type_mask  31U
#define AST_BIP      (16U << AST_type_shift)
#define AST_PHRASE   (17U << AST_type_shift)
#define AST_ATOM_LIT (18U << AST_type_shift)


// I wish I had documented this better.  I *hope* that what I'm doing here is
// converting the concrete syntax tree into an abstract syntax tree.

int compile(int Ph, int depth) {

  // AST format not properly designed yet.  These are placeholders:

#define P(x) (x)
  int AST_index = Ph&AST_idx_mask;
  int AST_type  = Ph & (AST_type_mask << AST_type_shift);
  int op    = AST(AST_index+1);
  int alt   = AST(AST_index+2);
  int count = AST(AST_index+3);
  int t[LARGEST_ALT];
  int r = 0;

  switch (op) {
    // It is here for incorporating as the basis of a compile() function to do something useful with an AST.
    // For example this generated the code that was manually converted into algol60-indent.h

//\\ B<EOF> = 0;
//\\#
//\\ P<begin-arguments> =
   case P_begin_arguments:
     {                              //\\    "(";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_begin_arguments, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<end-arguments> =
   case P_end_arguments:
     {                              //\\    ")";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_end_arguments, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<begin-array> =
   case P_begin_array:
     {                              //\\    "[";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_begin_array, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<end-array> =
   case P_end_array:
     {                              //\\    "]";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_end_array, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<begin-scope> =
   case P_begin_scope:
     {                              //\\    "{";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_begin_scope, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<end-scope> =
   case P_end_scope:
     {                              //\\    "}";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_end_scope, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<value-separator> =
   case P_value_separator:
     {                              //\\    ",";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_value_separator, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<object-separator> =
   case P_object_separator:
     {                              //\\    ";";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_object_separator, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<name-separator> =
   case P_name_separator:
     {                              //\\    "=";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_name_separator, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<array> =
   case P_array:
     {                              //\\    <begin-array> <value-list> <end-array>;
     t[1] = compile(P(1), depth+1 /* P_begin_array */);
     t[2] = compile(P(2), depth+1 /* P_value_list */);
     t[3] = compile(P(3), depth+1 /* P_end_array */);
     return t[0] = P_mktuple(P_array, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<opt-sign> =
   case P_opt_sign:
     if (alt == 0)               {  //\\    "-",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_opt_sign, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_opt_sign, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<number> =
   case P_number:
     if (alt == 0)               {  //\\    <opt-sign> <float>,
       t[1] = compile(P(1), depth+1 /* P_opt_sign */);
       t[2] = compile(P(2), depth+1 /* P_float */);
       return t[0] = P_mktuple(P_number, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <opt-sign> <integer>;
       t[1] = compile(P(1), depth+1 /* P_opt_sign */);
       t[2] = compile(P(2), depth+1 /* P_integer */);
       return t[0] = P_mktuple(P_number, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<value> =
   case P_value:
     if (alt == 0)               {  //\\    "true",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_value, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "false",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_value, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    <array>,
       t[1] = compile(P(1), depth+1 /* P_array */);
       return t[0] = P_mktuple(P_value, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    <number>,
       t[1] = compile(P(1), depth+1 /* P_number */);
       return t[0] = P_mktuple(P_value, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 4)        {  //\\    <instruction>,
       t[1] = compile(P(1), depth+1 /* P_instruction */);
       return t[0] = P_mktuple(P_value, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 5)        {  //\\    <name>,
       t[1] = compile(P(1), depth+1 /* P_name */);
       return t[0] = P_mktuple(P_value, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <string>;
       t[1] = compile(P(1), depth+1 /* P_string */);
       return t[0] = P_mktuple(P_value, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<rest-of-value-list> =
   case P_rest_of_value_list:
     if (alt == 0)               {  //\\    <value-separator> <value> <rest-of-value-list>,
       t[1] = compile(P(1), depth+1 /* P_value_separator */);
       t[2] = compile(P(2), depth+1 /* P_value */);
       t[3] = compile(P(3), depth+1 /* P_rest_of_value_list */);
       return t[0] = P_mktuple(P_rest_of_value_list, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_rest_of_value_list, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<value-list> =
   case P_value_list:
     {                              //\\    <value> <rest-of-value-list>;
     t[1] = compile(P(1), depth+1 /* P_value */);
     t[2] = compile(P(2), depth+1 /* P_rest_of_value_list */);
     return t[0] = P_mktuple(P_value_list, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<quote> =
   case P_quote:
     {                              //\\    «"»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_quote, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<escaped-char> =
   case P_escaped_char:
     {                              //\\    «\.»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_escaped_char, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<char> =
   case P_char:
     {                              //\\    <!quote> «.»;
     t[1] = -1; /* ignore negative guard */;
     t[2] = wlit(P(2));
     return t[0] = P_mktuple(P_char, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<chars> =
   case P_chars:
     if (alt == 0)               {  //\\    <char> <chars>,
       t[1] = compile(P(1), depth+1 /* P_char */);
       t[2] = compile(P(2), depth+1 /* P_chars */);
       return t[0] = P_mktuple(P_chars, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_chars, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<string> =
   case P_string:
     {                              //\\    <quote> <chars> <quote>;
     t[1] = compile(P(1), depth+1 /* P_quote */);
     t[2] = compile(P(2), depth+1 /* P_chars */);
     t[3] = compile(P(3), depth+1 /* P_quote */);
     return t[0] = P_mktuple(P_string, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<name> =
   case P_name:
     {                              //\\    «[A-Za-z\$][A-Za-z0-9_]*»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_name, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<opt-exponent> =
   case P_opt_exponent:
     if (alt == 0)               {  //\\    «[Ee]» <opt-sign> <integer>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_opt_sign */);
       t[3] = compile(P(3), depth+1 /* P_integer */);
       return t[0] = P_mktuple(P_opt_exponent, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_opt_exponent, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<opt-integer> =
   case P_opt_integer:
     if (alt == 0)               {  //\\    <integer>,
       t[1] = compile(P(1), depth+1 /* P_integer */);
       return t[0] = P_mktuple(P_opt_integer, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_opt_integer, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<decimal-part> =
   case P_decimal_part:
     {                              //\\    «[0-9][0-9]*»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_decimal_part, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<float> =
   case P_float:
     {                              //\\    <opt-integer> «\.» <decimal-part> <opt-exponent>;
     t[1] = compile(P(1), depth+1 /* P_opt_integer */);
     t[2] = wlit(P(2));
     t[3] = compile(P(3), depth+1 /* P_decimal_part */);
     t[4] = compile(P(4), depth+1 /* P_opt_exponent */);
     return t[0] = P_mktuple(P_float, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<integer> =
   case P_integer:
     {                              //\\    «[0-9][0-9]*»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_integer, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<instruction-list> =
   case P_instruction_list:
     if (alt == 0)               {  //\\    <instruction> <instruction-list>,
       t[1] = compile(P(1), depth+1 /* P_instruction */);
       t[2] = compile(P(2), depth+1 /* P_instruction_list */);
       return t[0] = P_mktuple(P_instruction_list, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_instruction_list, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<opt-block> =
   case P_opt_block:
     if (alt == 0)               {  //\\    <begin-scope> <instruction-list> <end-scope>,
       t[1] = compile(P(1), depth+1 /* P_begin_scope */);
       t[2] = compile(P(2), depth+1 /* P_instruction_list */);
       t[3] = compile(P(3), depth+1 /* P_end_scope */);
       return t[0] = P_mktuple(P_opt_block, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <object-separator>;
       t[1] = compile(P(1), depth+1 /* P_object_separator */);
       return t[0] = P_mktuple(P_opt_block, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<argument> =
   case P_argument:
     if (alt == 0)               {  //\\    <name> <name-separator> <value>,
       t[1] = compile(P(1), depth+1 /* P_name */);
       t[2] = compile(P(2), depth+1 /* P_name_separator */);
       t[3] = compile(P(3), depth+1 /* P_value */);
       return t[0] = P_mktuple(P_argument, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <value>;
       t[1] = compile(P(1), depth+1 /* P_value */);
       return t[0] = P_mktuple(P_argument, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<rest-of-argument-list> =
   case P_rest_of_argument_list:
     if (alt == 0)               {  //\\    <value-separator> <argument> <rest-of-argument-list>,
       t[1] = compile(P(1), depth+1 /* P_value_separator */);
       t[2] = compile(P(2), depth+1 /* P_argument */);
       t[3] = compile(P(3), depth+1 /* P_rest_of_argument_list */);
       return t[0] = P_mktuple(P_rest_of_argument_list, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_rest_of_argument_list, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<opt-argument-list> =
   case P_opt_argument_list:
     if (alt == 0)               {  //\\    <argument> <rest-of-argument-list>,
       t[1] = compile(P(1), depth+1 /* P_argument */);
       t[2] = compile(P(2), depth+1 /* P_rest_of_argument_list */);
       return t[0] = P_mktuple(P_opt_argument_list, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_opt_argument_list, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<instruction> =
   case P_instruction:
     {                              //\\    <name> <begin-arguments> <opt-argument-list> <end-arguments> <opt-block>;
     t[1] = compile(P(1), depth+1 /* P_name */);
     t[2] = compile(P(2), depth+1 /* P_begin_arguments */);
     t[3] = compile(P(3), depth+1 /* P_opt_argument_list */);
     t[4] = compile(P(4), depth+1 /* P_end_arguments */);
     t[5] = compile(P(5), depth+1 /* P_opt_block */);
     return t[0] = P_mktuple(P_instruction, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<SS> =
   case P_SS:
     {                              //\\    <instruction-list> <EOF>;
     t[1] = compile(P(1), depth+1 /* P_instruction_list */);
     t[2] = wlit(P(2) /*, L"EOF" */);
     return t[0] = P_mktuple(P_SS, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ E
   default:
     fprintf(stderr, "Unandled P: Ph=0x%08x AST_type = %d  AST_index = %d  op=%d  alt=%d  count=%d\n", Ph, AST_type>>AST_type_shift, AST_index, op, alt, count);
     return r;
  }

#undef P
}
