home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
dev
/
oberon-a-1.4ß.lha
/
Oberon-A
/
texts
/
C2Oberon.txt
next >
Wrap
Text File
|
1994-05-28
|
18KB
|
420 lines
$RCSfile: C2Oberon.txt $
Description: Hints for converting C code into Oberon
Created by: fjc (Frank Copeland)
$Revision: 1.2 $
$Author: fjc $
$Date: 1994/05/13 19:26:48 $
Copyright © 1994, Frank Copeland.
This file is part of Oberon-A.
See Oberon-A.doc for conditions of use and distribution.
________________________________________________________________________
[This document is only partly complete (there was more, but DME ate it).
:-( It is here because what there is might still be useful. It will be
finished for a future release. FJC]
Introduction
------------
This document contains advice for translating source code written in C
into Oberon. It covers both simple syntax conversion and broader,
program organisation issues.
C and Oberon both belong to the same tradition of imperative, procedural
languages that trace their origins back to Algol in the late 1950's.
They are both general purpose languages and are sufficiently low-level
that they can be used as system-programming languages (C is more
conciously directed to this use). Where they mainly differ is in the
areas of modularity and type safety; Oberon is stronger in both these
areas.
In most cases the syntaxes are similar enough to allow a straightforward
translation from one language to the other. A text editor with a macro
facility can help simplify this task. Difficulties arise when
encountering constructs common in C which are missing in Oberon, such as
union types and unsigned integers. Other, more subtle difficulties may
arise as a result of C's less strict (often non-existant) type checking.
Finally, C's approach to modular programming is completely different to
Oberon's, and may require a complete restructuring of the source code.
Simple Data Types
-----------------
Simple data types are the basic building blocks of all data structures.
As they are determined by the underlying architecture common to almost
all modern computers, C and Oberon have a very similer range of basic
types. However, while the ANSI C standard specifies minimum sizes and
ranges for all of these types, Oberon leaves much more up to the
implementor. The equivalences given are those for Amiga C compilers and
the Oberon-A compiler.
The following table helps to explain the equivalences:
ANSI C Min. Size Oberon-A
------ --------- --------
char 1 byte When used to hold ASCII values, the equivalent
is CHAR; when used as a small integer, the
equivalent is SHORTINT.
unsigned char 1 byte When used to hold ASCII values, the equivalent
is CHAR; when used as a small integer, the
equivalent is BYTE. For BYTE see below.
short 2 bytes INTEGER.
int 2 bytes INTEGER or LONGINT. Some C compilers have
16-bit ints, others have 32-bit ints. For
16-bit ints, use INTEGER, otherwise use
LONGINT.
unsigned int 2 bytes No equivalent. See below.
long 4 bytes LONGINT.
unsigned long 4 bytes No equivalent. See below.
float 6 digits REAL.
double 10 digits LONGREAL.
long double 10 digits LONGREAL.
The BYTE type is strictly limited in Oberon (it is removed in Oberon-2).
It may be used to represent an unsigned byte-sized value (0-255), but
the only operation allowed is assignment. To perform arithmetic on BYTE
values, you must first assign them to INTEGER variables.
Oberon does not allow for unsigned integers apart from the limited BYTE
type. In many cases this is no problem since a signed integer can be
used instead without problems, although it may be necessary to use a
larger type (INTEGER instead of SHORTINT, for instance).
The main problem occurs when you must specify a type with the same
size as the unsigned type; this often occurs when declaring Oberon
equivalents for the Amiga system data structures. You cannot use a
larger type in this case; the system WILL crash if you do. Often the
operating system defines unsigned constants to be placed in these
variables with values that are larger than the maximum for a signed
integer of that size. These must be converted to negative values using
this formula:
<constant> - (<max value of unsigned type> + 1).
For example:
An unsigned int constant 0xFFFE or 65534 converts to:
(65534 - (65535 + 1)) = -2.
Often unsigned integers are used as bit fields, which are directly
equivalent to the Oberon SET type. An unsigned char bit field is
equivalent to the SYSTEM.BYTESET type; an unsigned int is equivalent to
the SYSTEM.WORDSET type; an unsigned long corresponds to the SET type.
If the exact size of the variable doesn't matter, use the SET type; the
other two types are unique to the Oberon-A implementation and are not
portable.
C has no direct equivalent to Oberon's BOOLEAN type, but ints are often
used for the same purpose. When they are, a value of zero equates to
FALSE and any other value equates to TRUE.
Oberon has no equivalent to C's enumerated data types, but they can be
simulated very easily using integer constants. For instance:
enum days = { Sun,Mon,Tues,Wed,Thurs,Fri,Sat };
becomes:
CONST
Sun = 0; Mon = 1; Tues = 2; Wed = 3;
Thurs = 4; Fri = 5; Sat = 6;
Constant values
---------------
Character literals in C are defined using single quotes: 'a', 'Z', etc.
String literals use double quotes: "This is a string". Oberon uses
double quotes for both. This can create an unexpected difficulty.
Oberon has no way of distinguishing a string literal with a single
character in it from a character literal except from the context in
which it is used. If the compiler does not contain special code to deal
with the anomaly, perfectly legal code may generate errors. (Oberon-A
now handles this anomaly).
String and character literals in C may contain escape sequences such as
'\n' and "\x5c". Oberon does not recognise escape sequences (but
Oberon-A does, as an extension; see OC.doc.) Character literals in
Oberon may be expressed as hexadecimal ASCII codes instead: '\n' becomes
0AX.
In C, any numeric literal starting with "0x" or "0X" is a hexadecimal
value. Upper and lower case characters can be used for the hexadecimal
digits. Oberon uses an "H" character at the end of the literal to
indicate a hexadecimal number and hex digits must be in upper case. A
number must start with a numeric character, the same as in C. Example:
"0xa5d3" becomes "0A5D3H". Any integer constant in C starting with "0"
(except for hex constants, obviously) is interpreted as an octal number.
Oberon has no equivalent for this and the constant must be converted
into its decimal or hexadecimal equivalent.
A "U" at the end of an integer constant indicates an unsigned number.
Oberon has no equivalent for this (see above). An "L" at the end of an
integer constant indicates that it has a long int type. This is
unnecessary in Oberon, which handles all the necessary type conversions
automagically.
Floating point constants are generally defined the same way in C and
Oberon, except that an exponent must be indicated with an uppercase "E"
in Oberon. C constants usually are of type double; Oberon defaults to
type REAL. To specify a LONGREAL constant, Oberon uses a "D" in the
exponent instead of an "E". C uses an "L" at the end of a floating
point constant to indicate it is a long double type; remove this when
converting to Oberon.
Bit field constants in C are usually defined in one of two ways. One is
to use the form: "(1<<bit)" or "(1L<<bit)". This is equivalent to
Oberon's: "{bit}". The other is to use a hex literal, such as:
"0xC801". The only way out here is to determine which bits are set in
the binary representation of the number, remembering that bits are
numbered st