home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / oxcc1433.zip / DOC / OXCC.TXT < prev    next >
Text File  |  1995-11-06  |  18KB  |  447 lines

  1. OXCC.TXT Version: 1.433 -- preliminary 5 Nov 1995 by Norman D. Culver
  2.  
  3.     OXCC is a multipass interpreting C compiler with numerous language
  4.     extensions (see c.grm).
  5.  
  6.     OXCC generates output in an Architecture Neutral Format (ANF).
  7.     Sample backends are provided to guide the programmer in dealing with
  8.     ANF and in writing additional backends for a specific purpose.
  9.  
  10.     The builtin interpreter provides for a great deal of flexibility
  11.     but it does make the compiler a memory hog. The entire file under
  12.     compilation is stored in memory as an Abstract Syntax Tree (AST).
  13.     The AST can be printed to stdout with the -a option.
  14.  
  15.     Language extensions have been inspired by GCC, MSC, and Watcom C.
  16.     OXCC is designed to produce 16 bit, 32 bit, 64 bit, segmented and 
  17.     flat model code for any target architecture and operating system.
  18.  
  19.     OXCC can regenerate C source code after interpreting some or all of 
  20.     its' input. Source regeneration properly handles `malloced' data
  21.     containing pointers. The regenerated source code can be `shrouded'.
  22.     Regenerated source files have the suffix .cr .
  23.  
  24.     The builtin interpreter can be run in fast or slow mode. Slow mode
  25.     maintains elaborate pointer and initialization information which
  26.     often is the only way to catch a subtle runtime bug.
  27.  
  28.     The compiler and include files are located in the file `oxcc.cff'. It
  29.     is run from the command line by the skeleton program `oxcc.exe'
  30.     (see skel.doc). If no switches are enabled, OXCC merely checks the
  31.     input file(s) for errors.
  32.  
  33.     OXCC is reentrant; a set of C calls and a set of class based calls
  34.     are provided. Multiple instances of OXCC can be run simultaneously.
  35.     A program being compiled by OXCC can run OXCC as a subroutine.
  36.     The program under compilation can gain access to the AST and
  37.     symbol tables which describe it by using the calls __builtin_iv() and
  38.     __builtin_root(). See: toxcc.c
  39.  
  40. Usage: oxcc [-adoqrstuwABDEFGHILMOPRSTWY(] file...
  41.    -a == print ast                   -s == print symbol table
  42.    -t == print runtimes              -u == print memory usage
  43.    -r == run the code                -f == if run code, go fast
  44.    -L == produce listing             -E == preprocess only
  45.    -S == shrouded source output      -T == trace lines while interpreting
  46.    -P == Parse only
  47.    "-(args for interpreted main" 
  48.    -dn == enable debug output, 1=parser 2=lexer 3=both
  49.    -q == suppress printing gratuitous info
  50.    -o outfile == name of output file, default is first infile
  51.    -A == ansi_mode (suppress extensions, not fully implemented)
  52.    -W == if run code and not fast mode, warn about address problems
  53.    -w == suppress compiler warnings
  54.    -R func == if run code, start at function `func'
  55.    -Ipath == include path for the C preprocessor
  56.    -Ddef == define something for the C preprocssor
  57.    -Gx == generate output in format `x' (abdnmrs)
  58.    -Ox == generate output for operating system `x' (dDwWCNoOUL)
  59.    -Hx == generate output for hardware type `x' (iIPDHmM)
  60.    -Bx == generate output for debugger `x' (vwbgd)
  61.    -Fx == generate object file format `x' (oOPWBace)
  62.    -Yx == generate assembler format `x' (ugmt)
  63.    -Mx == use memory model `x' (tsmlchx)
  64.  
  65. OUTPUT OPTIONS
  66.     -Gs   regenerate source (output file has .cr suffix)
  67.     -SGs  regenerate shrouded source (output file has .cr suffix)
  68.     -Gb   generate bytecodes (calls oxccb, output file has .byt suffix)
  69.     -LGb  generate bytecode listing (calls oxccb, output file has .lst suffix)
  70.     -Ga   generate assembler output (calls oxccaH, where H is hardware type)
  71.     -Gd   generate readable ANF code (output file has .dbg suffix)
  72.     -Gm   generate machine code (calls oxccmH, where H is hardware type)
  73.     -Gn   generate ANF code (output file has .anf suffix)
  74.     -Gr   generate RIP code (calls oxccr, output file has .rip suffix)
  75.  
  76.     (see oxanf.doc, oxanf.h)
  77.     -Ox   placed in header slot `target_os'         default `D' DOS32PLAT
  78.     -Hx   placed in header slot `target_hardware'   default `I' INTEL8632
  79.     -Bx   placed in header slot `target_debugger'   default  0  NONE
  80.     -Fx   placed in header slot `obj_format'        default `a' AOUTFORMAT
  81.     -Yx   placed in header slot `target_assembler'  default `g' GAS
  82.     -Mx   placed in header slot `memory_model'      default `x' MODFLAT
  83.  
  84.  
  85. INCOMPATIBILITIES
  86.  
  87.     FUNCTION DECLARATIONS
  88.     OXCC, being a multipass compiler, always chooses the `best' declaration
  89.     for a function. The old style practice of hiding function declarations
  90.     with a declaration containing an unknown number of args (commonly used
  91.     by some programmers) just will not work. At the very least you
  92.     will get a warning if a subroutine is called with arguments imcommensurate
  93.     with the `best' declaration. OXCC will not assume that the declaration
  94.     of an undeclared function `func' is `int func()', you must explicitly
  95.     declare all functions.
  96.  
  97.  
  98. LANGUAGE EXTENSIONS
  99.  
  100.     RUNTIME INTERPRETATION
  101.     The -r switch will cause OXCC to interpret the AST if it can find
  102.     a function named `main' or failing that a function with the base name
  103.     of the input file e.g. test32.c with a function named `test32'.
  104.     The user can specify a unique starting function with the -R switch.
  105.     Arguments can be passed to the starting function by using the -( switch
  106.     providing the starting function adheres to the argc, argv convention.
  107.     e.g.:
  108.        oxcc -r test32.c "-(23 hello 14 -W"
  109.     Another way to cause runtime interpretation is to call the starting
  110.     function from the right hand side of the last initialized outer variable.
  111.     The only restriction is that the starting function must return a value.
  112.  
  113.  
  114.     INTERPRETING OUTER DECLARATIONS INCLUDING INNER STATIC VARIABLES
  115.     OXCC evaluates (interprets) non-constant expressions in outer declarations.
  116.     Anything that can appear in a normal C program can contribute to the value
  117.     that is stored in an initialized variable. Uninitialized variables can 
  118.     become initialized as a side effect of a function call. Two reserved words
  119.     `_ival' and `_ifunc' can be prepended to variables and functions 
  120.     respectively in order to prevent them from appearing in the output.
  121.     e.g.:
  122.         double q = sin(2.0) / cos(4.3);
  123.         void *ptr = malloc(200);    // interpreted malloc acts like calloc
  124.         static int x,y;
  125.         _ifunc int initfunc()      // function `initfunc' will not be output
  126.         {
  127.         int i;
  128.             x = 50;    // static variable x is initialized to 50.
  129.             y = 25;    // static variable y is initialized to 25.
  130.             for(i = 0; i < x; ++i)
  131.                 ptr[i] = malloc(y);    // initialize the array of pointers
  132.             return 0;
  133.         }
  134.         int startfunc(int z)  // function `startfunc' will appear in output
  135.         {
  136.             x += z;        // static variable x is modified before output
  137.             ...
  138.             return 0;
  139.         }
  140.         _ival int z = initfunc();    // variable `z' will not be output
  141.         char *ary[20] = {[2]=ptr[3], [3]=malloc(x), [18]=malloc(y)};
  142.         _ival int dummy = startfunc(25); // variable `dummy' will not be output
  143.  
  144.  
  145.     AUTOMATIC VARIABLES (INNER DECLARATIONS)
  146.     Automatic variables can be initialized with non-constant expressions.
  147.     Static variables mentioned inside functions can be non-constant and
  148.     will be initialized at outer declaration time.
  149.     `alloca' is not a suitable initializer for a static variable inside
  150.     a function, use `malloc'.
  151.  
  152.  
  153.     DEFAULT ARGUMENTS FOR FUNCTIONS
  154.     Functions can be declared with default args, just use an `=' and fill
  155.     in the right hand side.
  156.     e.g.:
  157.         int func(int a = 3, struct _a b = {2.3,4,1}, char *cp = "hello")
  158.         {
  159.             ....    
  160.         }
  161.     Functions with default args can be called with 0 or more actual args.
  162.     They can also be called normally.
  163.     e.g.:
  164.         func(cp: "goodby"); // a and b will take the default values
  165.         func(3,B,ptr);      // a, b, and cp are fully specified
  166.         func(3);            // b and cp will take the default values
  167.         func();             // a, b, and cp take the default values
  168.  
  169.  
  170.     LABELED IDENTIFIERS FOR INITIALIZING ARRAYS AND STRUCTURES
  171.     This extension is inspired by GCC 2.6.x .
  172.     e.g.:
  173.         int array[200] = {[5]= 2, [123]= 45};
  174.         int array[20][50] = {[3][12]= 6, [18][23]= 8};
  175.         struct {
  176.           int x;
  177.           int y;
  178.           double q;
  179.           struct {
  180.             int a;
  181.             int b;
  182.           } bb;
  183.           struct {
  184.             int a;
  185.             int b;
  186.           } cc;
  187.         } aa = {.q=4.6, .cc={.b = 12}};  // everything else set to 0
  188.  
  189.  
  190.     COMPOUND EXPRESSIONS RETURN A VALUE
  191.     Place parenthesis around braces to create a compound expression
  192.     which consists of multiple statements and returns a value.
  193.     This extension is inspired by GCC.
  194.     e.g.:
  195.       int y = ({int i; 
  196.                  for(i=0; i<200;++i)
  197.                    if(i>x)
  198.                     break;
  199.                  i+x;    // mention variable to be returned
  200.                });  // y = i+x
  201.  
  202.  
  203.     NESTED FUNCTIONS
  204.     Nested functions are functions placed inside functions at
  205.     the location of automatic variables, i.e. before stmts following
  206.     a left brace. All of the automatic variables of the enclosing
  207.     function are within the scope of the nested function and do not
  208.     have to be passed as arguments when the nested function is called.
  209.  
  210.     OXCC implements flavor #1 of nested functions in which the stack
  211.     of the nested function coincides with the stack of the enclosing
  212.     function. This is the most efficient way to deal with nested functions
  213.     but precludes a nested function from being called recursively. The
  214.     address of a nested function can be taken and passed to a syncronous
  215.     callback. Asyncronous callbacks (such as might occur in an operating
  216.     system like WINDOWS) will not work. Nested functions can call other
  217.     nested functions which are within scope.
  218.  
  219.     Flavor #2 of nested functions requires that the nested function be
  220.     extracted from its' surroundings and given a stack of its' own. A
  221.     pointer to the stack frame of the enclosing function is passed invisibly
  222.     whenever the nested function is called. Callbacks are implemented with
  223.     thunks. This method produces a much slower nested function facility
  224.     but is usually necessary when generating machine language. Asyncronous
  225.     callbacks will not work.
  226.  
  227.  
  228.     TYPEOF, ALIGNOF
  229.     The type of an expression can be derived and applied wherever a normal
  230.     type would be used.
  231.     e.g.:
  232.         typeof(x) y;
  233.         typeof(*x) y;
  234.     The alignment of an expression can be obtained.
  235.     e.g.:
  236.         int x = __alignof__(y);
  237.  
  238.  
  239.     COMPUTED TYPEDEF
  240.     A typedef can be computed.
  241.     e.g.:
  242.         typedef XTYPE = x;
  243.         XTYPE q;
  244.  
  245.  
  246.     STRUCTURE ALIGNMENT AND PACKING
  247.     Structures can be designated as packed with the `_Packed' keyword.
  248.     OXCC also supports the awful __attribute__ constructions of GCC.
  249.     OXCC also supports various forms of the #pragma pack(n) directives
  250.     but it is strongly suggested that these not be used because source
  251.     regeneration does not handle pragma regeneration.
  252.    
  253.   
  254.     LOCAL LABELS
  255.     Each block is a scope in which local labels can be declared. The
  256.     value of the label goes out of scope with the block. This is handy
  257.     for macros. GCC inspired.
  258.     e.g.:
  259.       {
  260.           __label__ l1:            // declares l1 to be a local label
  261.             ...
  262.             goto l1;
  263.             ...
  264.         l1:
  265.       }
  266.  
  267.  
  268.     CASE RANGES
  269.     Case values may be expressed in the form:
  270.         case 2 ... 4:
  271.  
  272.  
  273.     ARITHMETIC ON VOID POINTERS
  274.     Pointers typed as void* are assumed to have the same size as char*
  275.     for the purpose of pointer arithmetic.
  276.  
  277.  
  278.     MACROS WITH VARIABLE NUMBERS OF ARGUMENTS
  279.     GCC inspired extension to the C preprocessor.
  280.     e.g.:
  281.         #define myprintf(format, args...) \
  282.         fprintf(stderr, format, ## args)
  283.  
  284.  
  285.     ZERO LENGTH ARRAYS
  286.     Arrays of zero length are allowed within structures.
  287.  
  288.  
  289.     CONDITIONALS WITH OMITTED OPERANDS
  290.     The construction x ? : y
  291.     is equivalent to x ? x : y 
  292.     except that x is not evaluated a second time.
  293.     
  294.  
  295.     DOUBLE WORD INTEGERS
  296.     The long long type is supported.
  297.  
  298.     LONG DOUBLE
  299.     The long double type is supported.
  300.  
  301.     FUNCTION TYPES
  302.     Various keywords from the segmented DOS world are understood by OXCC.
  303.     Currently OXCC does not do anything other than label the function
  304.     for later processing. (see c.grm)
  305.     
  306.  
  307.     SEGMENT INFORMATION
  308.     The keywords `__segdef__' and `__seguse__' are used to specify
  309.     segment info. The arguments to __segdef__ must be constant expressions.
  310.     This info is passed along to back end code generators.
  311.     e.g.:
  312.         __segdef__ DATA16 arg1, arg2, arg3;    // 0 to 3 args
  313.         __segdef__ DATA32 arg1, arg2, arg3;
  314.         __segdef__ TEXT16 arg1, arg2, arg3;
  315.  
  316.         __seguse__ DATA32;
  317.         int x,y,z;
  318.  
  319.         __seguse__ TEXT16;
  320.         int func()
  321.         {
  322.         }
  323.         __seguse__ TEXT32;
  324.         int func1()
  325.         {
  326.         }
  327.  
  328.  
  329.     BASED POINTERS
  330.     Microsoft C defines based pointers and segment variables, OXCC currently
  331.     parses and stores the information for later processing by back ends,
  332.     but it does not yet know how to interpret this stuff. It can correctly
  333.     regenerate source.
  334.  
  335.  
  336.     NEAR FAR HUGE POINTERS
  337.     Ditto as per Based pointers.(see c.grm)
  338.  
  339.  
  340.     ASSEMBLER INSTRUCTIONS
  341.     Various flavors of assembler code can be absorbed and regenerated by
  342.     OXCC. Interpretation is out of the question and assembler instructions
  343.     are not passed to back end code generators on the theory that portability
  344.     can never be achieved. The OXCC solution is to provide an extensible
  345.     facility for direct generation of ANF code. (see c.grm)
  346.  
  347.  
  348.     ANF INSTRUCTION BLOCKS
  349.     OXCC generates ANF code (see anf.doc, oxanf.h) from C instructions. The
  350.     programmer can generate ANF code by enclosing it in a block.
  351.     e.g.:
  352.         __anf__ {
  353.           mov x,y/2;        // divide y by 2 and store in x
  354.           lsh y,z,3;        // shift z left by 3 and store in y
  355.            ...
  356.         }
  357.     ANF blocks can be placed inside or outside of functions.
  358.     The basic set of ANF instructions can be extended by programmers to
  359.     achieve meaningful (I hope) methods of expressing concepts which
  360.     normally require assembler code. Essentially, ANF instructions consist
  361.     of an opcode followed by up to 3 arguments, the opcode set can be
  362.     extended by:
  363.        1. add new strings to oxanf.h
  364.        2. compile oxanf.h
  365.        3. insert in oxlib.cff with `cfar.exe' (see oxcc.mak)
  366.     ANF arguments can be any valid C expression and are evaluated by OXCC with
  367.     code generation where appropriate.
  368.  
  369.  
  370.     NO-NAME STRUCTURES/UNIONS
  371.     Inspired by Visual C++ 2.0
  372.     In order to compile 32 bit Windows programs it is necessary to deal with
  373.     un-named structures and unions which are members of named struct/unions.
  374.     This feature permits the programmer to reference the members of the
  375.     un-named struct/unions as if they were members of the enclosing named
  376.     container. Just make sure that all of the member names are unique.
  377.     Very nice idea.
  378.  
  379.  
  380. GLOBAL SUBROUTINES IN OXCC -- also callable by code being interpreted
  381.  
  382.     (see oxcc.h and toxcc.c)
  383.     void *__builtin_iv(void);
  384.     void *__builtin_root(void);
  385.     void *oxcc_get_pg(void *iv);
  386.     void oxcc_enable_trace(void *iv);
  387.     void oxcc_disable_trace(void *iv);
  388.     void oxcc_debug(void *iv, int bits);
  389.  
  390.     void oxcc_proc_ptr_info(void *iv, void (*func)());
  391.         func(void*,void*,void*,long);
  392.     void oxcc_proc_syms(void *iv, unsigned space, void (*func)());
  393.         func(AstP node, long symb, void *container);
  394.     void oxcc_proc_swtable(void*iv, void *swnode, void (*func)());
  395.         func(long swval, AstP root);
  396.     void oxcc_proc_mallocs(void *iv, void *func());
  397.         func(void *loc, int size, Item *ip);
  398.  
  399.     void *oxcc_open_instance(void);
  400.     void oxcc_set_options(void *iv, char *opts);
  401.     int oxcc_preproc_file(void *iv, void *is, void *os, void *es,
  402.                                            int argc, char **argv);
  403.     int oxcc_parse_file(void *iv, void *is, void *es, char *filename);
  404.     void oxcc_print_parse_errors(void *iv, void *es);
  405.     int oxcc_check_ast_tree(void *iv, void *es, char *filename);
  406.     int oxcc_init_outers(void *iv, void *es);
  407.     int oxcc_run_tree(void *iv, void *es, char *fnam, char *arg, char *startf);
  408.     int oxcc_gen_code(void *iv, void *es, char *filename, void *os);
  409.     void oxcc_cleanup_parse(void *iv);
  410.     void oxcc_close_codefile(void *iv);
  411.     void oxcc_close_instance(void *iv);
  412.  
  413.     void oxcc_print_ast(void *iv, void *os, int flag);
  414.     void *oxcc_get_ast_root(void *iv);
  415.     int oxcc_eval_expr(void *iv, void *buf, double *result, void *es);
  416.  
  417.     void gSetup(void *self, void *str);
  418.     int gPreProc(void *self, void *is, void *os, void *es,int argc,char **argv);
  419.     int gParse(void *self, void *is, void *es, char *filename);
  420.     void gPerror(void *self, void *es);
  421.     int gCheckTree(void *self, void *es, char *filename);
  422.     int gInitOuters(void *self, void *es);
  423.     int gRunCode(void *self, void *es, char *filename, char *args);
  424.     int gGenCode(void *self, void *es, void *os, char *filename);
  425.     void gCleanup(void *self);
  426.     void gCloseCode(void *self);
  427.     void gPrtAst(void *self, void *es, int flag);
  428.     void *gGetRoot(void *self);
  429.     int gEval(void *self, void *buf, double *result, void *es);
  430.  
  431.  
  432. TODO
  433.   1.  Improved optimization
  434.   2.  Inline functions
  435.   3.  Flavor #2 for nested functions
  436.   4.  Modify oxcc to be callable as a reentrant subroutine or class [DONE 25May]
  437.   5.  True interpretation of segmented code and 16 bit code.
  438.   6.  Interpret ANF instruction blocks.
  439.   7.  Support long double and complex data types. [long double DONE 5Nov]
  440.   8.  Write more back ends
  441.   9.  Better documentation
  442.   10. Better test program [test.bat for starters]
  443.   11. Add a new type `enumstring' to avoid parallel tables
  444.   12. Built in inheritance engine with COM, SOM, DCE compliance. [Coming up]
  445.   13. Generate Java,html,RIP code (need to juice up the grammar a bit)
  446.   14. Suggestions ??
  447.