home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
CENVIW1.ZIP
/
CMM_VS_C.DOC
< prev
next >
Wrap
Text File
|
1993-08-10
|
21KB
|
477 lines
CEnvi Shareware Manual, Chapter 3:
Cmm versus C, for C Programmers
CEnvi unregistered version 1.0
9 AUGUST 1993
CEnvi Shareware User's Manual
Copyright 1993, Nombas, All Rights Reserved.
Published by Nombas, P.O. Box 875, Medford, MA 02155 USA
(617)391-6595, (617)391-5289
Thank you for trying this shareware version of CEnvi from Nombas.
3. Cmm versus C: The Cmm language for C programmers
This chapter is for those who already know how to program in the
C language. This chapter describes only those elements of Cmm
that differ from standard C, and so if you don't already
understand C, then this shouldn't have much meaning for you.
Non-C programmers should instead look at the previous chapter.
Since it is assumed that readers of this chapter are already
knowledgeable in C, only those aspects of Cmm that differ from C
are described here. If it's not mentioned here, then assume that
Cmm behavior will be standard C.
Deviations from C are a result of these two harmonious Cmm
directives: Convenience and Safety. Cmm is different from C
where the change makes Cmm more convenient for small programs,
command-line code, or scripting files, or if unaltered C rules
encourage coding that is potentially unsafe.
3.1. C Minus Minus
Cmm is "C minus minus" where the minuses are Type Declarations
and Pointers. If you already know C and can remember to forget
these two aspects of C (I repeat, no Type Declarations and no
Pointers) then you know Cmm. If you were to take C code, and
delete all the lines, code-words, and symbols that either declare
data types or explicitly point to data, then you would be left
with Cmm code; and although you would be removing bytes of source
code, you would not be removing capabilities.
All of the details below that compare Cmm against C follow from
the general rule:
*Cmm is C minus Type Declarations and minus Pointers.
3.2. Data Types
The only recognized data types are Float, Long, and Byte. The
words "Float", "Long", and "Byte" do not appear in Cmm source
code; instead, the data types are determined by context. For
instance 6 is a Long, 6.6 is a Float, and '6' is a Byte. Byte is
unsigned, and the other types are signed.
3.3. Automatic Type Declaration
There are no type declarators and no type casting. Types are
determined from context. If the code says "i=6" then i is a
Long, unless a previous statement has indicated otherwise.
For instance, this C code:
int Max(int a,int b)
{
int result;
result = ( a < b ) ? b : a ;
return result;
}
could become this Cmm code:
Max(a,b)
{
result = ( a < b ) ? b : a ;
return result;
}
3.4. Array Representation
Arrays are used in Cmm much like they are in C, except that they
are stored differently: a first-order array (e.g., a string) is
stored in consecutive bytes in memory, but arrays of arrays are
not in consecutive memory locations. The C declaration "char
c[3][3];" would state that there are sixteen consecutive bytes in
memory. In Cmm a similar statement such as "c[2][2] = 'A'" would
tell you that there are (at least) three arrays of characters,
and the third array of arrays has (at least) three characters in
it; and although the characters in c[0] are in consecutive bytes,
and the characters in c[1] are in consecutive bytes, the two
arrays c[0] and c[1] are not necessarily adjacent in memory.
3.4.1 Array Arithmetic
When one array is assigned to the other, as in:
foo = "cat";
goo = foo;
then both variables define the same array and start at the same
offset 0. In this case, if foo[2] is changed then you will find
that goo[2] has also been changed.
Integer addition and subtraction can also be performed on arrays.
Array addition or subtraction sets where the array is based. By
altering the previous code segment to:
foo = "cat";
goo = foo + 1;
goo and foo would now be arrays containing the same data, except
that now goo is based one element further, and foo[2] is now the
same data as goo[1].
To demonstrate:
foo = "cat"; // foo[0] is 'c', foo[1] = 'a'
goo = foo + 1;// goo[0] is 'a', goo[-1] = 'c'
goo[0] = 'u'; // goo[0] is 'u', foo[1] = 'u', foo is "cut"
goo++; // goo[0] is 't', goo[-2] = 'c'
goo[-2] = 'b' // goo[0] is 't', foo[0] = 'b', foo is "but"
3.4.2 Automatic Array Allocation
Arrays are dynamic, and any index, (positive or negative) into an
array is always valid. If an element of an array is referred to,
then the Cmm must see to it that such an element will exist. For
instance if the first statement in the Cmm source code is "foo[4]
= 7;" then the Cmm interpreter will make an array of 5 integers
referred to by the variable foo. If a statement further on
refers to "foo[6]" then the Cmm interpreter will grow foo, if it
has to, to ensure that the element foo[6] exists. This works
with negative indices as well. When you refer to foo[-10], then
foo is grown in the other direction if it needs to be, but foo[4]
will still refer to that "7" you put there earlier. Arrays can
reach any dimension order, so that foo[6][7][34][-1][4] is a
valid.
3.5. Structures
Structures are created dynamically, and their elements are not
necessarily contiguous in memory. When CEnvi comes across the
statement 'foo.animal = "dog"' it creates a structure element of
foo that is referred to as "animal" and is an array of
characters, and this "animal" variable is thereafter carried
around with "foo" (much like a stem variable in REXX). The
resulting code looks very much like regular C code, except that
there is not a separate structure definition anywhere.
This C code:
struct Point {
int Row;
int Column;
};
struct Square {
struct Point BottomLeft;
struct Point TopRight;
};
void main()
{
struct Square sq;
int Area;
sq.BottomLeft.Row = 1;
sq.BottomLeft.Column = 15;
sq.TopRight.Row = 82;
sq.TopRight.Column = 120;
Area = AreaOfASquare(sq);
}
int AreaOfASquare(struct Square s)
{
int width, height;
width = s.TopRight.Column - s.BottomLeft.Column + 1;
height = s.TopRight.Row - s.BottomLeft.Row + 1;
return( length * height );
}
can be changed into the equivalent Cmm code simply be removing
declaration lines, resulting in:
main()
{
sq.BottomLeft.Row = 1;
sq.BottomLeft.Column = 15;
sq.TopRight.Row = 82;
sq.TopRight.Column = 120;
Area = AreaOfASquare(sq);
}
int AreaOfASquare(s)
{
width = s.TopRight.Column - s.BottomLeft.Column + 1;
height = s.TopRight.Row - s.BottomLeft.Row + 1;
return( length * height );
}
Structures can be passed, returned, and modified just as any
other variable. Of course structures and arrays are independent,
so you could very well have the statement "foo[8].animal.forge[3]
= bil.bo".
3.6. Passing Variables by Reference
By default, LValues in Cmm are passed to functions by reference,
and so if the function alters a variable then the variable in the
calling function is altered as well IF IT IS AN LVALUE. So
instead of this C code:
main() {
.
.
.
CQuadrupleInPlace(&i);
.
.
.
}
void CQuadrupleInPlace(int *j)
{
*j *= 4;
}
the Cmm version would be:
main() {
.
.
.
QuadrupleInPlace(i);
.
.
.
}
void QuadrupleInPlace((j)
{
j *= 4;
}
If the rare circumstance arises that you want to pass a copy of
an LValue to a function, instead of passing the variable by
reference, then you can use the Cmm "copy-of" operator "=".
foo(=i) can be interpreted as saying "pass a value equal to i,
but not i itself"; so that "foo(=i) ... foo(j) { j *= 4; }" would
not change the value at i.
Note that for this Cmm version, the following calls to
QuadrupleInPlace() would be valid, but no value will have changed
upon return from QuadrupleInPlace() because an LValue is not
being passed:
QuadrupleInPlace(8);
QuadrupleInPlace(i+1);
QuadrupleInPlace(=1);
3.7. Data Pointers(*) and Addresses(&)
No pointers. None. The "*" symbol NEVER means "pointer" and the
"&" symbol never means "address". This may at first cause
seasoned C programmers to gasp in disbelief, but it turns out to
be not such a big deal, and these two operators are seldom
missed, after considering these two rules:
1) "*var" can be replaced in all instances by "var[0]"
2) variables (if LValues) are passed by reference
3.8. Case Statements
Case statements in a switch statement may be a constant, a
variable, or any other statement that can be evaluated to a
variable. So you might see this Cmm code:
switch(i) {
case 4:
case foe():
case sqrt(foe()):
case (PILLBOX * 3 - 2):
default:
}
3.9. Initialization: Code external to functions
All code that is not inside any function block is interpreted
before main() is called. So the following Cmm code:
printf("hey there ");
main()
{
printf("ho there ");
}
printf("hi there ");
would result in the output "hey there hi there ho there ".
3.10. Unnecessary tokens
If symbols are redundant, then they are usually unnecessary in
Cmm. This allows for more flexibility in the non-C-trained and
also lets more code get in the tiny space available on the
command line. Besides, I got tired of my compiler saying
"missing semi-colon"; What good is a semi-colon if it doesn't
tell the compiler anything new? So you can have the statement
"foo()" as well as "foo();". It certainly doesn't hurt to have
the semi-colon there, especially when it can clarify a "return;"
statement, for example, but it isn't necessary. Similarly, "("
and ")" are often unnecessary, so you may have "while a < b a++"
as a complete statement.
3.11. #include
The #include statement has been enhanced for reading source
snippets from within other types of files. So we have
#Include <filespec,Extension,Prefix,HeaderLine,FooterLine>
where filespec is the same as in C's #include <filespec>
statement, Extension is a file extension (such as BAT) that may
be added to the filespec (so batch files can say #include
<%0,bat>", Prefix specifies that only those lines in filespec
that begin with Prefix will be source, and HeaderLine and
FooterLine specify that source will be read only from sections of
filespec between HeaderLine and FooterLine. If a full path is
not specified then CEnvi searches for the file in various paths
in this order:
*Search the current directory.
*If the code is run from a *.cmm source file, then search in
the source directory for the *.cmm file.
*If this is the Windows version of CEnvi, searches all the
files in the CMMPATH profile value (from WIN.INI in the
[CEnvi] section).
*Search all directories in the CMMPATH environment variable.
*Search the directory that CEnvi.exe is executed from.
*Search all directories from the PATH environment variable.
3.12. Macros
Function macros are not supported. Since speed is not of primary
importance, a macro gains little over a function call, and so any
macros may simply become functions.
Token replacement macros ("#define NULL 0") are supported in Cmm.
3.13. Converting existing C code to Cmm
Converting existing C code to Cmm, should you choose to do so, is
mostly a process of deleting unnecessary text. You search on
type declarations, such as "int", "float", "struct", "char",
"[]", etc... and then delete these declaration strings. For
instance, these instances of C code (or C++ code) on the left can
be replaced by the Cmm code on the right:
C Cmm
---------- -------------
int i; .................... i (or nothing at all)
int foo = 3; .................. foo = 3;
struct { ................... /* nothing */
int row;
int col;
}
char name[] = "George"; ....... name = "George";
int goo(int a,char *s,int &c) . goo(a,s,c)
int zoo[] = { 1, 2, 3 }; ...... zoo = { 1, 2, 3 };
The next step in converting C to Cmm is to search for the address
and pointer operators ("*", "&"). If the '&' and '*' are
together so that the address of a variable is passed to a
function, then both of these operators become unnecessary because
Cmm passes lvars by reference. If there are still "*" found then
they are usually referring to the zeroth value of a pointer
address, and so can be replaced with [0], as in "*foo = 4"
replaced by "foo[0] = 4". Finally, the "->" operator for
structures must be replaced by "." either because the structure
is now being passed by referenced or because the element of the
structure is being referred to by its array index: "foo->row" may
need to become "foo[0].row".
-------------------------------- FILE LIST --------------------------------
The CEnvi Unregistered Shareware package includes the files in the
following list. You are not permitted to upload or otherwise transfer
copies of any registered version of CEnvi that does not include all of the
files in this list.
*CENVI.EXE: CEnvi shareware executable for DOS, OS/2, or Windows.
*CENVI.DOC: CEnvi Shareware Manual, Chapter 1: CEnvi Unregistered Shareware
*CMMTUTOR.DOC: CEnvi Shareware Manual, Chapter 2: Cmm Language Tutorial
*CMM_VS_C.DOC: CEnvi Shareware Manual, Chapter 3: Cmm versus C, for C
Programmers
*CENVILIB.DOC: CEnvi Shareware Manual, Chapter 4: Function Library
*FILELIST.DOC: This file.
*LICENSE.DOC: CEnvi Unregistered Shareware License Agreement
*REGISTER.DOC: CEnvi registration form
*INSTALL.CMM: Cmm source file for installing this shareware version
* *.CMM, *.CMD, *.BAT, *.LIB: Many many sample programs using CEnvi. See
CENVI.DOC for a complete list.
----------------------------- REGISTRATION -------------------------------
This is a shareware release. Please register. As a registered CEnvi user
you will receive:
*The latest version of CEnvi for all supported platforms (currently DOS,
OS/2, and Windows).
*The CEnvi user's manual (almost 100 pages, including a description of the
Cmm programming language, a tutorial for those who have never programmed,
and descriptions and examples of the nearly 150 functions included in the
CEnvi library).
*Free incremental electronic downloads for new versions of CEnvi for all
supported operating systems.
*Unlimited support from Nombas and CEnvi/Cmm users through CompuServe
(72212,1622), internet (bsn@world.std.com), the cenvi-cmm e-mail mailing
list (cenvi-cmm@world.std.com), and the Nombas BBS (617-391-6595).
*Access to the growing list of CEnvi utilities and libraries (some of which
are included in this unregistered shareware package, and others are
contributed by Nombas and CEnvi/Cmm users to the electronic locations
described above).
------------------------- CENVI REGISTRATION FORM -------------------------
Thank you for registering your shareware copy of CEnvi version 1.0. Please
fill out and mail in this form, along with payment.
Where did you get CEnvi? ______________________________________________
Name: _________________________________________________________________
Company: ______________________________ Position: _____________________
Address: ______________________________________________________________
_______________________________________________________________________
______________________________________________________________________
Country: _________________________ (add ZIPcode if applicable)
Phone: ___________________________ EMail: ______________________________
Diskette size: [ ] 3.5" [ ] 5.25"
CEnvi Registered License ............ Quantity _____ x $38.00 = $ _________
Additional CEnvi Registered licenses for your
organization (does not include additional manuals
or diskettes). You must already be a registered
user to purchase additional licenses.
Additonal License Quantity _____ x $15.00 = $ _________
Additional CEnvi Manuals. You must already be a
registered user to purchase additional manuals.
Additional Manuals Quantity _____ x $10.00 = $ _________
Friend-of-Cmm Discount: enter $-5.00, and BBS
location, if you have uploaded CEnvi Unregistered
Shareware to a BBS where it wasn't already available.
BBS Location ____________________________________________ $-_________
Shipping outside USA, Canada, or Mexico $4.00 ................ $ _________
Subtotal $ _________
Massachusetts residents please add 5% sales tax ............... $ _________
Total $ _________
Include a check or money order for this total, in U.S. funds and drawn on a
U.S. bank, payable to Nombas. Mail with this form to:
Nombas
P.O. Box 875
Medford, MA 02155 USA
Nombas may also be contacted at:
BBS: (617)391-6595
Phone: (617)391-6595, (617)391-5289
Internet: bsn@world.std.com
CompuServe: 72212,1622
Nombas welcomes all comments, good or bad, regarding CEnvi and Cmm. Please
use the back of this form to give us all your suggestions about CEnvi and
Cmm. This is version 1.0; Where should we go from here?