183 lines
5.8 KiB
PSL
183 lines
5.8 KiB
PSL
// This is a comment
|
|
|
|
// 1. Basics
|
|
|
|
// Functions
|
|
func Add(X : Univ_Integer; Y : Univ_Integer) -> Univ_Integer is
|
|
return X + Y;
|
|
end func Add;
|
|
// End of line semi-colons are optional
|
|
// +, +=, -, -=, *, *=, /, /=
|
|
// all do what you'd expect (/ is integer division)
|
|
|
|
// If you find Univ_Integer to be too verbose you can import Short_Names
|
|
// which defines aliases like Int for Univ_Integer and String for Univ_String
|
|
import PSL::Short_Names::*, *
|
|
|
|
func Greetings() is
|
|
const S : String := "Hello, World!"
|
|
Println(S)
|
|
end func Greetings
|
|
// All declarations are 'const', 'var', or 'ref'
|
|
// Assignment is :=, equality checks are ==, and != is not equals
|
|
|
|
func Boolean_Examples(B : Bool) is
|
|
const And := B and #true // Parallel execution of operands
|
|
const And_Then := B and then #true // Short-Circuit
|
|
const Or := B or #false // Parallel execution of operands
|
|
const Or_Else := B or else #false // Short-Cirtuit
|
|
const Xor := B xor #true
|
|
var Result : Bool := #true;
|
|
Result and= #false;
|
|
Result or= #true;
|
|
Result xor= #false;
|
|
end func Boolean_Examples
|
|
// Booleans are a special type of enumeration
|
|
// All enumerations are preceded by a sharp '#'
|
|
|
|
func Fib(N : Int) {N >= 0} -> Int is
|
|
if N <= 1 then
|
|
return N
|
|
else
|
|
// Left and right side of '+' are computed in Parallel here
|
|
return Fib(N - 1) + Fib(N - 2)
|
|
end if
|
|
end func Fib
|
|
// '{N >= 0}' is a precondition to this function
|
|
// Preconditions are built in to the language and checked by the compiler
|
|
|
|
// ParaSail does not have mutable global variables
|
|
// Instead, use 'var' parameters
|
|
func Increment_All(var Nums : Vector<Int>) is
|
|
for each Elem of Nums concurrent loop
|
|
Elem += 1
|
|
end loop
|
|
end func Increment_All
|
|
// The 'concurrent' keyword in the loop header tells the compiler that
|
|
// iterations of the loop can happen in any order.
|
|
// It will choose the most optimal number of threads to use.
|
|
// Other options are 'forward' and 'reverse'.
|
|
|
|
func Sum_Of_Squares(N : Int) -> Int is
|
|
// The type of Sum is inferred
|
|
var Sum := 0
|
|
for I in 1 .. N forward loop
|
|
Sum += I ** 2 // ** is exponentiation
|
|
end loop
|
|
end func Sum_Of_Squares
|
|
|
|
func Sum_Of(N : Int; Map : func (Int) -> Int) -> Int is
|
|
return (for I in 1 .. N => <0> + Map(I))
|
|
end func Sum_Of
|
|
// It has functional aspects as well
|
|
// Here, we're taking an (Int) -> Int function as a parameter
|
|
// and using the inherently parallel map-reduce.
|
|
// Initial value is enclosed with angle brackets
|
|
|
|
func main(Args : Basic_Array<String>) is
|
|
Greetings() // Hello World
|
|
Println(Fib(5)) // 5
|
|
// Container Comprehension
|
|
var Vec : Vector<Int> := [for I in 0 .. 10 {I mod 2 == 0} => I ** 2]
|
|
// Vec = [0, 4, 16, 36, 64, 100]
|
|
Increment_All(Vec)
|
|
// Vec = [1, 5, 17, 37, 65, 101]
|
|
// '|' is an overloaded operator.
|
|
// It's usually used for concatenation or adding to a container
|
|
Println("First: " | Vec[1] | ", Last: " | Vec[Length(Vec)]);
|
|
// Vectors are 1 indexed, 0 indexed ZVectors are also available
|
|
|
|
Println(Sum_Of_Squares(3))
|
|
|
|
// Sum of fibs!
|
|
Println(Sum_Of(10, Fib))
|
|
end func main
|
|
|
|
// Preceding a type with 'optional' allows it to take the value 'null'
|
|
func Divide(A, B, C : Real) -> optional Real is
|
|
// Real is the floating point type
|
|
const Epsilon := 1.0e-6;
|
|
if B in -Epsilon .. Epsilon then
|
|
return null
|
|
elsif C in -Epsilon .. Epsilon then
|
|
return null
|
|
else
|
|
return A / B + A / C
|
|
end if
|
|
end func Divide
|
|
|
|
// 2. Modules
|
|
// Modules are composed of an interface and a class
|
|
// ParaSail has object orientation features
|
|
|
|
// modules can be defined as 'concurrent'
|
|
// which allows 'locked' and 'queued' parameters
|
|
concurrent interface Locked_Box<Content_Type is Assignable<>> is
|
|
// Create a box with the given content
|
|
func Create(C : optional Content_Type) -> Locked_Box;
|
|
|
|
// Put something into the box
|
|
func Put(locked var B : Locked_Box; C : Content_Type);
|
|
|
|
// Get a copy of current content
|
|
func Content(locked B : Locked_Box) -> optional Content_Type;
|
|
|
|
// Remove current content, leaving it null
|
|
func Remove(locked var B : Locked_Box) -> optional Content_Type;
|
|
|
|
// Wait until content is non-null, then return it, leaving it null.
|
|
func Get(queued var B : Locked_Box) -> Content_Type;
|
|
end interface Locked_Box;
|
|
|
|
concurrent class Locked_Box is
|
|
var Content : optional Content_Type;
|
|
exports
|
|
func Create(C : optional Content_Type) -> Locked_Box is
|
|
return (Content => C);
|
|
end func Create;
|
|
|
|
func Put(locked var B : Locked_Box; C : Content_Type) is
|
|
B.Content := C;
|
|
end func Put;
|
|
|
|
func Content(locked B : Locked_Box) -> optional Content_Type is
|
|
return B.Content;
|
|
end func Content;
|
|
|
|
func Remove(locked var B : Locked_Box) -> Result : optional Content_Type is
|
|
// '<==' is the move operator
|
|
// It moves the right operand into the left operand,
|
|
// leaving the right null.
|
|
Result <== B.Content;
|
|
end func Remove;
|
|
|
|
func Get(queued var B : Locked_Box) -> Result : Content_Type is
|
|
queued until B.Content not null then
|
|
Result <== B.Content;
|
|
end func Get;
|
|
end class Locked_Box;
|
|
|
|
func Use_Box(Seed : Univ_Integer) is
|
|
var U_Box : Locked_Box<Univ_Integer> := Create(null);
|
|
// The type of 'Ran' can be left out because
|
|
// it is inferred from the return type of Random::Start
|
|
var Ran := Random::Start(Seed);
|
|
|
|
Println("Starting 100 pico-threads trying to put something in the box");
|
|
Println(" or take something out.");
|
|
for I in 1..100 concurrent loop
|
|
if I < 30 then
|
|
Println("Getting out " | Get(U_Box));
|
|
else
|
|
Println("Putting in " | I);
|
|
U_Box.Put(I);
|
|
|
|
// The first parameter can be moved to the front with a dot
|
|
// X.Foo(Y) is equivalent to Foo(X, Y)
|
|
end if;
|
|
end loop;
|
|
|
|
Println("And the winner is: " | Remove(U_Box));
|
|
Println("And the box is now " | Content(U_Box));
|
|
end func Use_Box;
|