## CS 662: Theory of Parallel Algorithms SR - Sequential Aspects

San Diego State University -- This page last updated February 1, 1996

## Sequential Part of SR

Hello World Example

```resource hello()
write("Hello World")
end

```
Place code in file.sr and compile with command:

sr file.sr

```
```
Example of IO & Procedure Call
```
resource Example()
procedure Test(v: int) returns r: int
r := 2*v
end

var n: int
writes("enter a positive integer: ")
write("two times:", n, "is", Test(n))
end
```

### Types, Variables and Assignments

#### Some Basics

Identifiers are sequences of letters, digits, and underscores.

First character must be a letter

Case sensitive

Newline or semicolons can be used to terminate declarations, statements, or expressions

```resource EndLines()

var Nice:	int
var Try:	int;

Nice := 5 +
3	#Nice is 8

Try  := 5
+ 3   #Try is 5

/* This is also a comment
*/

end

```

#### Basic Types

```resource BasicTypes()

var FirstInt:	int
var SecondReal:	real	:=	4.3
var ThirdChar:	char	:= 'a'
var FourthString:	string[20]	:= "Hi Mom"
var IsThisRight:	bool	:= true
var AreWeDone:	bool	:= false

var Guess := 3	#type deduced from value

const Fixed: int := 3	#needs an initial value
const Tight: float := 2* SecondReal

IsThisRight := true and
(false or not AreWeDone)

AreWeDone := IsThisRight xor AreWeDone
```
```	#operators are short-circuited
```

```	SecondReal:= FirstInt + 2  #convert int to real

FirstInt := 3.2;  			#compile error

end
```

#### Arrays

```resource ArrayTypes()

var FirstArray[10]:  int  #first index = 1

FirstArray[12] := 3
#runtime error: illegal subscript [12] of array with bounds [1:10]

var SecondArray[5,3]: real #2 dimensional

var ThirdArray[-2: 5]: bool #first index is -2

var Me[3]: int := (3, 2, 1)
#initialize array with constructor

var You[10]: int := ([6] 0, [4] 1)

var Trouble[10]: int := ([6] 0, [3] 1)
#runtime error: size mismatch

type Age = int

var Old: Age := 95;

type AnArrayOfInt = [0:100] int

var WhatIsThis: AnArrayOfInt

end

```

Array Slices
```
resource SlicedToast()

var BigArray[1:10, 1:10]: int := ([100] 0)

var SmallArray[1:10]: int := ([10] 1)

SmallArray[2:5] := BigArray[4,5:8]

BigArray[5,*] := SmallArray[*]

end

```
Forms of a Slice

Array[K:J] results in Array[K], Array[K+1], ..., Array[J]

Array[K:*] results in Array[K], ..., to end of array

Array[*:J] results in start of the array to Array[J]

Array[*] results in entire array

Restrictions Apply

A slice can not appear as operand of the swap operator

Slices can not be passed as reference parameters

Strings can not be assigned to a slice of strings if their maximum lengths differ

Assignments can be made to a single slice if an array, unless it is either sliced again or subscripted after being sliced

#### Bounds of Arrays

lb is built-in function which returns lower bound of the first dimension of an array

ub returns upper bound of the first dimension of an array

```var A[10]: int

var Q['a':'z', -2:4]

```
```lb(A)                   1                       lb(Q,1)                 'a'
ub(A)                   10                      lb(Q,2)                 -2
lb(Q)                   'a'                     ub(Q,2)                 4
ub(Q)                   'z'                     ub(A,1)                 10

```
```

```

#### Enumerations

```resource Count()

type color = enum(red, blue, yellow)

type StopLight = enum(red, yellow, green)
#Error, can not repeat enum literal

type Why = enum(do, this)
#Error, can not use reserved words (do)

var flower: color := blue

var CollegeAve: StopLight = red

write(pred(flower))		#prints 	0

write(high(StopLight))	#prints	2

write(min(blue,yellow))	#prints	1

end

```
Enumerations Functions

max maximum of N enumeration literals

min minimum of N enumeration literals

succ successor of an enumeration literal

pred predecessor of an enumeration literal

low smallest element of an enumeration type

high largest element of an enumeration type

#### Records

```resource recordThis()

var Me: rec(name: string[10]; age: int)

Me.name := "Roger"

Me.age := 15

type dims = rec( height, weight: real)

type person = rec( 	name: string[10];
measurements: dims;

var Test: dims := dims(132.2,  52.1)

var You: person :=
person("Sam", dims(21.3, 2.9), 'A')

You.measurements.height := 34.2

write(You.name)

end

```

#### Pointers

```
resource GetToThePoint()

var intPtr: ptr int

var Target: int := 5

intPtr := @Target  #@ - address of operator

intPtr^ := intPtr^ + 1  #^ dereference operator

Target := intPtr^

type Simple = rec(A, B: int)

var RecordPointer: ptr Simple

RecordPointer := new(Simple)

RecordPointer^.A := 10

free(RecordPointer)

var DoublePointer: ptr ptr real

DoublePointer := new(ptr real)

DoublePointer^ := new(real)

DoublePointer^^ := 5.5

write(DoublePointer^^)

end
```

#### Pointers Continued

```
```
Pointers can be assigned to, copied, and dereferenced

null is used to indicate a pointer value that points to no valid object

Any
```
resource WhatIsThis()

type Simple = rec(A, B: int)

var GenericPtr: ptr any

GenericPtr := new(int)

GenericPtr := new(real)

GenericPtr := new(Simple)

GenericPtr^.A := 5  #Compile error

var SimplePtr: ptr Simple

SimplePtr := GenericPtr

SimplePtr^.A := 5

end

```

Pointers of type any can only be assigned to and copied

#### Expressions

```resource A_Bit_Like_C()

var J, K, L: int

J := 1;  K := 2;  L := 3;

J := ++K			#preincrement K = 3, J = 3

J := L++			#postincrement L = 4, J = 3

J += 1				#same as J := J + 1

K :=: L			#interchange K and L

J := K :=: L		#what does this do?

end

```

#### Basic Input/Output

```read(variable, variable,...)

```

Values be separated by white space

Read returns EOF if the end-of-file is reached before any values are found

```

write(variable, variable, ...)

```
Writes variables to standard output, separated by space

Places return after last variable

```writes(variable, variable, ...)

```
Same as write, but no return at end

#### Type Equivalence

NAME EQUIVALENCE

Two variables are same type if they have the same user defined or built in type name or appear on the same declaration

STRUCTURAL EQUIVALENCE

Two variables are the seam type if they have the same structure

One has to determine underlying structure

Time consuming if have types of types of types....

type t = [1:20] int;

var a[1:20], b[1:20]: int;

var c[1:20]: int;

var d: t;

var e, f: rec( a: int; b: t );

```Name Equivalent
a and b,
e and f,
d and e.b and f.b

Structural Equivalent
a, b, c, d, e.b , f.b

```

#### Blocks

```resource Nested()

var Who: int := 5;

begin

var Where: int;

Where := Who;			#Where = 5

var Who: int := 10;

Where := Who;			#Where = 10

begin

var Who: real := 4.4;

Where := Who;  		#illegal

end;

Where := Who + 1;		#OK

end

#Where does not exist here

end

```

### Sequential Control

#### If

```if a < b 	-> write("Bad Value")
fi

if a < b 	-> write("Bad Value")
[] else 	-> write("Good Value")
fi

```
```if A < 10 -> B := 1
[] A > 32 -> B := 2
[] A = 60 -> B := 3
[] A > 50 -> B := 4
[] else   -> B := 5
if

```
The order in which the guards are evaluated is nondeterministic

#### Do

```do X < Y -> Y := Y - X
[] Y < X -> X := X - Y
od

```
Repeat do until all guards evaluate to false

The order in which the guards are evaluated is nondeterministic

#### For-All

```fa x := 1 to 50  ->
write(x)
af

fa x := 50 downto 1 ->
write(x)
af

fa x := 1 to 50 by 2 ->
write(x)
af

fa x := 1 to 50 st A[x] < 10 ->
write(x)
af

```

#### Nested Loops

```
fa x := 1 to 10, y := 1 to x ->
write(x, y)
af
```

is the same as:

```fa x := 1 to 10 ->
fa y := 1 to x ->
write(x, y)
af
af
```

skip
```
```
Do nothing, go on to next statement

stopstop(expr)
```
```
Stop program and return value of expr to operating system

Return 0 if expr is not given

exit

Terminates the smallest enclosing loop

next

Go to next iteration of enclosing loop

### Procedures

#### Declarations

```procedure factorial(x: int)returns result: int
if x <= 1 -> result := x
[] x >  1 -> result := x * factorial(x-1)
fi
end

procedure LongList(a, b, c : int; d : int)
end

```

#### Parameter Passing

```val	copy in	default
res	copy out
var	copy in and out
```

return values are passed by copy

```resource testParameter()

procedure test(ParamType x: int)
writes(x, ",')
x := 5
end

var n := 10
test(n)
write(n)
end

```
```ParamType	Output
val 		10, 10
res 		-808464433, 5
var 		10, 5
ref		10, 5
```
```

```

More Procedures
```
resource main()

procedure sort(ref a[*,*]: int)
fa k := lb(a) to ub(a) -1,
j := k + 1 to ub(a) st
a[j-1] > a[j] -> a[j-1] :=: a[j]
af

return				#ends function call

write("never reach here")

end sort

var x[1:20] : int
var y[40 : 100] : int
var z['a' : 'k'] : int

# code to initialize x, y, z

sort(x)

sort(y)

call sort(z)			#call is optional

end main

```

#### Op and Proc

Forward Declaration of Functions

op is the signiture of the procedure

proc is body of the procedure

```procedure Test(v: int) returns r: int
r := 2*v
end

Short for:

op Test(int) returns r: int

proc Test(v) returns r
r := 2*v
end

resource main()
op factorial(x: int) returns result : int
op sum(int) return int

write(factorial(3))
write(fact(5))

proc factorial(x) returns result
if x <= 1 -> result := x
[] x > 1 -> result := x*factorial(x-1)
fi
end factorial

proc sum(x) returns result
if x <= 1 -> result := x
[] x > 1 -> result := x + sum(x-1)
fi
end sum
end
```

#### Operation Types

```resource main()

optype f(int) returns int
op factorial: f
op sum: f

write(factorial(3))
write(sum(5))

proc factorial(x) returns result
if x <= 1 -> result := x
[] x > 1 -> result := x*factorial(x-1)
fi
end factorial

proc sum(x) returns result
if x <= 1 -> result := x
[] x > 1 -> result := x+sum(x-1)
fi
end sum

end main
```

#### Operation Capabilities

Pointers to Functions
```resource main()
optype f(int) returns int
op factorial: f
op sum: f

procedure Tricky(var X: cap f)
var test: int

if test < 10 -> X := factorial
[] test > 10 -> X := sum
fi
end

var What: cap f		#Pointer to a function

Tricky(What)

write(What(4))

proc factorial(x) returns result
if x <= 1 -> result := x
[] x > 1 -> result := x*factorial(x-1)
fi
end

proc sum(x) returns result
if x <= 1 -> result := x
[] x > 1 -> result := x+sum(x-1)
fi
end

end
```

### Resources and Globals

```
resource Stack
type result = enum(OK, OVERFLOW, UNDERFLOW)
op push(item: int) returns r: result
op pop(res item: int) returns r: result

body Stack(size: int)
var store[1:size]: int
var top: int := 0

proc push(item) returns r
if top < size ->
store[++top] := item
r := OK
[] top = size ->
r := OVERFLOW
fi
end

proc pop(item) returns r
if top > 0 ->
item := store(top--)
r := OK
[] top = 0 ->
r := UNDERFLOW
end

begin				#Optional initialization code
write("Start up Stack")
end

final  				#Optional final code
write("End Stack")
end
end
```

Using a Resource
```

resource StackUser()
import Stack			#Stack from previous page

var x: Stack.result
var s1, s2: cap Stack

s1 := create Stack(10)
s2 := create Stack(20)

s1.push(4)
s1.push(12)
s2.push(3)

if (x := s1.pop(y)) = OK -> write(y)
[] else -> write("Bad return call")
fi

final
destroy s1
write("Done with user")
end
end

```
Output

Start up Stack

Start up Stack

12

End Stack

Done with user

More Resources
Full foo
```resource foo
body foo(x, y: int)
write("Input is:", x, y)
end foo

```
Short foo
```resource foo(x, y: int)
write("input is:", x, y)
end foo
```

Using foo

```resource DoIt()
import foo
var X: cap foo

X := create foo(2,5)
end
```

Bank Example
```resource BankAccount
op transaction(amount: real)
op getBalance() returns x: real
#No variables in spec

body BankAccount(initialDeposit: real)

var balance: real

proc getBalance() returns x
x := balance
end getBalance
#Can't use balance for name of proc and resource variable

proc transaction(amount)
balance := balance + amount
end transaction

begin
balance := initialDeposit
end

end BankAccount

resource test()

import BankAccount
var Mine: cap BankAccount

Mine := create BankAccount(10)
write(Mine.getBalance())
end

```

#### Extending Resources

Declaration Inheritance
```
resource BankAccount
#Same as previous page
end BankAccount

resource CheckingAccount
extend BankAccount
op check(amount: real)

body CheckingAccount(initialDeposit: real)

var balance: real

proc getBalance() returns x
x := balance
end getBalance

proc transaction(amount)
balance := balance + amount
end transaction

proc check(amount)
transaction(- amount)
end check

begin
balance := initialDeposit
end
end

resource test()
import CheckingAccount
var Mine: cap CheckingAccount
Mine := create CheckingAccount(10)
write(Mine.getBalance())
end
```

Multiple Inheritance
```resource left
op GetSam(X: int)
body left()
proc GetSam(X)
write("Left")
end
end

resource right
op GetSam(X: int)
body right()
proc GetSam(X)
write("Right")
end
end

resource bottom
extend left, right
body bottom()
proc GetSam(X)
X := 5
end
end

resource test
import bottom
write("Done")
end

```
Compile Error
```
```
line 10 (extended by bottom): fatal: duplicate identifier: GetSam

line 10 (extended by test): fatal: duplicate identifier: GetSam

#### Globals

```
global Characters
const TAB := '\t'
const CR	:= 'r'
end

global Node
type node =
type tail = ptr node
end

global Matrix
const N := 20
var m[N,N]: int := ([N] ([N] 0))
end

resource foo()
import Characters, Node, Matrix
var x: Node.node
var y: node 		#if name "node" is unique

if x.value = Characters.TAB -> null fi

Matrix.m[3,4] = 23
end
```

Only One Copy of a Global
```global One
var X: int := 0
end

resource A
import One
op increase()
body A()
proc increase()
X++
end
end

resource B
import One
op writeX()
body B()
proc writeX()
write(X)
end
end

resource foo()
import A, B
var You, Me: cap A
var Sam: cap B
You := create A()
Me := create A()
Sam := create B()
You.increase()
Me.increase()
Sam.writeX()
end
```

General Form of Global

global global_name

imports
declarations

body global_name

imports
declarations, statments, procs
final
clean up code
end
end
SR Performance

```Experiment					SGI 340	Sun IPX
Local Procedure Call				1.7	2.7
Dynamic Process - create empty process		50.0	171.9
Asynchronous message with context switch 	35.0 	122.5
Rendezvous 					54.0	202.9

```

Time in microseconds