ptom

-LCB-

A

pascal

Translator

For

Mobile

Code

Christian

F.

Tschudin

Technical

Report

July

Computer

Science

Department

University

of

Zurich

Winterthurerstr

Zurich

Switzerland

Email

tschudin@ifi.unizh.ch

Abstract

We

report

on

an

implementation

of

a

pascal

translator

that

generates

code

for

mobile

software

messengers

-LRB-

agents

-RRB-

these

agents

can

roam

a

network

of

interconnected

execution

platforms

on

behalf

of

a

user

enabling

users

to

implement

customized

network

functionality

themselves

In

this

report

we

focus

on

the

language

extensions

-LRB-

pascal-m

-RRB-

and

the

implementation

aspects

of

the

translator

The

main

departure

in

pascal-m

from

standard

pascal

is

that

the

programmer

has

access

to

the

generated

code

in

form

of

string

constants

An

interesting

aspect

of

the

pascal-to-MO

-LRB-

ptom

-RRB-

translator

is

that

pascal-m

is

translated

to

the

stack-based

high-level

language

MO.

MO

is

similar

to

postscript

and

has

no

notion

of

memory

addresses

although

pascal

compilers

usually

produce

code

for

machines

or

software

interpreters

with

word

addressable

memory

because

MO

completely

hides

the

exact

memory

locations

of

code

as

well

as

data

we

have

to

use

other

implementation

approaches

for

activation

frames

variable

dereferencing

and

code

fixups

Other

aspects

of

the

translator

implementation

like

data

mapping

and

heap

management

are

also

described

Finally

we

relate

our

work

to

recent

developments

in

the

field

of

intermediate

code

and

languages

Introduction

pascal

is

still

one

of

the

most

used

languages

when

it

comes

to

explain

algorithms

in

textbooks

or

scientific

journals

In

our

research

project

on

mobile

code

we

also

had

the

need

to

document

the

algorithms

we

used

for

programming

the

network

with

communications

messengers

i.e.

small

autonomous

mobile

code

pieces

that

can

roam

the

network

Therefore

we

developed

a

new

pascal

dialect

-LCB-

pascal-m

-LCB-

and

the

ptom

translator

that

translates

pascal-m

to

the

target

language

MO.

The

novel

element

of

pascal-m

is

that

the

programmer

has

direct

access

to

the

generated

code

from

within

pascal-m

This

allows

for

explicit

manipulation

of

code

strings

to

be

shipped

to

neighboring

messenger

execution

platforms

Mobile

Code

and

the

Language

Issue

Mobile

software

agents

are

based

on

the

concept

of

remote

programming

In

principle

this

concept

could

be

implemented

by

the

exchange

of

code

only

-LRB-

mobile

code

-RRB-

together

with

a

mechanism

at

the

receiver

side

that

accepts

incoming

code

and

executes

For

portability

reasons

one

uses

intermediate

code

instead

of

native

code

Programs

expressed

in

such

a

code

are

either

interpreted

or

compiled

on-the-fly

to

the

receiver

's

native

instruction

set

A

third

language

level

may

provide

more

comfort

for

the

programmer

agents

can

then

be

expressed

in

an

object

oriented

high-level

language

which

is

compiled

to

intermediate

code

and

then

interpreted

or

further

compiled

into

native

code

In

section

we

point

to

other

programming

languages

used

for

mobile

code

Which

mobile

code

language

is

chosen

depends

on

many

-LRB-

external

-RRB-

factors

including

personal

preferences

The

MO

language

was

developed

in

a

bottom-up

approach

as

a

fast

lane

to

a

running

mobile

code

system

On

one

hand

it

adheres

to

an

approach

of

pure

mobile

code

in

trying

to

minimize

the

assumptions

about

and

the

operational

effort

for

a

mobile

code

infrastructure

mobile

code

should

be

used

to

built

such

infrastructures

instead

of

relying

on

their

existence

On

the

other

hand

MO

was

chosen

to

be

a

high-level

language

making

the

programming

task

fast

and

less

error

prone

MO

is

a

stack-based

postfixed

language

with

a

very

compact

syntax

that

is

presented

in

section

The

mobile

code

fragments

expressed

in

MO

are

called

messengers

-LRB-

which

nicely

contrasts

with

the

more

passive

concept

of

messages

-RRB-

Perhaps

even

more

important

that

the

comfort

of

programming

is

the

expressive

power

and

the

underlying

execution

model

of

a

programming

language

A

conceptual

argument

in

MO

is

that

remote

programming

inevitably

involves

late

binding

when

a

messenger

-LRB-

mobile

agent

-RRB-

arrives

at

a

remote

system

its

sequence

of

instructions

has

to

be

bound

to

the

local

instruction

set

and/or

to

subroutines

already

resident

at

the

remote

system

Another

issue

of

MO

is

that

we

explicitly

envisage

metaprogramming

i.e.

the

binding

to

procedures

not

known

at

compiletime

and

the

generation

of

new

messengers

at

runtime

from

within

MO

code

Both

concerns

binding

at

receive

time

and

metaprogramming

led

to

disregard

languages

that

require

compilation

although

-LRB-

transparently

-RRB-

compiling

MO

could

be

a

possible

optimization

in

the

future

When

we

consider

pascal

as

a

mean

of

expressing

messengers

we

have

conflicting

interests

because

pascal

's

type

checking

is

contrary

to

MO

's

late

binding

principle

pascal

checks

all

types

at

compile

time

as

many

other

modern

languages

do

mobile

agent

systems

built

on

top

of

such

languages

naturally

try

to

extend

type

checking

to

the

programming

of

agents

An

outcome

of

extending

pascal

in

order

to

support

mobile

agents

is

that

it

makes

the

different

underlying

concepts

and

implicit

assumptions

visible

and

also

permits

a

direct

comparison

with

other

mobile

code

systems

based

e.g.

on

java

In

our

case

we

can

relate

pascal-m

and

MO

to

java

and

the

bytecodes

for

the

java

virtual

machine

respectively

Note

however

that

ptom

is

a

translator

not

a

compiler

because

the

target

language

is

not

native

CPU

code

In

fact

ptom

just

expresses

programs

written

in

a

high-level

language

in

some

other

high-level

language

The

latest

pascal

source

code

of

the

ptom

translator

-LRB-

including

a

few

pascalm

programming

examples

-RRB-

and

this

documentation

are

accessible

under

in

practice

one

often

makes

a

distinction

between

an

agent

's

code

and

the

agent

's

state

that

has

to

be

transferred

Also

there

are

often

some

restrictions

on

which

code

should

be

accepted

and

executed

by

means

of

mutual

authentication

of

agent

and

execution

platform

ftp

ftp.ifi.unizh.ch

pub/projects/msgr

ptom

This

technical

report

is

also

online

available

as

ftp

Overview

In

section

of

this

report

we

give

a

brief

introduction

to

the

messenger

concept

and

the

target

language

MO

that

is

understood

by

all

messenger

execution

platforms

For

a

full

account

of

the

MO

language

we

refer

to

-LSB-

-RSB-

as

well

as

we

assume

in

this

paper

some

familiarity

with

the

execution

model

and

data

types

of

postscript

-LSB-

-RSB-

Section

introduces

the

extensions

of

pascal-m

while

in

section

we

cover

some

implementation

details

of

the

translator

proper

and

show

an

example

program

written

in

pascal-m

Section

concludes

this

report

with

a

discussion

and

references

to

related

work

mainly

the

recent

growing

interest

in

intermediate

languages

and

intermediate

code

representation

for

compilers

due

to

the

advent

of

mobile

code

Messengers

and

the

Programming

Language

MO

Communications

by

messengers

is

an

alternate

paradigm

for

implementing

computer

communications

-LSB-

-RSB-

instead

of

exchanging

predefined

messages

according

to

a

well-defined

protocol

between

pre-installed

protocol

entities

protocols

are

implemented

with

mobile

code

fragments

only

These

messengers

carry

with

them

the

logic

of

the

protocol

to

implement

The

advantage

of

this

approach

is

that

protocolspecific

software

must

not

be

installed

beforehand

of

any

communication

between

distant

hosts

-LCB-

binding

a

communications

service

to

an

implementation

is

delayed

until

runtime

and

ruled

by

the

initiator

The

price

for

the

protocol

genericity

and

the

increased

flexibility

is

that

the

range

of

optimization

is

narrowed

-LRB-

once

a

ordinary

message-exchange

protocol

has

proven

to

be

useful

highly

optimized

implementations

are

deployed

and

statically

installed

-RRB-

The

messenger

paradigm

can

also

be

characterized

as

the

instructional

form

of

computer

communications

while

classical

message

exchange

is

based

on

message

interpretation

For

the

operation

of

a

messenger-based

communication

architecture

one

needs

execution

platforms

which

accept

arbitrary

messengers

and

execute

them

At

the

transmission

level

we

have

messenger

packets

sent

to

platforms

that

consist

mainly

of

a

sequence

of

instructions

Each

received

messenger

packet

becomes

an

active

messenger

process

that

is

unconditionally

executed

It

can

locally

interact

with

the

execution

platform

and

is

able

to

submit

new

messenger

packets

to

other

platforms

In

the

sequel

we

use

the

term

messenger

for

messenger

packets

as

well

as

messenger

processes

MO

is

a

first

implementation

of

the

messenger

paradigm

-LSB-

-RSB-

It

defines

a

data

format

for

messenger

packets

and

specifies

the

internal

structure

-LRB-

execution

model

-RRB-

of

an

MO

execution

platform

MO

is

also

the

name

for

the

language

in

which

the

messengers

instructions

are

expressed

Figure

shows

the

main

elements

of

the

MO

messenger

execution

platform

ffl

Messenger

packets

received

by

the

platform

become

concurrent

and

independent

processes

ffl

Messenger

processes

interact

through

a

shared

memory

area

messengers

can

deposit

data

values

under

arbitrary

keys

In

MO

this

is

realized

as

a

public

x

y

abc

process

queues

channels

messengers

received

processes

Messenger

execution

platform

shared

memory

Figure

The

structure

of

a

messenger

execution

platform

dictionary

that

all

processes

can

read

from

and

write

to

-LRB-

but

which

is

not

browsable

-RRB-

ffl

Messenger

processes

can

synchronize

their

execution

with

process

queues

if

a

process

enters

a

queue

-LRB-

which

is

identified

by

a

key

-RRB-

it

becomes

active

only

when

it

advances

at

the

queue

's

head

position

A

process

can

be

in

only

one

queue

at

any

time

entering

another

queue

automatically

removes

the

process

from

its

current

queue

Queues

can

be

stopped

-LRB-

inhibiting

other

queued

processes

to

advance

-RRB-

and

later

be

restarted

ffl

Messenger

processes

can

create

new

messenger

packets

and

request

their

transfer

to

neighboring

platforms

with

the

submit

command

The

messenger

transfer

is

not

reliable

i.e.

messengers

may

be

lost

or

be

delivered

in

desequenced

order

It

is

also

possible

to

spawn

local

messenger

processes

ffl

Finally

note

that

a

platform

offers

except

the

transmission

to

neighboring

platforms

only

local

services

All

communication

services

that

would

involve

the

cooperation

of

several

platforms

must

be

implemented

by

messengers

Messengers

are

prototypic

mobile

agents

in

the

sense

that

they

represent

the

essence

of

mobile

code

Using

the

simple

messengers

one

can

built

richer

and

perhaps

even

intelligent

mobile

agents

including

direct

agent-to-agent

communications

Comparing

MO

with

postscript

The

MO

programming

language

is

structurally

very

similar

to

postscript

although

graphics

related

operators

are

completely

missing

There

is

an

operand

stack

a

stack

of

dictionaries

for

name

resolution

and

a

-LRB-

hidden

-RRB-

execution

stack

maintained

by

the

MO

interpreter

There

are

simple

data

values

-LRB-

integers

time

values

keys

and

names

-RRB-

and

container

types

-LRB-

arrays

strings

dictionaries

and

FIFO

message

queues

-RRB-

Many

standard

operators

of

postscript

are

also

present

in

MO.

This

is

also

true

for

the

construction

of

arrays

and

procedures

with

the

mark

and

array

operators

-LSB-

-RSB-

-LCB-

-RCB-

respectively

MO

's

submission

channels

and

process

queues

are

opaque

types

that

can

not

be

directly

accessed

instead

they

must

be

referenced

by

keys

which

are

a

kind

of

handle

At

the

lexical

level

the

differences

between

MO

and

postscript

are

more

prominent

ffl

Uppercase

names

are

limited

to

a

single

character

Most

standard

operators

of

MO

have

uppercase

names

which

leads

to

a

very

compact

coding

because

no

delimiting

space

characters

are

required

Example

-LRB-

postscript

-RRB-

currentdict

-LCB-

exch

exch

pop

pop

-RCB-

forall

-LRB-

MO

-RRB-

-LCB-

XXPP

-RCB-

L

Multicharacter

identifiers

thus

are

limited

to

lowercase

characters

and

may

not

contain

punctuation

characters

which

are

also

defined

to

be

single

character

identifiers

ffl

Strings

are

in

MO

delimited

with

double

quotes

instead

of

parenthesis

The

backslash

can

be

used

to

define

strings

by

giving

hex

digits

xyz

is

the

same

as

ffl

To

quote

names

postscript

uses

the

slash

character

which

in

MO

becomes

the

quote

character

Many

MO

and

postscript

operators

-LCB-

beside

differing

in

names

-LCB-

behave

indenticaly

Figure

gives

the

equivalences

for

some

of

the

standard

MO

operators

The

pascal-m

Language

pascal-m

is

a

new

pascal

dialect

for

expressing

messenger

code

The

reason

for

defining

yet

another

pascal

was

twofold

on

one

hand

we

realized

that

messenger

expressed

in

MO

are

hardly

self

-LCB-

documenting

which

makes

it

difficult

to

exchange

ideas

about

mobile

code

by

showing

code

examples

It

is

also

true

that

programming

in

MO

is

tedious

and

MO

code

should

better

be

generated

by

programs

On

the

other

hand

we

think

that

programming

with

mobile

code

is

not

mastered

yet

as

well

as

discussions

about

the

right

way

to

support

it

at

the

language

level

are

going

on

in

the

object

-LCB-

oriented

community

Our

view

is

that

mobile

code

questions

some

very

basic

assumptions

on

objects

like

e.g.

the

stationary

flow

of

control

and

the

consequently

stationary

method

interface

-LRB-

in

Agha

's

actor

model

this

translates

to

global

mailbox

addresses

-RRB-

In

order

to

avoid

an

investigation

into

problems

of

object

-LCB-

orientation

instead

of

mobile

code

we

adopt

a

minimalistic

approach

messengers

are

lean

mobile

flows

of

control

with

private

memory

that

can

roam

the

network

and

which

can

enter

into

contact

only

through

side

effects

in

a

platform

's

shared

memory

Wirth

's

classic

pascal

-LSB-

-RSB-

is

therefore

a

good

starting

point

for

developing

a

highlevel

language

for

these

purely

sequential

messengers

Our

viewpoint

is

that

pascalm

is

an

experimental

language

that

should

help

to

better

understand

programming

requirements

for

mobile

code

Composing

Messengers

at

Run

Time

One

central

element

of

the

messenger

programming

language

MO

is

the

ability

of

messenger

processes

to

compose

other

messengers

While

in

high-level

languages

like

pascal

or

C

one

has

a

clear

separation

between

high-level

language

and

machine

code

this

separation

becomes

impeding

with

messengers

In

fact

arbitrary

character

strings

can

in

MO

be

claimed

to

be

the

code

of

a

new

messenger

-LRB-

in

case

of

invalid

instructions

missing

or

wrong

parameters

the

messenger

is

simply

aborted

-RRB-

At

MO

postscript

comment

currentdict

push

topmost

dictionary

-LSB-

-LSB-

push

a

mark

-RSB-

-RSB-

collect

all

elements

downto

mark

into

an

array

-LCB-

-LCB-

push

a

procedure

mark

-RCB-

-RCB-

collect

all

elements

downto

mark

into

a

procedure

array

put

define

an

dictionary

entry

or

set

an

array

element

no

equivalent

push

a

new

random

key

no

equivalent

-LRB-

underscore

-RRB-

name

of

the

global

dictionary

that

represents

the

shared

memory

area

ifelse

execute

one

of

the

two

elements

according

to

the

boolean

value

quote

character

-LRB-

begin

move

dictionary

from

operand

to

dictionary

stack

-RRB-

end

discard

topmost

element

of

dictionary

stack

A

array

create

an

array

of

given

size

D

dict

create

a

dictionary

-LRB-

in

MO

no

size

must

be

given

-RRB-

F

find

find

the

topmost

dictionary

where

the

given

name

is

defined

G

get

get

a

dictionary

entry

or

an

array

element

H

stopped

execute

a

procedure

in

a

new

context

and

catch

errors

I

index

push

a

copy

of

the

ith

element

relative

to

the

operand

stack

's

top

J

exit

jumps

out

of

the

innermost

loop

L

for

and

loop

loops

a

given

number

of

times

-LRB-

or

indefinitely

-RRB-

L

forall

loop

over

an

array

or

dictionary

P

pop

discard

the

topmost

element

of

the

operand

stack

S

string

create

a

string

instance

of

given

length

X

exch

swap

the

two

topmost

operands

Z

stop

terminate

the

inner-most

H

context

Figure

Important

MO

operators

and

their

postscript

equivalent

a

first

look

pascal-m

respects

the

classical

high-level/machine-level

separation

and

tries

to

go

as

far

as

possible

in

hiding

the

low-level

aspects

of

MO.

Nevertheless

should

the

programmer

be

able

to

manipulate

the

code

produced

by

the

pascal-m

translator

For

introducing

this

in

a

clean

way

we

provide

messenger

type

declarations

A

messenger

type

declaration

is

introduced

by

the

new

keyword

msgrtype

that

has

the

structure

of

a

parameterless

procedure

definition

Messenger

types

defined

this

way

can

not

be

called

instead

they

define

a

string

constant

PROGRAM

demo

CONST

msg

a

message

MSGRTYPE

a

BEGIN

END

VAR

s

string

BEGIN

-LCB-

demo

-RCB-

s

msg

s

a

s

makemsgr

-LRB-

newkey

a

msg

-RRB-

END

The

messenger

type

declaration

for

a

results

in

a

string

constant

that

can

be

accessed

like

any

other

constant

string

value

-LRB-

e.g.

msg

-RRB-

The

actual

messenger

instance

is

created

by

the

makemsgr

function

defined

as

FUNCTION

makemsgr

-LRB-

startqueue

key

mtype

string

mdata

string

-RRB-

string

This

function

produces

a

messenger

packet

by

including

a

key

that

selects

the

process

queue

in

which

the

messenger

should

be

started

as

well

as

a

data

field

which

can

be

used

to

parametrize

the

messenger

's

code

New

Scoping

Rules

For

Messenger

Type

Declarations

Because

messengers

are

selfcontained

programs

shipped

to

remote

locations

they

may

not

contain

references

to

variables

or

procedures

defined

outside

the

messenger

's

scope

The

ptom

translator

enforces

this

by

allowing

references

to

external

type

and

constant

definitions

only

Variables

procedures

and

functions

which

are

in

a

messenger

's

surrounding

scope

may

not

be

referenced

from

within

the

messenger

Figure

depicts

this

new

scoping

rule

that

departs

from

standard

pascal

a

MSGRTYPE

e

VAR

f

CONST

b

TYPE

c

PROGRAM

a

MSGRTYPE

h

PROCEDURE

g

PROCEDURE

d

PROGRAM

a

CONST

b

TYPE

c

char

PROCEDURE

d

BEGIN

END

MSGRTYPE

e

VAR

f

integer

PROCEDURE

g

BEGIN

END

MSGRTYPE

h

BEGIN

END

BEGIN

-LCB-

msgrtype

e

-RCB-

END

BEGIN

-LCB-

program

a

-RCB-

END

Figure

Visibility

of

names

in

messenger

type

declarations

messenger

type

declarations

grounds

the

usual

nesting

hierarchy

of

procedures

and

functions

i.e.

starts

a

new

name

space

that

inherits

from

its

environment

only

constants

and

type

definitions

-LRB-

including

messenger

types

-RRB-

Figure

shows

this

in

text

form

for

the

example

of

figure

the

table

entries

indicate

whether

a

given

name

-LRB-

rows

-RRB-

is

visible

for

a

given

environment

-LRB-

columns

-RRB-

or

not

Other

New

Aspects

of

pascal-m

Our

aim

was

to

stay

as

close

as

possible

to

the

original

pascal

language

and

not

to

make

every

feature

of

MO

available

to

the

pascal-m

programmer

However

beside

the

messenger

type

declaration

introduced

we

also

had

to

extend

the

number

of

supported

types

to

some

degree

Character

strings

and

string

concatenation

with

PROGRAM

a

PROCEDURE

d

MSGRTYPE

e

PROCEDURE

g

MSGRTYPE

h

b

visible

visible

visible

visible

visible

c

visible

visible

visible

visible

visible

d

visible

visible

-LCB-

-LCB-

-LCB-

e

visible

-LCB-

visible

visible

visible

f

-LCB-

-LCB-

visible

visible

-LCB-

g

-LCB-

-LCB-

visible

visible

-LCB-

h

-LCB-

-LCB-

visible

-LCB-

visible

Figure

Visibility

of

names

for

the

example

in

figure

are

in

most

pascal

dialects

-LRB-

as

well

as

java

-RRB-

now

state-of-the-art

so

we

do

not

consider

this

a

novel

extension

The

exit

statement

for

escaping

loops

and

the

otherwise

clause

for

case

statements

are

also

rather

standard

today

and

are

supported

by

pascal-m

The

key

Type

Shared

Memory

Access

and

inline

Procedures

The

new

simple

data

type

key

is

a

direct

heritage

from

MO

specifically

introduced

for

the

programming

of

messengers

In

pascal-m

keys

are

rather

boring

data

instances

they

only

can

be

copied

from

one

variable

to

another

or

be

returned

as

a

function

's

result

However

keys

are

essential

for

accessing

the

shared

memory

area

for

handling

process

queues

and

for

submitting

messengers

to

other

locations

For

example

the

globaldef

and

globalget

procedure

enable

to

store

-LRB-

fetch

-RRB-

arbitrary

data

values

in

the

platform

's

global

dictionary

Under

pascal-m

entries

are

referenced

by

random

keys

Only

by

knowing

a

key

can

other

messenger

access

the

corresponding

data

value

Using

globalundef

entries

can

also

be

explicitly

removed

With

globalknown

one

can

check

whether

for

a

given

key

an

entry

already

exists

or

not

For

implementation

simplicity

we

did

not

implement

MO

-LCB-

specific

procedures

-LRB-

like

the

above

mentioned

global

procedures

-RRB-

as

pascal-m

standard

procedures

Instead

an

inline

mechanism

is

offered

which

enables

to

directly

code

a

pascal-m

function

's

MO

instructions

For

example

the

procedure

is

defined

as

PROCEDURE

globaldef

-LRB-

k

key

a

any

-RRB-

INLINE

The

special

type

any

allows

for

a

generic

handling

-LRB-

import/export

from

the

shared

memory

area

-RRB-

of

variables

regardless

fo

their

actual

type

It

is

up

to

the

programmer

to

ensure

that

data

fetched

from

the

shared

memory

area

actually

have

the

type

of

the

receiving

pascal-m

variable

A

possible

extension

would

be

to

offer

a

IS

predicate

similar

to

Oberon

-LRB-

or

isinstanceof

in

java

-RRB-

by

which

a

runtime

type

check

can

be

explicitly

enforced

A

collection

of

the

most

important

MO

bindings

has

been

developed

and

consists

of

a

set

of

inlined

procedure

declarations

This

small

MO

-LCB-

library

that

can

be

included

in

all

pascal-m

source

code

is

shown

in

Appendix

B.

Although

it

is

not

part

of

the

pascal-m

language

specification

proper

its

use

is

essential

for

programming

that

-LCB-

according

to

the

semantics

of

the

shared

memory

area

at

the

level

of

MO

-LCB-

the

value

stored

by

this

procedure

is

a

copy

of

the

local

variable

instance

If

later

on

the

program

needs

to

modify

the

shared

data

it

should

reload

the

instance

with

a

call

to

globalget

messengers

Summary

of

Main

Differences

to

Standard

pascal

Figure

summarizes

the

main

differences

between

standard

pascal

Wirth

's

small

pascal-s

-LRB-

which

was

the

base

of

the

ptom

translator

-RRB-

and

our

messenger

-LCB-

specific

pascal-m

language

pascal-m

features

some

relaxed

syntactic

rules

aligned

with

pascal

pascal-s

pascal-m

real

variables

real

variables

not

supported

alfa

for

character

strings

not

supported

string

type

pointer

types

not

supported

pointer

types

variant

records

not

supported

not

supported

set

types

not

supported

not

supported

forward

declaration

not

supported

forward

declaration

file

IO

file

IO

not

supported

-LCB-

-LCB-

messenger

type

-LCB-

-LCB-

key

type

-LCB-

-LCB-

any

type

-LCB-

-LCB-

exit

for

loops

-LCB-

-LCB-

otherwise

-LCB-

-LCB-

inline

functions

Figure

Main

differences

between

pascal

pascal-s

and

pascal-m

modern

dialects

of

pascal

-LRB-

e.g.

-LSB-

-RSB-

-RRB-

declaration

blocks

for

variables

types

and

procedures

can

be

placed

in

any

order

Another

syntactic

departure

of

pascal-m

regards

the

unit

of

compilation

ptom

can

translate

single

functions

-LRB-

without

the

PROGRAM

END

structure

-RRB-

which

is

useful

for

writing

small

MO

procedures

-LRB-

for

an

example

see

section

and

figure

-RRB-

The

main

difference

is

the

size

of

generated

code

without

the

PROGRAM

END

structure

the

translator

does

not

insert

the

pascal-m

runtime

library

into

the

code

stream

Note

however

that

the

code

strings

generated

for

messenger

types

always

contain

the

runtime

library

The

pascal-m

runtime

library

should

not

be

confounded

with

the

above

mentioned

MO

-LCB-

library

more

on

the

runtime

library

can

be

found

in

section

and

Possible

Future

Extensions

of

pascal-m

As

we

continue

to

express

messengers

with

the

new

pascal-m

language

we

will

certainly

encounter

other

language

features

that

would

be

nice

to

have

Some

of

them

that

we

already

know

about

are

listed

below

but

we

did

not

implement

them

yet

ffl

Parametrized

messengers

parameters

to

messenger

types

can

only

be

passed

in

a

single

string

variable

-LRB-

see

the

makemsgr

procedure

-RRB-

and

implicitly

in

the

new

messenger

's

key

for

the

starting

queue

This

requires

the

programmer

to

format

-LRB-

serialize

-RRB-

multiple

parameters

into

a

single

parameter

string

and

-LCB-

inside

the

messenger

-LCB-

to

decode

-LRB-

deserialize

-RRB-

the

parameters

It

would

be

elegant

to

have

parametrized

messenger

declarations

and

letting

the

compiler

insert

the

corresponding

encoding

and

decoding

routines

directly

into

the

messenger

type

's

code

string

ffl

Conformant

arrays

and

the

possibility

to

use

them

in

formal

parameter

lists

would

be

simple

to

implement

in

ptom

because

MO

already

implements

highlevel

arrays

with

implicit

length

information

ffl

Runtime

type

check

as

was

mentioned

above

it

would

be

helpful

to

check

a

variable

's

type

at

runtime

in

case

this

variable

was

copied

from

the

platform

's

shared

memory

A

IS

predicate

like

the

one

found

in

Oberon

-LSB-

-RSB-

would

do

it

ffl

Because

the

ptom

translator

knows

the

stack

layout

of

a

messenger

-LRB-

expressed

in

pascal-m

-RRB-

one

could

envisage

the

implementation

of

a

go

procedure

like

the

one

offered

to

mobile

agents

in

telescript

-LSB-

-RSB-

The

go

procedure

would

have

to

freeze

the

complete

state

of

the

messenger

-LRB-

stack

and

execution

state

-RRB-

encode

it

in

some

suitable

form

transfer

it

to

some

remote

platform

and

reinstantiate

the

messenger

there

In

fact

messengers

would

be

used

to

implement

higher

level

agents

It

may

be

useful

to

envisage

a

new

declaration

header

-LRB-

such

as

e.g.

agenttype

-RRB-

for

messenger

types

that

request

explicit

execution

stack

handling

Internals

of

the

ptom

Translator

The

ptom

translator

was

not

built

form

scratch

Instead

Wirth

's

well

-LCB-

known

small

pascal

compiler

was

used

as

a

starting

point

This

also

means

that

ptom

is

written

in

pascal

The

ptom

translator

currently

compiles

under

Turbo

Pascal

as

well

as

with

Sun

Pascal

Major

modifications

to

pascal-s

were

made

in

the

following

domains

ffl

The

code

interpreter

that

is

part

of

pascal-s

was

removed

ptom

generates

MO

code

ffl

File

IO

is

not

supported

by

pascal-m

all

related

procedures

and

types

were

removed

from

pascal-s

ffl

No

efforts

are

made

to

recover

a

syntax

error

of

the

program

under

translation

thus

the

error

-LRB-

-RRB-

routine

eventually

calls

halt

ffl

Instead

of

using

calls

to

the

read

procedure

ptom

works

on

a

full

source

code

string

-LRB-

memory

is

cheap

mobile

agents

are

small

-RRB-

Like

pascal-s

we

send

code

first

to

memory

and

dump

it

later

ffl

Adjustments

were

made

to

the

set

of

supported

data

types

and

constructors

reals

and

associated

data

transfer

procedures

were

removed

the

pointers

and

enumerated

types

were

-LRB-

re

-RRB-

implemented

like

in

full

pascal

strings

and

keys

were

added

as

new

builtin

types

In

the

following

paragraphs

we

discuss

several

of

these

points

in

more

detail

Code

Generation

Strategies

One

of

the

interesting

aspect

of

the

ptom

translator

is

that

code

must

be

generated

for

a

machine

that

provides

high-level

access

to

data

objects

only

Ordinarily

compilers

for

straight

machine

code

have

to

handle

memory

allocation

-LRB-

a

-RRB-

for

the

generated

code

-LRB-

including

fixups

-RRB-

-LRB-

b

-RRB-

for

the

execution

stack

of

the

running

program

and

-LRB-

c

-RRB-

for

constants

like

strings

and

other

static

data

Translating

for

postscript

-LCB-

like

target

code

results

in

significant

simplifications

Example

the

if-else

statement

Consider

for

example

the

code

to

be

generated

for

an

if-else

statement

with

the

boolean

expression

expr

and

the

two

code

branches

consisting

of

statements

and

-LRB-

figure

-RRB-

In

the

case

of

assembler

code

label

is

required

for

jumping

to

pascal

Assembler

postscript

MO

IF

expr

THEN

ELSE

expr

jz

jmp

expr

-LCB-

-RCB-

-LCB-

-RCB-

ifelse

expr

-LCB-

-RCB-

-LCB-

-RCB-

Figure

Different

implementations

of

an

if

else

statement

the

second

branch

while

label

points

to

the

code

where

execution

continues

after

the

if-else

statement

The

exact

location

of

and

is

not

known

at

the

moment

when

corresponding

jump

instructions

must

be

emitted

because

at

this

point

of

time

one

does

not

know

the

exact

code

size

of

the

statements

and

A

fixup

operation

is

required

that

patches

into

already

generated

code

the

label

addresses

as

soon

as

they

become

available

-LRB-

pascal-s

does

it

this

way

-RRB-

-LRB-

Another

possibility

would

be

to

assign

index

values

to

all

labels

-LRB-

e.g.

and

-RRB-

and

to

set

up

a

jump

table

where

the

addresses

of

and

will

be

put

The

jump

instructions

would

then

include

a

level

of

indirection

e.g.

jz

jtab

-LSB-

-RSB-

instead

of

jz

-RRB-

Looking

at

the

translator

code

this

results

in

the

simplified

program

structure

of

figure

In

the

case

of

MO

-LRB-

or

postscript

-RRB-

no

fixup

addresses

are

required

postscript

's

ifelse

operator

-LRB-

in

MO

-RRB-

expects

two

procedures

on

the

operand

stack

from

which

one

is

chosen

according

to

the

boolean

value

-LRB-

which

also

on

the

operand

stack

-RRB-

In

fact

it

is

the

parser

that

examines

the

-LCB-

and

-RCB-

symbols

grouping

together

the

branches

into

two

procedure

objects

and

pushing

them

on

the

operand

stack

The

grouping

is

done

once

when

the

program

is

read

in

by

the

interpreter

this

means

that

the

execution

of

an

if-else

statement

involves

pushing

the

two

-LRB-

references

to

-RRB-

procedure

objects

but

is

not

slowed

down

by

the

grouping

activity

performed

at

parsing

time

Note

that

MO

has

no

if

operator

-LRB-

only

an

ifelse

operator

written

as

-RRB-

and

therefore

we

always

generate

a

second

possibly

empty

procedure

although

there

may

be

no

else

clause

in

the

pascal

program

Compiler

for

Assembler

code

Translator

for

MO

code

if

sy

ifsy

then

error

-LRB-

-RRB-

insymbol

expression

if

sy

thensy

then

error

-LRB-

-RRB-

insymbol

emit

-LRB-

jz

XX

-RRB-

location

of

XX

statement

if

sy

elsesy

then

begin

emit

-LRB-

jmp

YY

-RRB-

location

of

YY

fixup

-LRB-

current-code-position

-RRB-

insymbol

statement

fixup

-LRB-

current-code-position

-RRB-

end

else

fixup

-LRB-

current-code-position

-RRB-

if

sy

ifsy

then

error

-LRB-

-RRB-

insymbol

expression

if

sy

thensy

then

error

-LRB-

-RRB-

insymbol

emit

-LRB-

-LCB-

-RRB-

statement

emit

-LRB-

-RCB-

-LCB-

-RRB-

if

sy

elsesy

then

begin

insymbol

statement

end

emit

-LRB-

-RCB-

-RRB-

Figure

Generating

code

for

an

if

else

statement

Example

Procedure

Calls

And

Variable

Access

MO

provides

an

operand

stack

where

arbitrary

data

values

can

by

pushed

and

popped

While

it

is

easy

to

access

the

top

element

as

well

as

elements

at

a

given

distance

relative

to

the

stack

's

top

it

is

difficult

to

address

elements

by

an

absolute

index

value

This

renders

techniques

for

accessing

a

procedure

's

local

variables

via

a

frame

or

base

pointer

infeasible

Keeping

track

of

all

arguments

pushed

and

popped

during

a

program

's

execution

is

error

prone

wherefore

we

chose

to

use

dictionaries

with

explicitly

named

variable

entries

for

implementing

a

procedure

activation

frame

The

prologue

of

a

procedure

then

has

the

form

-LCB-

dict

begin

-LRB-

in

MO

this

becomes

-LCB-

D

-LRB-

-RRB-

immediately

followed

by

the

instructions

to

pop

off

the

arguments

passed

to

that

function

and

assigning

them

to

variables

in

the

newly

created

dictionary

The

epilogue

is

simply

a

end

-RCB-

-LRB-

-RRB-

-RCB-

in

MO

-RRB-

which

automatically

discards

all

local

variables

Accessing

local

variables

then

becomes

very

easy

as

shows

the

example

in

figure

In

this

example

the

r

variable

is

inserted

by

the

translator

we

use

this

name

by

convention

for

a

function

's

return

value

Just

before

doing

the

epilogue

the

content

of

this

variable

is

pushed

on

the

operand

stack

leaving

it

there

for

the

calling

procedure

Using

postscript

's

dictionary

stack

for

the

activation

frames

has

the

advantage

that

name

resolution

-LRB-

and

thus

locating

the

variable

in

memory

-RRB-

is

carried

out

by

the

postscript

interpreter

and

has

not

to

be

carried

out

by

the

translator

Thus

there

is

no

need

anymore

for

static

and

dynamic

links

through

activation

frames

although

the

translator

still

checks

whether

there

is

a

scope

wherein

a

given

variable

name

is

defined

More

precisely

the

access

to

a

variable

in

some

outer

scope

is

programmed

as

shown

in

figure

The

find

operator

-LRB-

F

in

MO

-RRB-

returns

the

topmost

dictionary

where

the

given

name

is

defined

and

a

boolean

variable

telling

if

a

dictionary

was

found

or

not

Because

the

translator

already

checked

that

the

variable

is

defined

somewhere

we

can

always

disregard

this

boolean

value

Then

we

push

the

name

of

pascal

postscript

MO

-LRB-

Bytes

-RRB-

function

f

-LRB-

i

integer

-RRB-

integer

var

s

integer

begin

s

i

f

s

s

end

f

-LCB-

dict

begin

i

exch

def

s

def

s

i

add

def

r

s

s

mul

def

r

end

-RCB-

def

f

-LCB-

D

-LRB-

X'iX

's

's

r

s

s

r

-RRB-

-RCB-

Figure

Using

a

dictionary

as

an

activation

frame

pascal

postscript

MO

-LRB-

Bytes

-RRB-

procedure

a

var

b

integer

procedure

c

begin

b

b

end

begin

b

c

end

a

-LCB-

dict

begin

b

def

c

-LCB-

dict

begin

b

find

pop

b

b

add

put

end

-RCB-

def

b

def

c

end

-RCB-

def

a

-LCB-

D

-LRB-

c

-LCB-

D

-LRB-

bFP

b

-RRB-

-RCB-

c

-RRB-

-RCB-

Figure

Accessing

a

variable

in

a

outer

scope

the

variable

to

assign

to

evaluate

the

right

-LCB-

hand

side

of

the

expression

and

use

the

put

operator

to

store

the

value

at

the

right

place

Note

that

for

accessing

b

's

value

from

within

procedure

c

we

do

not

have

to

care

about

the

exact

level

of

nesting

i.e.

about

which

dictionary

contains

this

name

the

interpreter

will

find

it

for

us

by

scanning

the

dictionary

stack

Example

Passing

Arguments

By

Value

And

By

Reference

Finally

we

show

how

the

ptom

translator

generates

code

for

passing

arguments

by

reference

-LRB-

pascal

's

VAR

arguments

-RRB-

As

was

shown

in

the

previous

examples

arguments

for

a

procedure

are

pushed

on

the

operand

stack

before

calling

the

procedure

or

function

which

is

straight

forward

for

value

arguments

This

has

to

be

modified

in

the

case

we

want

to

pass

a

reference

instead

of

a

value

In

the

case

of

a

VAR

argument

we

pass

a

two-element

array

which

contains

the

dictionary

where

the

value

and

the

name

under

which

the

value

can

be

found

Since

in

MO

and

postscript

an

array

occupies

just

one

entry

on

the

operand

stack

we

can

use

the

old

push/pop

mechanism

for

passing

by-reference

parameters

too

Figure

shows

an

example

of

this

Note

that

in

this

example

the

variable

d

now

contains

an

array

The

loop

pascal

postscript

MO

-LRB-

Bytes

-RRB-

procedure

a

var

b

integer

procedure

c

-LRB-

var

d

integer

-RRB-

begin

d

end

begin

c

-LRB-

b

-RRB-

end

a

-LCB-

dict

begin

b

def

c

-LCB-

dict

begin

d

exch

def

d

-LCB-

-RCB-

forall

put

end

-RCB-

def

-LSB-

currentdict

b

-RSB-

c

end

-RCB-

def

a

-LCB-

D

-LRB-

c

-LCB-

D

-LRB-

X'dX

d

-LCB-

-RCB-

-RRB-

-RCB-

-LSB-

b

-RSB-

c

-RRB-

-RCB-

Figure

Passing

by-reference

parameters

over

this

variable

pushes

the

array

's

elements

on

the

operand

stack

such

that

they

are

perfectly

aligned

for

the

put

operator

that

comes

after

having

evaluated

the

right

-LCB-

hand

side

of

the

assignment

Of

course

it

is

the

translator

that

keeps

track

of

whether

a

variable

actually

holds

a

value

or

whether

it

only

contains

the

reference

to

it

Correspondingly

the

translator

generates

different

code

for

an

assignment

statement

Data

Mapping

Simple

pascal

data

types

like

integers

booleans

and

character

values

are

all

mapped

to

MO

integers

The

ptom

translator

generates

operations

which

assert

that

the

corresponding

ranges

are

respected

pascal-m

string

values

are

naturally

represented

by

MO

strings

although

the

translator

must

insert

index

adjustment

computations

because

in

pascal-m

strings

are

implicitly

defined

as

array

-LSB-

-RSB-

of

char

while

in

MO

all

arrays

start

with

an

index

of

String

concatenation

is

also

simple

because

MO

already

offers

a

concatenation

operator

The

translator

just

has

to

care

about

forcing

true

string

copies

after

concatenation

and

substring

operations

as

well

as

before

assignments

because

the

MO

interpreter

avoids

as

far

as

possible

to

physically

copy

string

fragments

which

may

lead

to

undesired

side

effects

at

the

level

of

pascal

pascal-m

arrays

are

mapped

to

MO

arrays

The

translator

inserts

for

all

element

accesses

the

required

index

offset

Accesses

to

elements

beyond

the

array

's

index

range

are

trapped

by

the

MO

interpreter

When

a

new

array

variable

is

instantiated

the

translator

has

to

generate

special

instructions

to

also

instantiate

every

element

according

to

the

element

's

base

type

-LRB-

in

native

code

compilers

one

just

allocates

a

free

memory

area

e.g.

on

the

stack

-RRB-

Finally

note

that

multidimensional

pascal

arrays

are

mapped

to

true

array

of

arrays

in

MO.

For

records

the

most

natural

way

of

representing

them

is

again

the

dictionary

data

structure

a

field

with

name

a

and

of

type

integer

for

example

becomes

a

dictionary

entry

where

the

name

a

is

associated

to

an

integer

value

As

with

the

elements

of

a

new

array

instance

it

is

necessary

to

define

all

entries

of

a

record

as

soon

as

a

new

record

instance

is

needed

Using

dictionaries

has

the

advantage

that

the

pascal

with

statements

is

very

easy

to

implement

it

suffices

to

push

the

record

dictionary

on

the

dictionary

stack

Of

course

the

translator

must

remember

this

when

it

assigns

a

new

value

to

a

variable

that

has

local

scope

but

for

which

the

associated

dictionary

is

not

the

topmost

dictionary

anymore

-LRB-

see

section

-RRB-

Assignments

of

record

and

array

variables

require

a

special

treatment

by

the

translator

A

simple

memory

copy

is

not

possible

in

postscript

or

MO

and

other

than

the

simple

types

MO

does

not

support

the

assignment

of

composite

types

Strings

as

we

already

mentioned

are

therefore

explicitly

duplicated

with

the

C

operator

However

this

operator

works

only

for

the

topmost

level

of

a

composite

object

for

example

a

duplicated

dictionary

is

an

independent

new

object

but

if

some

of

the

entries

refer

to

other

composite

objects

these

objects

were

not

copied

but

are

now

shared

by

the

two

copies

of

the

dictionary

The

ptom

translator

inserts

for

record

and

array

assignments

as

well

as

for

value

parameters

a

call

to

the

d

procedure

which

duplicates

even

nested

data

structures

This

procedure

is

not

part

of

MO

and

has

to

be

furnished

by

the

program

itself

in

fact

the

d

procedure

is

part

of

the

pascal-m

runtime

library

-LRB-

see

also

section

-RRB-

Dynamic

Memory

Allocation

The

ptom

translator

generates

code

that

automatically

allocates

variables

when

a

procedure

or

function

is

activated

-LRB-

called

-RRB-

A

lazy

allocation

of

these

variables

i.e.

waiting

until

the

variable

is

explicitly

assigned

to

by

the

programmer

does

not

work

because

of

the

way

we

make

use

of

dictionaries

In

section

we

showed

how

the

find

operator

is

used

to

locate

the

topmost

variable

instance

of

a

given

name

in

order

to

assign

to

it

a

value

Without

explicit

allocation

this

approach

would

not

work

anymore

In

pascal

is

the

programming

of

dynamic

memory

allocation

linked

to

pointer

types

By

using

the

new

-LRB-

ptrvar

-RRB-

and

dispose

-LRB-

ptrvar

-RRB-

the

programmer

can

request

the

-LRB-

dynamic

-RRB-

allocation

and

destruction

of

a

variable

instance

The

ptom

translator

uses

MO

keys

for

implementing

pointers

A

special

heap

dictionary

-LRB-

h

-RRB-

contains

all

associations

between

pointers

-LRB-

the

key

-RRB-

and

their

variable

instances

Figure

gives

an

example

how

this

works

Allocating

a

dynamic

variable

-LRB-

new

-RRB-

consists

in

creating

pascal

MO

-LRB-

Bytes

-RRB-

and

comments

var

p

integer

i

integer

begin

new

-LRB-

p

-RRB-

p

i

p

dispose

-LRB-

p

-RRB-

p

end

automatic

allocate

of

pointer

automatic

allocate

of

integer

p

create

a

random

ptr

entry

in

h

h

p

assignment

via

ptr

i

h

pG

dereference

the

ptr

variable

h

pU

undefine

the

ptr

in

h

is

defined

as

Figure

An

implementation

of

new

and

dispose

a

random

key

k

-LRB-

which

becomes

the

pointer

value

stored

in

the

pointer

variable

-RRB-

and

associating

it

to

a

newly

created

variable

instance

in

the

h

dictionary

Pointer

dereferencing

is

a

simple

lookup

of

this

key

in

the

h

dictionary

assignment

to

the

variable

pointed

to

by

a

pointer

also

refers

to

the

heap

dictionary

The

dispose

-LRB-

-RRB-

procedure

is

implemented

as

a

simple

undefine

i.e.

we

remove

the

entry

with

key

k

from

the

heap

dictionary

This

has

the

nice

property

that

stale

pointers

-LRB-

pointer

to

freed

memory

zones

-RRB-

automatically

generate

a

runtime

error

that

is

trapped

by

the

MO

interpreter

because

dispose

removes

the

entry

in

h

a

subsequent

G

-LRB-

get

-RRB-

due

to

the

dereferencing

of

the

stale

pointer

will

fail

is

represented

as

the

integer

value

Currently

there

is

no

support

for

trapping

assignments

to

a

pointer

-LRB-

which

would

be

simple

to

add

-RRB-

Attempts

to

access

a

variable

via

a

pointer

however

are

trapped

as

long

as

there

is

no

entry

for

the

value

in

the

heap

dictionary

-LRB-

such

an

entry

could

appear

when

one

assigns

a

value

to

a

pointer

-RRB-

Name

Space

Mapping

Classical

compilers

usually

drop

variable

and

procedure

names

once

the

parsing

and

code

generation

is

completed

-LRB-

except

for

symbol

tables

for

debugging

purposes

and

external

references

for

the

linker

phase

-RRB-

In

fact

variable

references

are

replaced

by

memory

addresses

In

our

approach

we

keep

the

names

and

use

them

for

all

references

to

variables

and

functions

The

ptom

translator

just

enforces

that

the

characters

used

in

the

names

are

compatible

with

the

lexical

rules

of

MO.

The

case

to

solve

are

digits

as

part

of

an

identifier

because

MO

limits

multi-character

identifiers

to

consist

of

lowercase

characters

a

z

only

The

ptom

translator

replaces

the

digits

etc.

found

in

pascal

identifiers

by

a

b

etc.

In

order

to

avoid

potential

name

clashes

when

the

underscore

character

is

inadvertently

used

at

the

pascal-m

level

underscores

are

also

escaped

i.e.

replaced

by

two

underscores

at

the

level

of

MO.

The

ptom

Runtime

Library

Most

of

the

time

the

ptom

translator

generates

plain

MO

instructions

without

considering

optimization

like

avoiding

frequent

repetition

of

more

complex

instruction

sequences

However

there

are

some

cases

where

factoring

out

common

instruction

sequences

is

adequate

or

even

mandatory

For

these

procedures

which

form

a

kind

of

small

run

-LCB-

time

library

the

following

names

were

defined

-LRB-

we

also

list

other

names

used

internally

by

the

runtime

-RRB-

ffl

d

dup

procedure

recursively

duplicates

composite

objects

like

arrays

or

records

ffl

e

reserved

for

a

possible

runtime

error

code

-LRB-

only

present

in

the

runtime

library

of

a

program

-RRB-

ffl

h

heap

dictionary

usually

an

empty

dictionary

at

start

time

but

this

may

also

point

to

the

global

MO

heap

ffl

r

function

's

return

value

this

special

name

is

used

in

functions

as

the

return

variable

-LRB-

using

the

function

's

own

name

is

not

possible

because

it

is

already

used

for

referencing

the

function

's

procedural

body

-RRB-

ffl

s

stringify

procedure

turn

a

character

-LRB-

integer

-RRB-

value

into

a

string

of

length

ffl

z

contains

miscellaneous

data

for

gracefully

halting

a

pascal-m

program

-LRB-

only

present

in

the

runtime

library

of

a

program

-RRB-

pascal-m

code

generated

MO

code

MSGRTYPE

a

VAR

b

string

MSGRTYPE

c

BEGIN

END

PROCEDURE

d

BEGIN

END

BEGIN

b

c

END

code

of

runtime-library

would

be

placed

here

instantiate

b

-LRB-

empty

string

-RRB-

'd

-LCB-

-LRB-

-RRB-

-RCB-

define

procedure

d

b

body

of

a

-LRB-

the

assignment

-RRB-

Figure

Code

for

messenger

types

is

not

output

at

declaration

time

This

runtime

library

is

automatically

produced

by

the

ptom

translator

Because

some

of

its

entries

are

useful

only

for

complete

pascal-m

programs

code

strings

of

messenger

types

do

not

include

all

elements

of

the

runtime

library

The

ptom

translator

omits

corresponding

entries

-LRB-

e

z

-RRB-

according

to

the

absence

of

a

program

keyword

Code

Output

The

introduction

of

the

msgrtype

declarations

leads

to

some

unusual

considerations

about

the

time

when

code

is

actually

output

The

reason

for

this

is

that

messenger

types

behave

like

string

constants

i.e.

they

are

inlined

into

the

code

at

the

places

where

the

types

are

referenced

which

is

different

from

the

place

where

they

are

declared

Between

these

places

a

pascal-m

compiler

must

store

the

messenger

type

string

in

internal

memory

In

the

ptom

translator

the

generation

of

code

that

instantiates

local

variables

of

a

procedure

or

messenger

type

is

also

delayed

but

now

for

implementation

reasons

The

case

to

consider

is

the

mix

of

messenger

type

declarations

and

the

declarations

of

local

variables

In

pascal-m

we

have

to

generate

explicit

variable

instantiation

code

as

was

explained

in

section

Consider

the

code

fragment

and

its

translation

in

MO

in

figure

The

goal

is

to

have

after

having

processed

the

messenger

type

a

a

single

string

in

memory

for

a

In

a

first

attempt

one

could

try

to

emit

code

as

soon

as

possible

when

we

see

the

MSGRTYPE

a

header

we

could

emit

the

pascal-m

library

when

we

see

the

VAR

b

string

line

we

would

generate

the

variable

instantiation

code

immediately

following

the

library

code

etc.

However

when

we

encounter

the

declaration

for

the

messenger

type

c

we

can

not

emit

its

code

right

now

it

has

to

be

inserted

only

when

it

is

referenced

in

the

body

of

messenger

a

So

we

would

have

to

store

the

code

for

c

in

another

memory

area

Therefore

we

delay

writing

code

for

messenger

a

until

the

start

of

its

body

so

that

we

can

use

the

linear

memory

area

for

first

writing

the

code

of

messenger

type

c

When

a

's

body

commences

we

just

have

pascal-m

code

generated

MO

code

PROGRAM

a

VAR

b

integer

PROCEDURE

c

BEGIN

END

PROCEDURE

d

BEGIN

END

BEGIN

END

code

of

runtime-library

would

be

placed

here

instantiate

variable

b

c

-LCB-

-LRB-

-RRB-

-RCB-

define

procedure

c

'd

-LCB-

-LRB-

-RRB-

-RCB-

define

procedure

d

body

of

a

VAR

b

integer

PROCEDURE

c

BEGIN

END

PROCEDURE

d

BEGIN

END

instantiate

variable

b

c

-LCB-

-LRB-

-RRB-

-RCB-

define

procedure

c

'd

-LCB-

-LRB-

-RRB-

-RCB-

define

procedure

d

Figure

Suppressing

the

generation

of

the

pascal-m

runtime

library

to

go

through

the

translator

's

data

structures

in

order

to

generate

the

instantiation

code

for

variables

-LRB-

and

the

prologue

if

a

were

a

procedure

etc

-RRB-

What

we

explained

here

for

local

messenger

type

declarations

also

applies

to

local

procedure

declarations

their

code

too

is

written

into

the

memory

area

before

the

outer

messenger

type

or

procedure

's

body

starts

This

means

that

we

duplicate

the

code

of

local

procedures

a

first

time

it

is

temporarily

written

when

the

declaration

is

encountered

and

then

we

copy

this

code

when

the

actual

body

of

the

outer

procedure

starts

It

would

be

possible

to

reclaim

the

memory

occupied

by

the

precipitately

emitted

code

of

local

procedures

by

shifting

the

finalized

messenger

type

code

over

it

but

this

has

not

been

implemented

yet

Two

Different

Translation

Modes

The

ptom

translator

can

be

used

to

produce

MO

code

for

small

procedures

and

functions

expressed

in

pascal-m

without

also

emitting

the

pascal-m

library

This

is

useful

when

one

assembles

a

set

of

ptom

generated

procedures

by

hand

and

one

does

not

want

to

manually

remove

the

runtime

library

included

by

default

This

behavior

is

selected

by

simply

omitting

the

usual

PROGRAM

name

header

line

-LRB-

no

main

body

is

then

allowed

however

-RRB-

Thus

both

pascal-m

code

fragments

of

figure

are

valid

compilation

units

Example

of

a

Messenger

written

in

pascal-m

The

following

example

shows

how

easy

it

is

to

write

a

concurrent

messenger

application

although

the

problem

it

solves

is

not

very

relevant

The

bubble

sort

algorithm

was

parallelized

such

that

several

messengers

can

compare

adjacent

element

of

an

array

concurrently

The

pascal-m

sources

of

the

bsort

procedure

are

given

in

appendix

A

figure

shows

the

possible

execution

paths

of

the

messengers

that

are

created

by

this

procedure

wait

queue

bsort

procedure

shared

memory

area

array

to

sort

array

of

process

queues

Figure

The

execution

paths

of

the

bsort

messengers

The

main

flow

of

execution

is

the

bsort

procedure

First

it

stores

the

array

to

sort

in

shared

memory

for

letting

the

concurrent

worker

messengers

access

it

After

some

more

initialization

work

-LRB-

setting

up

an

array

of

process

queue

for

concurrency

control

-RRB-

it

starts

a

first

sweeper

messenger

and

blocks

in

a

separate

process

queue

waiting

for

the

signal

that

sorting

is

done

The

sweeper

starts

comparing

the

elements

from

index

position

When

it

encounters

two

elements

in

wrong

sequence

they

are

swapped

and

the

sweeper

messenger

moves

to

the

next

array

position

The

first

time

a

sweeper

swaps

some

elements

it

creates

another

sweeper

messenger

that

starts

all

over

again

-LRB-

thus

the

number

of

concurrent

messengers

depends

on

the

data

in

the

array

-RRB-

Eventually

there

will

be

a

messenger

that

sweeps

the

full

array

without

encountering

any

element

pairs

to

swap

this

final

sweeper

unblocks

the

waiting

bsort

messenger

thread

Note

that

all

sweeper

messengers

proceed

in

an

array

of

process

queues

in

order

to

prevent

race

conditions

on

array

entries

Because

all

sweeper

messengers

have

the

same

task

a

messenger

instance

is

created

only

once

with

makemsgr

and

stored

in

the

shared

memory

area

When

a

sweeper

has

to

start

another

sweeper

process

it

can

use

this

pre-assembled

messenger

packet

The

pascal-m

code

for

the

bsort

procedure

in

appendix

A

furthermore

shows

that

the

sweeper

messenger

is

created

without

explicit

passing

of

arguments

-LRB-

i.e.

the

data

argument

is

an

empty

string

-RRB-

Nevertheless

requires

each

sweeper

messenger

a

key

under

which

it

can

access

the

data

in

the

shared

memory

area

This

key

is

implicitly

passed

in

the

messenger

's

start

queue

-LRB-

first

parameter

of

makemsgr

-RRB-

this

explains

why

the

sweeper

messenger

gets

its

current

process

queue

and

uses

this

key

for

accessing

the

record

in

the

shared

memory

area

It

is

the

same

queue

that

the

bsort

procedure

uses

for

storing

the

data

record

in

the

shared

memory

area

Discussion

The

ptom

translator

does

not

break

any

speed

records

nor

does

it

attempt

to

produce

perfect

MO

code

There

are

several

areas

where

one

could

enhance

it

ffl

ptom

does

no

optimization

unused

variables

and

procedures

dead

code

etc.

are

all

ignored

i.e.

they

nevertheless

generate

code

ffl

The

deeper

a

program

makes

recursive

calls

the

more

there

will

be

a

runtime

overhead

in

the

MO

interpreter

This

has

to

do

with

the

way

we

implement

activation

frames

by

pushing

local

dictionaries

on

the

dictionary

stack

This

means

that

the

MO

interpreter

must

traverse

the

complete

stack

every

time

it

has

to

resolve

the

name

even

of

a

builtin

MO

operator

Therefore

one

should

use

the

bind

operator

and

replace

MO

operator

names

by

the

dereferenced

operators

themselves

ffl

This

optimization

could

be

extended

to

also

bind

names

of

user-defined

pascal-m

procedures

-LRB-

most

variables

of

course

must

remain

unbound

because

of

the

dynamic/static

link

theme

-RRB-

ffl

A

simple

peephole

optimizer

would

eliminate

most

of

the

idempotent

instruction

sequences

-LRB-

e.g.

duplifying

a

string

result

twice

consecutive

initialization

and

assignment

etc.

-RRB-

More

of

conceptual

nature

is

the

observation

that

the

dichotomy

between

the

messenger

's

local

and

the

platform

's

shared

memory

is

difficult

to

express

in

a

natural

way

in

pascal-m

Our

view

is

that

one

should

not

mask

or

hide

the

explicit

import

and

export

of

data

-LRB-

currently

expressed

by

the

globaldef

and

globalget

procedures

-RRB-

It

would

be

nice

to

demonstrate

ptom

's

capacity

by

letting

the

translator

translate

itself

However

for

this

the

set

type

would

have

to

be

implemented

Finally

we

mention

that

the

current

ptom

translator

provides

virtually

no

debugging

aids

Using

the

H

operator

of

MO

-LRB-

stopped

in

postscript

-RRB-

it

would

be

easy

to

produce

code

that

can

catch

runtime

errors

and

by

including

line

number

information

that

could

indicate

where

the

error

happened

Such

support

functionality

could

for

example

be

controlled

by

Wirth

's

compiler

options

convention

-LRB-

-LCB-

D

-RCB-

-RRB-

Related

Work

MO

can

be

classified

in

several

ways

First

it

was

conceived

as

a

language

for

human

programmers

providing

all

necessary

functionality

of

a

high-level

language

-LRB-

no

memory

addresses

only

typed

data

values

etc

-RRB-

At

the

same

time

is

MO

used

as

the

machine

independent

representation

of

executable

programs

-LRB-

messengers

-RRB-

Finally

from

the

viewpoint

of

the

ptom

translator

MO

becomes

an

intermediate

language

Native

code

is

not

part

of

MO

but

the

MO

interpreter

has

been

used

to

support

the

execution

of

native

code

under

the

control

of

messengers

-LSB-

-RSB-

These

four

terms

span

the

field

of

work

that

is

related

to

messengers

and

mobile

code

in

general

ffl

Most

prominent

java

is

an

object

oriented

language

for

writing

applets

i.e.

programs

that

are

downloaded

to

and

executed

in

the

user

's

www

-LCB-

browser

-LSB-

-RSB-

The

javac

compiler

is

used

for

turning

high-level

java

code

into

byte

codes

for

a

stack-based

virtual

machine

-LRB-

java-VM

-RRB-

i.e.

an

interpreter

Programs

at

the

byte

code

level

have

not

the

same

flexibility

as

postscript

or

MO

code

metaprogramming

-LRB-

code

generation

at

runtime

-RRB-

heavily

depends

on

the

runtime

environment

i.e.

availability

of

compiler

access

at

runtime

-LRB-

see

e.g.

-LSB-

-RSB-

-RRB-

The

java

language

and

interpreter

has

been

used

to

implement

a

mobile

agent

systems

-LSB-

-RSB-

mobility

is

handled

in

a

transparent

way

not

influencable

by

the

agent

programmer

code

and

agent

state

travel

in

independent

transport

channels

ffl

telescript

which

predates

java

as

a

language

for

mobile

agents

has

a

similar

approach

with

two

languages

-LRB-

one

high-level

and

one

forth-like

low-level

telescript

-RRB-

but

was

designed

right

from

the

start

to

be

used

for

mobile

code

-LSB-

-RSB-

There

is

a

high-level

go

operator

that

triggers

an

agent

's

displacement

even

the

program

's

current

point

of

execution

is

transferred

ffl

tacoma

is

a

mobile

agent

system

that

is

based

on

the

scripting

language

Tcl

so

there

is

no

compiling

or

translating

involved

-LSB-

-RSB-

ffl

The

transfer

of

the

state

of

a

stack-based

program

is

examined

in

the

manual

for

the

Transportable

PostScript

-LRB-

Tps

-RRB-

language

-LSB-

-RSB-

ffl

For

an

overview

and

classification

of

still

other

languages

for

mobile

code

we

refer

to

-LSB-

-RSB-

The

use

of

intermediate

code

in

compilers

has

a

long

tradition

that

with

the

advent

of

mobile

code

is

suddenly

boosted

The

ucsd-pascal

produced

p-codes

for

a

easily

portable

interpreter

-LSB-

-RSB-

M-codes

are

used

as

intermediate

representation

of

programs

written

in

Clarity

C++

-LSB-

-RSB-

byte

codes

were

used

for

efficient

smalltalk

interpretation

-LSB-

-RSB-

Intermediate

code

representations

are

also

studied

for

on-the-fly

code

generation

-LSB-

-RSB-

Compiling

stack-based

languages

may

in

the

future

become

an

important

issue

for

mobile

code

for

a

study

on

forth

see

-LSB-

-RSB-

We

are

not

aware

of

any

translator/compiler

that

turns

pascal

code

into

postscript

or

any

other

high-level

stack-based

language

Acknowledgments

P.-A

Queloz

at

the

University

of

Geneva

provided

valuable

comments

on

a

first

draft

of

this

report

References

-LSB-

-RSB-

Adobe

Systems

Incorporated

editor

PostScript

Language

Reference

Manual

Addison-Wesley

fifteenth

edition

-LSB-

-RSB-

Kenneth

L.

Bowles

Microcomputer

problem

solving

using

PASCAL

Springer

-LSB-

-RSB-

G.

Cugola

C.

Ghezzi

G.

P.

Picco

and

G.

Vigna

Analyzing

mobile

code

languages

In

Proceedings

of

the

Workshop

on

Mobile

Object

Systems

ecoop

conference

July

-LSB-

-RSB-

L.

P.

Deutsch

and

A.

Schiffmann

Efficient

implementation

of

the

system

In

Proceedings

of

the

Symposium

on

the

Principles

of

Programming

Languages

-LSB-

-RSB-

Martin

Anton

Ertl

Implementation

of

Stack-Based

Languages

on

Register

Machines

PhD

thesis

Technische

Universit?at

Wien

April

-LSB-

-RSB-

Michael

Franz

Technological

steps

towards

a

software

component

industry

In

Programming

Languages

and

System

Architecture

March

-LSB-

-RSB-

General

Magic

Inc.

Telescript

Language

Reference

-LSB-

-RSB-

J.

Gosling

and

H.

McGilton

The

java

language

environment

A

white

paper

Technical

report

Sun

Microsystems

URL

ftp

-LSB-

-RSB-

Dennis

Heimbigner

The

Tps

Reference

Manual

Version

a.

University

of

Colorado

Arcadia

Project

March

Arcadia

Technical

Report

-LSB-

-RSB-

Tomy

Hetherington

An

introduction

to

the

extended

pascal

language

ACM

SIGPLAN

notices

-LRB-

-RRB-

-LCB-

November

-LSB-

-RSB-

Kathleen

Jensen

and

Niklaus

Wirth

pascal

User

Manual

and

Report

Springer

edition

-LSB-

-RSB-

D.

Johansen

et

al.

An

introduction

to

the

tacoma

distributed

system

Technical

report

Tromso

University

Computer

Science

Technical

Report

-LSB-

-RSB-

B.

T.

Lewis

L.

Peter

Deutsch

and

T.

C.

Goldstein

Clarity

MCode

A

retargetable

intermediate

representation

for

compilation

ACM

SIGPLAN

notices

-LRB-

-RRB-

-LCB-

March

-LSB-

-RSB-

Netscape

The

java

runtime

interface

version

URL

May

-LSB-

-RSB-

M.

Strasser

J.

Baumann

and

F.

Hohl

mole

A

java

based

mobile

agent

system

In

Proceedings

of

the

Workshop

on

Mobile

Object

Systems

ecoop

conference

July

-LSB-

-RSB-

Chr

F.

Tschudin

G.

Di

Marzo

Muhugusa

Murhimanya

and

J?urgen

Harms

Messenger

-LCB-

Based

Operating

Systems

July

Technical

report

-LRB-

Cahier

du

CUI

-RRB-

-LSB-

-RSB-

Christian

F.

Tschudin

On

the

Structuring

of

Computer

Communications

PhD

thesis

Universit?e

de

Gen?eve

Th?ese

No

-LSB-

-RSB-

Christian

F.

Tschudin

An

Introduction

to

the

MO

Messenger

Language

Technical

Report

Centre

Universitaire

d'Informatique

May

Cahier

du

CUI

-LSB-

-RSB-

Christian

F.

Tschudin

a

messenger

execution

environment

Usenet

newsgroup

comp.sources.unix

Vol

Issue

-LCB-

June

-LSB-

-RSB-

Niklaus

Wirth

From

Modula

to

Oberon

-LCB-

The

Programming

Language

Oberon

Technical

report

ETH

Eidgen?ossische

Technische

Hochschule

Z?urich

Departement

Informatik

Institut

f?ur

Computersysteme

November

Number

A

A

Messenger-Based

Parallel

Bubble

Sort

in

pascal-m

See

section

for

a

description

of

the

algorithm

and

figure

for

a

pictorial

view

of

the

execution

path

of

the

concurrent

sweeper

messengers

CONST

n

TYPE

eltype

integer

artype

ARRAY

-LSB-

n

-RSB-

OF

eltype

rec

RECORD

-LCB-

record

for

shared

memory

data

-RCB-

a

artype

-LCB-

array

to

sort

-RCB-

s

string

-LCB-

sweeper

messenger

code

-RCB-

q

ARRAY

-LSB-

n

-RSB-

of

key

-LCB-

array

of

process

queues

-RCB-

w

key

-LCB-

wait

queue

for

bsort

procedure

-RCB-

END

-LCB-

The

library

-LRB-

declarations

for

inlined

functions

and

procedures

-RRB-

would

go

here

see

the

Appendix

on

next

page

-RCB-

PROCEDURE

bsort

-LRB-

VAR

arr

artype

-RRB-

VAR

i

integer

k

key

r

rec

MSGRTYPE

sweeper

VAR

b

boolean

-LCB-

true

if

did

not

swap

elements

yet

-RCB-

i

integer

r

rec

x

eltype

BEGIN

-LCB-

sweeper

-RCB-

globalget

-LRB-

currentqueue

r

-RRB-

b

true

FOR

i

TO

DO

WITH

r

DO

BEGIN

queueenter

-LRB-

q

-LSB-

i

-RSB-

-RRB-

IF

a

-LSB-

i

-RSB-

a

-LSB-

i

-RSB-

THEN

BEGIN

x

a

-LSB-

i

-RSB-

a

-LSB-

i

-RSB-

a

-LSB-

i

-RSB-

a

-LSB-

i

-RSB-

x

IF

b

THEN

BEGIN

localsubmit

-LRB-

s

-RRB-

b

false

END

END

END

IF

b

THEN

queuestop

-LRB-

r.w

false

-RRB-

END

-LCB-

sweeper

-RCB-

BEGIN

-LCB-

bsort

-RCB-

k

newkey

WITH

r

DO

BEGIN

w

newkey

FOR

i

TO

n

DO

q

-LSB-

i

-RSB-

newkey

a

arr

s

makemsgr

-LRB-

k

sweeper

-RRB-

globaldef

-LRB-

k

r

-RRB-

queuestop

-LRB-

w

true

-RRB-

localsubmit

-LRB-

s

-RRB-

queueenter

-LRB-

w

-RRB-

END

queueleave

globalget

-LRB-

k

r

-RRB-

arr

r.a

globalundef

-LRB-

k

-RRB-

END

-LCB-

bsort

-RCB-

B

The

MO

library

of

inlined

procedures

The

following

declarations

of

functions

and

procedures

form

the

MO

library

that

every

pascal-m

program

has

to

include

if

it

wants

to

use

the

messenger

specific

functionality

of

the

underlying

MO

interpreter

-LRB-

submit

etc

-RRB-

If

the

ptom

translator

is

used

just

as

a

convenient

way

to

produce

MO

code

for

ordinary

-LRB-

non-mobile

code

-RRB-

applications

this

library

needs

not

to

be

included

Note

that

the

ptom

translator

replaces

all

calls

to

functions

and

procedures

of

the

MO

library

by

the

string

constant

given

behind

the

inline

keyword

If

such

an

inlined

function

is

used

many

many

times

in

a

program

it

may

be

useful

to

add

a

private

function

that

just

calls

the

inlined

library

function

This

is

less

efficient

but

results

in

only

one

copy

of

the

inlined

code

to

be

included

in

the

final

MO

code

Note

also

that

the

names

of

inlined

functions

do

not

appear

in

the

output

of

the

ptom

compiler

while

names

of

ordinary

functions

are

copied

as

is

If

code

size

is

a

concern

you

should

use

short

names

for

procedures

as

well

as

variables

-LCB-

lib

-RCB-

FUNCTION

code

string

INLINE

cod

FUNCTION

data

string

INLINE

dat

-LCB-

-RCB-

-LCB-

dat

-RCB-

FUNCTION

hostid

key

INLINE

hid

FUNCTION

newkey

key

INLINE

FUNCTION

notkey

-LRB-

k

key

-RRB-

key

INLINE

FUNCTION

globalknown

-LRB-

k

key

-RRB-

boolean

INLINE

XK

PROCEDURE

globaldef

-LRB-

k

key

a

any

-RRB-

INLINE

PROCEDURE

globalget

-LRB-

k

key

var

a

any

-RRB-

INLINE

-LCB-

-RCB-

PROCEDURE

globalundef

-LRB-

k

key

-RRB-

INLINE

XU

FUNCTION

currentqueue

key

INLINE

PROCEDURE

queueenter

-LRB-

k

key

-RRB-

INLINE

E

PROCEDURE

queuetimeout

-LRB-

k

key

millisec

integer

var

timeout

boolean

-RRB-

INLINE

-LCB-

-RCB-

PROCEDURE

queueleave

INLINE

V

PROCEDURE

queuestop

-LRB-

k

key

stpd

boolean

-RRB-

INLINE

Q

FUNCTION

makemsgr

-LRB-

k

key

mtype

string

mdata

string

-RRB-

string

INLINE

-LSB-

-RSB-

ctm

PROCEDURE

submit

-LRB-

k

key

msgr

string

-RRB-

INLINE

PROCEDURE

localsubmit

-LRB-

msgr

string

-RRB-

INLINE

nullX

FUNCTION

-LRB-

s

string

-RRB-

integer

INLINE

integer

-RCB-

-LCB-

Z

-RCB-

FUNCTION

-LRB-

s

string

-RRB-

string

INLINE

string

-RCB-

-LCB-

Z

-RCB-

FUNCTION

-LRB-

s

string

-RRB-

key

INLINE

key

-RCB-

-LCB-

Z

-RCB-

PROCEDURE

log

-LRB-

s

string

-RRB-

INLINE

-LCB-

log

-RCB-

HP

FUNCTION

-LRB-

i

integer

-RRB-

string

INLINE

-LCB-

false

-RCB-

-LCB-

true

-RCB-

FUNCTION

-LRB-

i

integer

-RRB-

string

INLINE

-LCB-

X

-RCB-

-LCB-

cte

-RCB-

FUNCTION

-LRB-

k

key

-RRB-

string

INLINE

cte

-LSB-

-RSB-

G

FUNCTION

random

integer

INLINE

cts

-LSB-

-RSB-

-LCB-

end

of

lib

-RCB-

communications messengers
mo
mobile software agents
pascal
postscript