resource hello() write("Hello World") endPlace code in file.sr and compile with command:
sr file.sr
resource Example() procedure Test(v: int) returns r: int r := 2*v end var n: int writes("enter a positive integer: ") read(n) write("two times:", n, "is", Test(n)) end
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; var Dad: int; Nice := 5 + 3 #Nice is 8 Try := 5 + 3 #Try is 5 Dad := 5 \ + 3; #Dad is 8 /* This is also a comment */ end
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
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
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
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
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
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
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
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
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; grade: char) 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
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 can be assigned to, copied, and dereferenced
null is used to indicate a pointer value that points to no valid object
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
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
read(variable, variable,...)Reads standard input
Values be separated by white space
Read returns number of values successfully read
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
Two variables are same type if they have the same user defined or built in type name or appear on the same declaration
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
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
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 ifThe order in which the guards are evaluated is nondeterministic
do X < Y -> Y := Y - X [] Y < X -> X := X - Y odRepeat do until all guards evaluate to false
The order in which the guards are evaluated is nondeterministic
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
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
Do nothing, go on to next statement
Stop program and return value of expr to operating system
Return 0 if expr is not given
Terminates the smallest enclosing loop
Go to next iteration of enclosing loop
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) # Your code here end
val copy in defaultres copy out
var copy in and out
ref pass by address
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
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 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
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
resource main() optype f(int) returns int op factorial: f op sum: f procedure Tricky(var X: cap f) var test: int read(test) 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
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
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
Start up Stack
Start up Stack
12
End Stack
Done with user
resource foo body foo(x, y: int) write("Input is:", x, y) end foo
resource foo(x, y: int) write("input is:", x, y) end foo
resource DoIt() import foo var X: cap foo X := create foo(2,5) end
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
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
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
line 10 (extended by bottom): fatal: duplicate identifier: GetSam
line 10 (extended by test): fatal: duplicate identifier: GetSam
global Characters const TAB := '\t' const CR := 'r' end global Node type node = rec(value: char; link: ptr node) type head = ptr 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
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
global global_name
body global_name
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