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.