-
Notifications
You must be signed in to change notification settings - Fork 2
O2C -- an Oberon-2 to GCC translator
License
pahihu/o2c
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
First the legal stuff: O2C -- an Oberon-2 to GCC translator Copyright (C) 1995 Michael van Acken, Juergen Zimmermann O2C is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. O2C is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with O2C; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Contents 0. Introduction 1. Including the GC Package 2. Emacs Mode 3. Notes on the Implementation 4. Interfacing to Other Languages Appendix: Man Pages =============================================================================== 0. Introduction o2c is an Oberon-2 (pre-)compiler. The source language is Oberon-2 as described in H. Moessenboeck, N. Wirth: The Programming Language Oberon-2; Institut fuer Computersysteme, ETH Zuerich, March 1995. o2c translates into a (GNU specific) version of C and calls gcc to create an executable from the intermediate C code. All calls to gcc are handled by o2c, you won't notice that the gcc is involved except for the delay in compilation time it causes. Translation process: Oberon-2 C Machine Code M.Mod -------> M.h, M.c -------> M.o (o2c) (gcc) It is possible to link programs with Hans-J. Boehm's conservative garbage collector. The primary site for o2c is ftp://ftp.uni-kl.de/pub/informatik/software/o2c-1.x.tar.gz This package contains 4 programs: o2c The compiler. o2b A symbol file browser. o2ef An error filter (if you don't use Emacs). o2whereis A tool to locate files (used by Emacs). Man pages for the commands and a Postscript file describing the internal data structures of the compiler can be found in the directory docs/; ASCII versions of the man pages are appended to this file. INSTALL describes how to install the programs on your system, how to add the Oberon-2 Mode to Emacs, and how to configure the compiler for the gc package. -------- NOTE: This package is no longer supported by its authors. There is no use in sending any bug reports. If you have problems with o2c you might try to switch to one of the compilers of the OOC project. Its home page is http://cognac.informatik.uni-kl.de/~oberon1/ooc/ooc_home.html OOC also includes an Oberon to C translator called oo2c. It's very similar to o2c, although it has several advantages: o it translates to ANSI-C o it generates more efficient C code o it uses autoconf to configure and install itself on a wide variety of Unix systems o it'll profit from future optimizations implemented as part of OOC. You can get oo2c here: ftp://cognac.informatik.uni-kl.de/pub/ooc/oo2c/ -------- 1. Including the GC Package The gc can be found (ftp) at parcftp.xerox.com in the directory pub/gc. This package implements a conservative garbage collector for standard C programs. `Conservative' means, that it'll consider every possible heap, stack, or register location as a pointer, regardless of the semantics that was associated with this location by the compiler. This has to be compared to the gc implemented in the ETH Oberon systems, where the compiler passes information about possible pointer locations to the run time system. The conservative approach needs more time to do its collection, and it may keep objects that could be freed if they are `referenced' by some data that isn't actually a pointer. It may be slow and not 100% effective, but it's the only way to implement a gc for C programs. When installing gc you have the option to set ALL_INTERIOR_POINTERS, or not. If set, all pointers to the interior of a memory block are considered valid, and they'll keep the block alive (i.e., it won't be freed by the gc). This has the disadvantage that some byte patterns, that are considered by gc as potential references into an object, keep the object alive although it could be collected. Without ALL_INTERIOR_POINTERS, only pointers to the offsets 0, 4, 8, 12, and 16 (this is set in file _OGCC.c, function _init__OGCC()) into a memory block are considered valid, i.e. as legal references to this block. This increases the probability of an object of being collected, and may increase the gc's performance. The disadvantage is, that open arrays on the heap are limited to a maximum of 4 (open) dimensions (this can be increased by modifying _init__OGCC()). The procedure NEW will allocate a memory block as `atomic' (i.e., call GC_malloc_atomic), if the variable's type doesn't contain any pointers (type tags don't count as such). During a garbage collection such blocks are not searched for potential references to other objects. This decreases the time for collections, and decreases the possibility for pseudo-references to keep other objects alive. That way large character arrays or huge numerical matrices won't have a negative impact on the gc's performance. The predefined constant SYSTEM.GC is TRUE, if the program was compiled with support for gc. The predefined procedure SYSTEM.COLLECT can be used to explicitly start a garbage collection (usually calls to to NEW will trigger a collection if the current heap size is exhausted). A word of warning: It's a bad idea to mix object files that where compiled for gc with files that where not. If an object was allocated under gc control, and is only kept alive by references from objects that weren't allocated under gc control, the gc will consider the object as unreachable and may deallocate it. This would invalidate all exisiting references to this object, causing nasty (and untraceable) data corruption. Therefor the options --usegc and --nogc should be used with caution, better stick to the default setting compiled into the compiler. 2. Emacs Mode This compiler comes with a major mode for the FSF GNU Emacs to manage Oberon-2 source code. It can make the task of writing an Oberon-2 program considerably easier. See INSTALL on how to get this mode installed. The oberon2.el package provides functions to - insert Oberon-2 syntactic structures - selectively display lines of source code - locate Oberon-2 files and declarations - support the compilation of programs and to locate errors. Emacs will interpret error messages generated by the compiler and automatically place the cursor at the error position. If you put an assignment like (setq o2-cwd (expand-file-name "dir")) in your ~/.emacs file, the compiler and the browser will be executed in the directory dir. dir has to be an absolute path, i.e. something like /usr/home/doop/ or ~/o2c/. Without this setq Emacs will use the current working directory on startup to execute o2c and o2b commands. The following text is a copy of the major mode help you'll get under Emacs with 'C-h m', provided your buffer has activated the Oberon-2 Mode. The mode can be activated manually by pressing 'M-x oberon-2-mode'. See INSTALL on how to set up Emacs to put the buffer of each file ending in '.Mod' into this mode. "Oberon-2 mode: Major mode for editing Oberon-2 code. Indentation: RET make a newline, but indent like previous line TAB indent for o2-indent spaces DEL convert tabs to spaces while moving backward C-c TAB add/remove indentation level(s) to region The variable o2-ident determines how much spaces are inserted per indentation level (default 2). Inserting Oberon-2 constructs: C-c m MODULE outline C-c p PROCEDURE outline C-c t typebound PROCEDURE outline C-c C-t redefinition of typebound PROCEDURE C-c i IF THEN statement C-c C-e insert ELSIF C-c c CASE statement C-c C-w WITH statement C-c e insert ELSE C-c b insert a '|' C-c f FOR statement C-c w WHILE statement C-c r REPEAT UNTIL statement C-c l LOOP statement C-c C-r RECORD constructor C-c h comment with various information about the module Move by procedure headings: C-c C-n move to next procedure C-c C-p move to previous procedure C-c C-u move to procedure, to which the present one is local M-C-h put mark at end of procedure, point at the beginning Functions to hide procedure bodies and declarations: C-c C-h hide whole procedure C-c C-s show whole procedure again C-c C-l hide bodies of all local procedures M-x o2-hide-proc hide local declarations and the body M-x o2-show-proc show local declarations and body again M-x o2-hide-all hide all of buffer except procedure headings M-x o2-show-all make all text in the buffer visible again Managing source code: C-c C-f find file to a given module name C-c 4 f like C-c C-f, but display in another window C-c 5 f like C-c C-f, but display in another frame C-c C-d generate and display the definition of a module C-c 4 d like C-c C-d, but display in another window C-c 5 d like C-c C-d, but display in another frame C-c . display (same window) the definition of an identifier C-c 4 . display (other window) the definition of an identifier C-c 5 . display (other frame) the definition of an identifier C-c / display & blink to declaration of ident under cursor C-c , display (same window) a procedure bound to a given type C-c 4 , display (other window) a procedure bound to a given type C-c 5 , display (other frame) a procedure bound to a given type All the above functions accept a module's alias name (as declared in the current buffers IMPORT list) instead of the real module name. For further information on 'C-c .' or 'C-c ,' use C-h k. Any of the above functions that displays files in another window or frame won't change the selected window if the `C-u' prefix is set. Example: `C-u C-c 4 .' will display the source of the definition of the given identifier in another window, but the current window stays selected and point stays at the current position. `S-mouse-3' (ie, shift with right mouse button) will, similar to `C-c /', invoke `C-u C-c 4 .' with the qualified identifier under the mouse cursor as argument and blink to the found position. Compiling: M-c compile current buffer C-u M-c prompt for compile command and compile current buffer M-C-c run a make on a module C-c ' display the next error C-c g prompt for module and error position, goto position Searches will distinct cases. Delete converts tabs to spaces as it moves back. Emacs won't use tab characters. M-; will indent or create a comment on the current line at column 41 (default). The Oberon-2 menu can also be invoked with `C-mouse-3' (ie, control with right mouse button) under GNU Emacs 19.29." 3. Notes on the Implementation The compiler itself is written in subset of Oberon-2, fairly similar to Modula-2. To distribute the compiler, it is called on itself to produce the required C sources and makefiles. The generated C code makes use of the following GNU C extensions: - nested functions, to simplify translation of Oberon-2 nested procedures - expression statements, to allow simple macros - alloca, to hold copies of value ARRAY parameters on the stack The front end is strictly seperated from the back end. It generates a description of the compiled program in form of an internal data structure (which is discribed in docs/Internal.ps). This is passed to the back end to generate the desired translation. The compiler deviates from the ETH compilers in the following points: - the SYSTEM procedures GETREG, PUTREG, and CC are disabled - SIZE(T), where T is a RECORD or ARRAY type, can't be used as part of a constant expression - the rounding behaviour of ENTIER is undefined (it depends on the C type cast operator and I don't know if and how its rounding is defined) - it won't do garbage collection unless you have Hans-J. Boehm's conservative garbage collector installed and told the compiler to make use of it (see section 1 resp. INSTALL) - there is a new prefined procedure SYSTEM.DISPOSE: DISPOSE(v), where v is a pointer to ARRAY or RECORD and v has been allocated storage to with NEW(v) or NEW(v, n0, n1, ..). DISPOSE deallocates the storage block whose address is stored in v and sets v to NIL. DISPOSE will also free memory allocated to v by SYSTEM.NEW if (and only if) v is of type SYSTEM.PTR. - new predefined constant SYSTEM.GC; it's TRUE if the program was compiled with gc support - new predefined procedure SYSTEM.COLLECT; runs an explicit garbage collection (normally this happens implicit if NEW runs out of memory). This is a noop if no gc support is included. - delayed loading of modules is impossible, the only similarity to the Oberon System's command mechanism is the possibility to declare an exported parameterless procedure as the program's entry point when running a make 4. Interfacing to Other Languages 4.1 External Modules External modules allow to link arbitrary libraries to an Oberon-2 program. They are similar to C header files: they contain descriptions of data types, variables and procedures exported by libraries. Note: These modules have to be considered as unsafe, low-level, and system (or rather compiler) dependent. Their syntax follows (in part) the one suggested in the Oakwood Guidelines. The syntax differs from the one in the Oberon-2 report in the following rules (an example can be found at the end of this chapter): Module = "MODULE" ident "[" <convention> "]" "EXTERNAL" "[" <externalLibrayName> "]" ";" [ImportList] DeclSeq "END" ident ".". ExtIdentDef = IdentDef [ "[" <externalName> "]" ]. ExtIdentList = ExtIdentDef {"," ExtIdentDef}. VarDecl = ExtIdentList ":" Type. ProcDecl = "PROCEDURE" ExtIdentDef [FormalPars]. <convention> denotes a calling convention, e.g. "C", "Pascal", "Modula-2". Any other convention than "C" will cause a warning. <externalLibraryName> is the name of the external library that has to be included by the external module. A name ending in .c will include a C source file, .o will include an object file, .a will include an archive file, an empty string will be ignored and all other strings will cause the library of that name to be linked to the executable. <externalName> allows to set explicitly the name under which variables or procedures are accessed in the generated code. If an external module M declares a PROCEDURE X ["Y"];, then the procedure is called in Oberon-2 by writing M.X and the compiler will translate it into a call to the C function Y. The following points differ from normal modules: - The underscore '_' is treated as a character and can be part of an identifier (but can't appear in the module name). - No statements are allowed in an EXTERNAL module. There is no BEGIN part, no declartions local to procedures and there are no type bound procedures. - The last formal parameter of a procedure can be '..'. It stands for an arbitrary number of parameters. This allows to define and use functions like printf (see Unix.Mod). - The keyword RECORD may optionally be followed by '[UNION]'. Such types will be translated into the C type 'union'. - The rule for matching parameter lists is extended as follows: Two formal parameter lists match if additionally holds: a) they don't contain open arrays or VAR records whose types are defined in normal modules, or b) both parameter lists are declared inside or both are declared outside of an EXTERNAL module - For each EXTERNAL module M.Mod including the external file "xyz.c" this file has to define the function 'void _init_M(void)'. This function will be called as part of the module initialization. 4.2 External Types Types defined, i.e. constructed, in an external module differ somewhat from the ones defined in an Oberon-2 module, since such types need to be mapped to C types. These types are implemented differently from the normal types, and different rules of type compability apply to them. Please note that an external type has be be constructed in an EXTERNAL module: Only structured types like pointer, record, array or procedure types can be external, and a simple type alias 'TYPE A=B;' will only transfer the external status of B to A. External Records They can't be extended and can't be an extension themselfes and they don't have a type descriptor, so a) they can't be part of type tests or type guards b) type bound procedures cannot be defined on them c) VAR parameters of this type are not passed together with a type tag d) pointer to this types don't have a type tag It is possible to declare C-like union types be placing '[UNION]' after the RECORD keyword. External Open Arrays No length information is stored for them, so a) the LEN function cannot be applied to them b) parameters of this type are not passed together with length info c) pointer to this type are not stored with length info d) when passing an external ARRAY OF T to a formal Oberon-2 parameter of type ARRAY OF T, the parameter's array length is set to MAX(LONGINT) and a warning is emitted An open array can't be element type of an external open array, i.e. multi- dimensional open arrays are not allowed. External Pointers Integer values can be assigned to such pointers, i.e. the result of a call to SYSTEM.ADR can be passed directly to them. NEW and SYSTEM.DISPOSE are not applicable on EXTERNAL pointers, or on pointers whose base type is EXTERNAL. External Procedures The calling convention differs from the one for normal procedures: a) no type decriptors are passed for formal VAR record parameters b) no length information is passed together with open array parameters The special parameter '..' is allowed to denote arbitrary actual parameters. 4.3 Linking Order of Libraries If you want to include two libraries liba and libb, where libb depends on liba, you'll have to write two external modules and the module for libb has to import the one for liba directly. This will ensure that "-llibb" will be placed before "-lliba" in the linker option list. Example: MODULE X11 ["C"] EXTERNAL ["X11"]; TYPE DisplayPtr* = POINTER TO Display; Display* = RECORD ... END; ... END X11; MODULE Xmu ["C"] EXTERNAL ["Xmu"]; IMPORT X11 (*necessary!*); ... END Xmu. This way the linker will be called with "-lXmu -lX11". For further examples see Unix.Mod, MathL.Mod, and Types.Mod (all in directory lib/). Authors Michael van Acken, Juergen Zimmermann Universitaet Kaiserlautern Appendix: Man Pages o2c(1) o2c(1) NAME o2c - Oberon-2 to C compiler SYNOPSIS o2c [option]... filename o2c [ -M|--make] [option]... module [command] DESCRIPTION o2c has two major modes of operation: compile and make. compile No option -M or --make is set. Translates one or more files into C code. This is quite fast since no object files are generated, useful to check a given module for syntactic or semantic errors. Example: o2c Hello.Mod compiles the module Hello. If no errors are found, the files Hello.c, Hello.OSym, and Hello.h are generated (the latter two only if the symbol file has changed). make Option -M or --make is set. All modules imported directly or indirectly by a given main module are recompiled if necessary, including compilation into .o files. In a final step the object files are linked together to form an exe- cutable. Example: o2c -M Hello World generates the executable file Hello_World. World is the name of a parameter- less procedure exported by module Hello. It's called right after the module initialization. In the terminology of the Oberon System it would be a command. o2c -M o2c generates the executable o2c. Since the startup code of module o2c doesn't termi- nate, no special command has to be executed. Errors are reported like this: In file lib/Hello.Mod: 14:139 ';' expected The first number is the error's position in the source code, i.e. file lib/Hello.Mod. It's a character position, not a line number. After the colon follow the error num- ber and the error message. If you prefer a different out- put format, e.g. if you'ld like to read error messages in the source text context, use the filter o2ef (see also o2ef(1)). o2c uses the following suffixes for its input and output files: .Mod Oberon-2 source .OSym symbol file .c intermediate C code 1 o2c(1) o2c(1) .h intermediate header file .o object file, generated by gcc The file ~/.o2c.red tells the compiler where to search for existing files and where to create new files, depending on their suffix. The file is a list of rules of the form pattern {"," pattern} = path {";" path} [+RCS]. pattern is a string of characters that may contain ? to match a single arbitrary character and * to match zero or more characters. E.g. *.Mod would match all files ending in .Mod. To locate a file file the path lists of the patterns matching file are searched from left to right. The first path containing the file file is used. If +RCS is set for a source file M.Mod, RCS files RCS/M.Mod,v or M.Mod,v will be found in addition to the perfect match M.Mod. The com- piler will automatically retrieve the working file M.Mod by calling co and will use it as input file. For files generated by the compiler (e.g. symbol files or C code) the first path in the list associated with the first matching pattern will be used to store the file. If file paths stored in ~/.o2c.red are relative to a directory, the compiler (and the browser) must be executed in this directory. Otherwise the compiler will complain about files not found. OPTIONS Single character options may be grouped together. -MA is equivalent to -M -A or --make --all. --make, -M Make an executable. The main module and all mod- ules it depends on are checked for consistency and are recompiled if necessary. gcc is called to gen- erate the object files and to build an executable. --all, -A Force (re-)compilation of all imported modules. Ignored unless --make is set. --file, -F Write a makefile for the given module into file Makefile. No compilation will be done. Ignored unless --make is set. --warn, -W Print additional warnings. Without this option only errors will be reported. --redir <file> Use <file> as redirection table (instead of the default ~/.o2c.red). 2 o2c(1) o2c(1) --help, -h Give a summary on how to call the compiler. --version, -V Print compiler version. --verbose, -v Print calls to co or gcc and recompilation steps. Useful in connection with --make. -a Disable assertions. Any calls to the predefined function ASSERT will be ignored. -R Normally the compiler will produce code to detect the following illegal program states: - a function is left without a return statement - a CASE expression does not match any label - a NIL pointer is being dereferenced - an array index is out of range - a SET index is out of range - RECORD assigment fails - a type guard or test is applied to a NIL pointer - a type guard fails - all guards of a WITH statement fail The option -R will disable all those checks. Note: These checks are fairly expensive, since all of them are performed on C level. -O Optimize code, i.e. set -O2 when calling gcc. --usegc Include support for gc package. This overrides the compiler's default setting. o2c has to be compiled with the correct path to the gc library. Note: It's dangerous to mix .o files that are compiled for gc with ones that are not. --nogc Disable support for gc package. This overrides the compiler's default setting. Note: It's dangerous to mix .o files that aren't compiled for gc with ones that are. -g Include debug information on C level, i.e. set -g3 when calling gcc. -s Strip executable. Don't use this together with -g since -s will cancel the effects of -g. -p Include profiler information (for gprof). --cflags <string> Pass <string> as parameter(s) to the C compiler. 3 o2c(1) o2c(1) --ldflags <string> Pass <string> as parameter(s) to the linker. The options -a, -R, -O, -g, -s, -p, --cflags, and --ldflags will only take effect during a make, in particu- lar only for those files that are compiled by gcc while these options are set. If you want to make sure that these options are in effect for all modules, use the options --make --all, or -MA for short, to recompile all modules. FILES ~/.o2c.red path list ErrorList.txt error messages file.Mod Oberon-2 source file file.OSym symbol file file.c intermediate C file file.h intermediate header file file.o object file file.m stores time of last compilation of EXTERNAL DIAGNOSTICS The exit status is non zero if and only if an error occured during compilation. SEE ALSO o2b(1), o2ef(1), o2whereis(1) AUTHORS Michael van Acken, Juergen Zimmermann 4 o2b(1) o2b(1) NAME o2b - Symbol file browser SYNOPSIS o2b [option]... module DESCRIPTION o2b reconstructs a printable representation from a mod- ule's symbol file. The output is similar to Modula-2 def- inition files. OPTIONS --expand, -x Expand extended records. Print for each record type its base types, which fields were inherited from them, and what type bound procedures were (re-)defined. --external, -e Print external names. For external modules the calling convention, the external library name, and (if they differ from the Oberon-2 names) external names for variables and procedures are displayed. --help, -h Give a summray on how to call o2b. --version, -V Print browser version. --redir <file> Use <file> as redirection table (instead of the default ~/.o2c.red). FILES ~/.o2c.red path list file.OSym symbol file SEE ALSO o2c(1), o2ef(1), o2whereis(1) AUTHORS Michael van Acken, Juergen Zimmermann 1 o2ef(1) o2ef(1) NAME o2ef - Filter for error messages generated by o2c SYNOPSIS o2c ... | o2ef [-c|-l|-L] DESCRIPTION o2ef filters error messages generated by o2c and trans- forms them into another textual representation. This is only intended as a help for those who either can't use the Oberon-2 Emacs mode (that's regrettable) or who don't want to use Emacs (a grave mistake). o2ef reads the errors emitted by o2c from stdin and writes them to stdout in a new format, e.g. like a C compiler's errors. OPTIONS -c Print errors in source text context (default). Each line of source code containing an error is printed with a few lines of leading and trailing lines. The error position is marked, followed by the error text. -l Print errors in the format file:line:error. This is the format used by gcc to describe errors. Only the line number containing the error is printed, the exact error position is lost. Many error mes- sages will lose a lot of their usefulness since the exact error position carries a great deal of infor- mation. Rather use -L instead. -L Print errors in the format file:line,column:error. SEE ALSO o2c(1), o2b(1), o2whereis(1) AUTHORS Michael van Acken, Juergen Zimmermann 1 o2whereis(1) o2whereis(1) NAME o2whereis - locate files used or generated by o2c SYNOPSIS o2whereis [-r] file DESCRIPTION o2whereis searches the paths given in ~/.o2c.red for the file file. How the search is done is described in o2c(1). The full path of the first file found is printed to std- out. o2whereis is used by the Oberon-2 Emacs mode to locate source and symbol files. OPTIONS -r If just a RCS file is found, print the full path of the RCS file. The default is to print the name of the associated working file. --redir <file> Use <file> as redirection table (instead of the default ~/.o2c.red). FILES ~/.o2c.red path list SEE ALSO o2c(1), o2b(1), o2ef(1) AUTHORS Michael van Acken, Juergen Zimmermann 1
About
O2C -- an Oberon-2 to GCC translator
Topics
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published