CONTENTS | PREV | NEXT
18C. Mapping E to C/C++/Pascal/Ada/Lisp etc.
--------------------------------------------
[some new stuff has been added here]
In the first/second column I will match E against AnsiC/C++, the third
column is reserved for a third language. I will mainly use Pascal here,
but where a feature asks for it, I will use others (for example, LISP
with quoted expression, Ada with exceptions etc).
note well: take these tables with a grain of salt. I'll try to denote
syntactic equivalences, and semantic properties as well as possible,
but different languages still need their own evaluation.
usage of signs:
- = feature not available in language in question.
? = author has no clue what this feature translates to.
(or atleast he's not sure).
... = feature may be available, but no appropriate 1:1 translation
possible to make it interesting.
x,y,z = arbitrary identifiers
e,f,g = arbitrary expressions
s,t,u = arbitrary statements
i,j,k = arbitrary integers
etc.
-----------------------------------------------------------------------
STRUCTURE/STATEMENTS
E C/C++ Pascal
----------------------- ----------------------- -----------------------
PROC x() int x() { FUNCTION x:INTEGER;
PROC x(y,z) int x(y,z) { FUNCTION x(y,z:INTEGER):INTEGER;
PROC x(y=1) int x(y=1) { -
ENDPROC return 0; }; x:=0; END;
ENDPROC e return e; }; x:=e; END;
ENDPROC e,f,g - -
RETURN e return e; ?
IF e if(e) { IF e THEN BEGIN
ELSEIF e } else if(e) { END ELSE IF e THEN BEGIN
ELSE } else { END ELSE BEGIN
ENDIF }; END;
IF e THEN s if(e) s; IF e THEN s;
IF e THEN s ELSE t if(e) s else t; IF e THEN s ELSE t;
FOR x:=e TO f - (1) FOR x:=e TO f DO BEGIN
FOR x:=e TO f STEP i - - (2)
EXIT e if(e) break; -
ENDFOR - END;
FOR x:=e TO f DO s - FOR x:=e TO f DO s;
WHILE e while(e) { WHILE e DO BEGIN
EXIT e if(e) break; -
ENDWHILE }; END;
WHILE e DO s while(e) s; WHILE e DO s;
s; WHILE e for(s;e;u) { s; WHILE e DO BEGIN
t; u t; t; u
ENDWHILE }; END;
REPEAT do { REPEAT
UNTIL e } while(!e); UNTIL e;
LOOP for(;;) { WHILE TRUE DO BEGIN (?)
ENDLOOP }; END;
SELECT x switch(x) { CASE x OF
SELECT x OF y switch(x) { CASE x OF
CASE 1; s... case 1: s...; break 1: BEGIN s... END
CASE a+1 - -
CASE 1,2,3 case 1: case 2: case3: 1,2,3:
CASE "a".."z" - -
ENDSELECT }; END
INC x x++; x:=x+1; (INC())
DEC x x--; x:=x-1; (DEC())
JUMP lab goto lab; GOTO lab;
x:=e x=e; x:=e;
/* */ /* */ { }
-> // -
(1) see WHILE; C has no FOR, "for" in C is another way of writing "while"
(2) only STEP -1 as DOWNTO
-----------------------------------------------------------------------
VALUES
E C/C++ Pascal
----------------------- ----------------------- -----------------------
1 1 1
1.0 1.0 1.0
$1 0x1 ?
%1 ? ?
"a" 'a' chr(97) (?)
'blabla' "blabla" 'blabla'
[1,2,3] - (1) -
[1,2,3]:INT - -
(1) in translating from E to C, you can often simulate them with:
myfunc([1,2,3])
becomes:
int dummy [] = {1,2,3};
myfunc(dummy);
-----------------------------------------------------------------------
OPERATORS
E C/C++ Pascal
----------------------- ----------------------- -----------------------
+ - * / + - * / + - * DIV
= <> > < >= <= == != > < >= <= = <> > < >= <=
AND OR (log) && || and or
AND OR (bit) & | ?
SIZEOF x sizeof(x) -
`e - - (1)
^x (4) *x ...
{x} &x ...
x++ x++ -
x-- --x -
-x -x -x
IF e THEN f ELSE g e ? f : g -
x.y x->y x^.y
- x.y x.y
x.y.z x->y->z x^.y^.z
x:=e x=e -
e BUT f (e,f) -
x[] x[0] *x (2) x[0]
x[1] x[1] x[1]
x[1] (3) &x[1] ?
x[1].y x[1]->y x[1]^.y
x[]++ *x++ -
x[1].y++ *(x+1)++ -
x::y.a ((y *)x)->a -
x.y::z.a ((z *)x->y)->a -
(1) see QUOTED EXPRESSIONS
(2) also for others, equivalences between *(x+e) and x[e] hold.
(3) if ARRAY OF <object>
(4) ONLY for giving by reference. otherwise: "[]"
-----------------------------------------------------------------------
CONSTANTS/TYPES
E C/C++ Pascal
----------------------- ----------------------- -----------------------
CONST X=1 #define X 1 CONST X=1;
const int X=1;
ENUM X,Y,Z #define X 0 (etc.) TYPE x=(X,Y,Z);
enum x{X,Y,Z};
SET X,Y,Z - TYPE x=SET OF (X,Y,Z);
DEF VAR
x int x; (or: long x;) x:INTEGER;
x:LONG int x; x:INTEGER;
x:PTR TO y struct y* x; x:^y;
x:y struct y x; x:y;
x[10]:ARRAY OF y struct y x[10]; x:ARRAY [0..9] OF y;
x[10]:STRING - (1) x:STRING[10]; (2)
x[10]:LIST - (1) - (1)
x:REG register int x;
OBJECT x struct x { (3) TYPE x = RECORD
y:CHAR,z:INT char y; short z; y:CHAR; z:INTEGER;
ENDOBJECT }; END;
(1) when translating from E to C, simulate with an array of char/int resp.,
and do your own range-checking etc.
(2) no Wirth Pascal, but available in all popular dialects.
(3) or public class.
-----------------------------------------------------------------------
QUOTED EXPRESSIONS
E LISP MIRANDA
----------------------- --------------------------- -------------------
`e (QUOTE e) 'e (3)
(LAMBDA () e) (1)
`x+y '(+ x y)
Eval(`e) (EVAL `e)
ForAll(v,l,`e) - (2)
MapList(v,l,l,`e) (MAPCAR (LAMBDA (V) E) L) map (\v->e) l
example:
E: MapList({x},[1,2,3,4],a,`x*x)
MIRANDA: map (\x->x*x) [1,2,3,4]
LISP: (MAPCAR (LAMBDA (X) (* X X) `(1 2 3 4))
(1) really QUOTE, but sometimes used where in LISP LAMBDA would be
used, like in MapList()
(2) not even in ProLog, see other logical languages.
(3) lazyness would be used instead here
-----------------------------------------------------------------------
UNIFICATION AND LISP CELLS
E LISP PROLOG
----------------------- ----------------------- -----------------------
<1|2> (1 . 2) [1|2]
<1,2,3> (1 2 3) [1,2,3]
<1,2|3> (1 2 . 3) [1,2|3]
E HASKELL PROLOG
----------------------- ----------------------- -----------------------
e <=> <x|y> (x:y) = e e = [X|Y]
e <=> <1,2,x> [1,2,x] = e e = [1,2,X]
e <=> [1,x] - -
-----------------------------------------------------------------------
EXCEPTIONS
E C++ ADA
----------------------- ----------------------- -----------------------
PROC x() HANDLE int x() { try { function x is begin
EXCEPT } catch (exc) { (1) exception
EXCEPT DO - -
ENDPROC }}; end x;
Raise(e) throw e; raise e;
Throw(e,f) ? -
ReThrow() throw e; raise e;
RAISE "MEM" IF New()=0 - - (2)
(1) catch handles only one specific exception, it's quite different
from general exception handlers as used in E.
(2) the runtime system does raise some exceptions, but I'm not sure
whether automatically raised exceptions can be _defined_ in Ada.
-----------------------------------------------------------------------
OBJECT ORIENTED PROGRAMMING
E C++
------------------------------- -----------------------
OBJECT x class x {
OBJECT x OF y class x : y {
self.i this->i
PROC a OF x IS self.i virtual int x::a() { return i; }
- int x::a() { return i; }
PROC a OF x IS EMPTY virtual int x::a() =0
PUBLIC public:
a.method(1) a->method(1)
SUPER a.method(1) a->supername::method(1)
[see also next part under NEW]
-----------------------------------------------------------------------
BUILTIN FUNCTIONS AND MEMORY ALLOCATION
(only a few are presented here, as an example)
E C/C++ Pascal
----------------------- ----------------------- -----------------------
WriteF(fs,...) printf(fs,...); WriteLn(a,b,...);
cout << a << b ... ;
ReadStr(f,s) scanf(fs,...) ReadLn(s)
Val(s) Val()
cin >> s;
StrCopy(s,s,n) (1) strcpy(s,s) s:=s; (2)
Mod(e,e) e%e e MOD e
Shl(e,n) e<<n Shl()
Long(e) - -
p:=New(e) p=malloc(e); New(p);
NEW p p=new type;
NEW p.constr() p=new constr() -
NEW [e,f,g] - -
Dispose(p) free(p); Dispose(p);
END p delete p;
(1) when translating from C, make sure you turn the arrays of char into
proper STRINGs.
(2) dunno what function is needed in the pointer case.