The SALSA Lite (SALSA 2.0 Alpha) Programing Language
Java HTML Vim script Shell
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
benchmarks
common
compiler
examples
runtime
syntax
tests
.gitignore
README
build.sh
build_jar.sh
parse_and_build.sh

README

Building:
    Make sure the salsa_lite directory is in your classpath.

    To reparse the grammar (and re-generate the compiler files) and recompile salsa run the parse_and_build.sh script.  You'll need JavaCC (the Java Compiler Compiler -- http://javacc.java.net/) installed to be able to modify the grammar and update syntax.  Make sure that the directory you put javacc in is also in your CLASSPATH, and that javacc-version/bin is in your PATH, so you can run the ./parse_and_compile.sh.

    To just compile everything (without regenerating the compiler files), run the build.sh script.


Running the compiler:
    I recommend using the following alias in your profile to run the salsa compiler:

    alias slc='java salsa_lite.compiler.SalsaCompiler'


Running SALSA programs:
    After running the salsa compiler, then running the java compiler on the generated code:
    java <module>.<ActorName>
    You can set the number of stages used with the -Dnstages=<number of stages> system property. Setting the number of stages controls the number of threads used by the runtime.
    You can set the number of actor registries used with the -Dnregistries<number of registries> system property.  More registries increases the concurrency in serializing actors (because of local deep copy, remote message sending and migration).
    
    Please let us know at salsadev [at] cs.rpi.edu if the SALSA compiler does not display errors or warnings that the Java compiler does.


Syntax Highlighting:
    *   Syntax highlighting files for vim have been added in salsa_lite/syntax/
    *   On OS X, copy these to $HOME/.vim/syntax/
    *   Add the following to your $HOME/.vimrc file: 'au BufRead,BufNewFile *.salsa set filetype=salsa'
    *   TODO:
                Not sure if this was the best way to do it (using an edited version of Java's vim syntax file)
                Should add syntax highlighting files for emacs/others
                Need instructions for use on other operating systems


Notable changes from SALSA 1.x and before:
    *   The compiler now does static typechecking. Error reporting for the compiler has also been greatly improved.
    *   Generics are usable.
    *   All parameters are pass-by-copy.  The compiler will insert a deep copy statement around a mutable object (or array) before it is passed as the argument to a message, or passed as a result from a message.  Previous versions of SALSA had pass-by-reference for local messages, and pass-by-copy for remote messages; this change makes everything pass-by-copy.
    *   When importing Java objects, use (for example) 'import object java.util.LinkedList;'. Objects in java.lang are automatically imported.
    *   The token keyword (to signify the return/pass value of a previous message) is no longer used.  Instead of:
            'a<-m1() @ b<-m2(token);'
        It is possible to use the new nested message passing semantics:
            'b<-m2( a<-m1() );'
        or named tokens:
            'token SomeType value = a<-m1();'
            'b<-m2( value );'
    *   void is not a valid return type for a message handler any more, use ack (for acknowledgement).  This better represents the fact that message handlers that don't return a value can still be used in continuations, as they send an acknowledgement.
    *   return statements are now pass statements. ie: use 'pass 10;' instead of 'return 10;'
    *   currentContinuation is not used anymore, instead pass statements are used.  ie: 'a<-m1() @ currentContinuation;' is now 'a<-m1() @ pass;'.  This will pass an acknowledgement as the first class continuation.  If you want to pass the actual value, use: 'pass a<-m1();'.  It is also possible to pass a token: 'token ack t = a<-m1(); pass t;' which has the same semantics as 'pass a<-m1();'.
    *   Join blocks are no longer in the language.  Instead, the JoinDirector actor can be used, see salsa_lite/examples/threadring/ThreadRing.salsa for an example.
    *   StandardOutput and StandardError are first class actors.  To use them you must first create them, ie: 'StandardOutput standardOutput = new StandardOutput(); standardOutput<-println("something");'.  They will always print to the theater they were created at, even if the actor later migrates away from it (this allows mobile actors to easily print to multiple theaters). 
    *   There is no longer an act method, instead, for an actor that can be run from the command line, create a constructor that takes an array of strings. When that actor is run, the constructor with an array of Strings as the argument will be invoked. ie: 'behavior MyActor { void act(String[] arguments) { ... } }' is now 'behavior MyActor { MyActor(String[] arguments() { ... } }'. This reflects the fact that an actor is created when it is run, unlike in java where the main method is a static invocation (and does not create an object).
    *   Salsa now allows for tokens within expressions, eg: 'a<-m1( b<-m2() + c<-m3() * d<-m4() );' will work.
    *   This can also be combined with continuations, eg: 'e<-m5() @ a<-m1( b<-m2() + c<-m3() * d<-m4() ) @ f<-m6();'.
    *   And in pass statements, eg: 'pass a<-m1( b<-m2() + c<-m3() * d<-m4() );'.
    *   It is possible to invoke methods on self.  Because of this, to prevent ambiguity, for an actor to send a message or invoke a method on itself, use either 'self<-message();' or 'self.method();'.  Using 'message()' or 'method()' will not work (we might want to change this, maybe make sending a message the default).
    *   Local actors have automatic garbage collection (using Java's garbage collector), so long as MobileActors with references to them are not migrated to another theater; or as long as references to them are not passed within messages to remote or mobile actors at other theaters.
    *   You can specify what stage an actor runs on: 'NewActor na = new NewActor() at (<stage number>);' or 'NewActor na = newActor() at (StageService.getStage(anotherActor));' or 'NewActor na = new NewActor() at (StageService.getNewStage());'.
    *   Actors can implement 'StagedActor' which will make them run on their own stage. This is useful for actors with blocking behavior or long running message handlers that may starve other actors running on the same stage.
    *   RemoteActors (actors remotely accessible but not mobile) and MobileActors (actors that are mobile and remotely accessible) have been added, instead of UniversalActor
    *   A reference to a RemoteActor can be created as follows:
            MyActor a = reference MyActor called (<name>) at (<host>, <port>);
        or if the RemoteActor is local:
            MyActor a = reference MyActor called (<name>);
    *   NameServers are now first class RemoteActors, see salsa_lite.runtime.wwc.NameServer
    *   A reference to a MobileActor can be created via a NameServer instead of by using a host/port (as that would be unreliable).  Note that this returns a token:
            NameServer myNameServer = reference NameServer called (<name>) at (<host>, <port>);
            token MyMobileActor a = reference MyMobileActor called (<name>) using (myNameServer); //this has to be a token
        or:
            NameServer myNameServer = reference NameServer called (<name>) at (<host>, <port>);
            token MyMobileActor a = (token MyMobileActor)(myNameServer<-get(<name>));
        or:
            token MyMobleActor a = reference MyMobileActor called (<name>) using (reference NameServer at (<host>, <port>) called (<name>));
    *   A Remote or Mobile actor can be created remotely with similar semantics (again note that these return tokens):
            NameServer myNameServer = reference NameServer called (<name) at (<host>, <port>);
            token MyMobileActor myMobileActor = new MyMobileActor(...) called (<name>) using (myNameServer) at (<host>, <port>);
            token MyRemoteActor myRemoteActor = new MyRemoteActor(...) called (<name>) at (<host>, <port>);
        or locally:
            NameServer myNameServer = reference NameServer called (<name) at (<host>, <port>);
            MyMobileActor myMobileActor = new MyMobileActor(...) called (<name>) using (myNameServer);
            MyRemoteActor myRemoteActor = new MyRemoteActor(...) called (<name>);
       called and using are optional, however without a name and NameServer a MobileActor cannot migrate and without a name a RemoteActor cannot be referenced remotely.
   *    Actors can be created at a specific stage using the 'on' keyword as part of an allocation expression.  This can be combined with 'called', 'using' and 'at' for Remote and Mobile actors as well:
        MyMobileActor myMobileActor = new MyMobileActor(...) called (<name>) using (myNameServer) on (1); // puts it on stage 1
        token MyRemoteActor myRemoteActor = new MyRemoteActor(...) called (<name>) at (host, port) on (1); // puts it on stage 1
        MyActor myActor = new MyActor(...) on (3); // puts it on stage 1
        MyActor myActor = new MyActor(...) on (new SynchronousMailboxStage()); // puts it its own stage
            

BUGS:
    *   Check to see if having a pass statement within a try/catch block will cause first class continuations to not work.
    *   If a non-remote/mobile actor creates a mobile actor the initialize() method of the TransportService never gets called, so there's no server socket open to receive messages back from it.
    *   *NEW* - It's possible to write something like:
        ack m() {
            a<-m1() @
            b<-m2() @
        }
        Without the compiler throwing an error. It should not be possible to continue to nothing.
    *   *NEW* - It's possible to do:
        ack m() {
            System.out.println("blah") @
            ...
        }
        it's should not be possible to continue from a non-message send.
    *   Type checking for generics may not completely work not sure about things like <? super Something> and <T, E extends T, F extends E>.
    *   Syntax for generic methods needs to be added.
    *   Get interfaces working correctly.  They need special messages that know they were sent using an interface, so they invoke the correct message handler.
    *   Local actors are serailized the same either locally (because of a deepcopy) or remotely (because of message passing).  This could be made more efficient if we could figure out what stream the actor was being sent over, and storing it in a different registries, one for local, one for remote.  The local one would not need to get the local host and local port to calculate the hashcode, and could remove the actor after deserialization (for garbage collection).
    *   With remote message sending, we need to make sure the host is the same (eg, getting a reference to a remote actor via it's IP address or it's hostname should resolve to the same reference).
    *   Need to fix tests/SendAndPassTest -- 'token ack t = someMessage() @ pass;' or 'token ack t = someMessage() @ otherMessage()' isn't working.
    *   Need to fix wwc.Theater.  It creates two theaters.
    *   If a mobile actor is created on stage -1, and it migrates away, that stage is not cleaned up.
    *   Inheritance is broken again, need to fix it.  Looks like child actors aren't adding the basic Actor message handlers.
    *   If a joinDirector's resolveAfter message doesn't have a continuation a warning is printed to the screen at runtime.  This should be handled at compile time by the compiler.
    *   msg() @ if { ... } doesn't generate compiler error
    *   Actor a = ... @ Constructor(); doesn't generate compiler error

TODO:
    *   Add reference redirection for migrated actors -- if there is a remote reference pointing to an actor at another theater which migrates to a different theater, this reference needs to get updated.
    *   Add garbage collection support for MobileActors and Remote Actors (and local actors in a distributed setting) -- maybe restrict collection to unnamed actors.
    *   Report an error if trying to invoke a static method on a non-static object
    *   Allow self(...) and parent(...) as the first line within constructors to call another or the superclasses's constructor.
    *   Add support for access control.  All fields of an actor are private (and can't be shared due to no-shared memory), but methods and constructors should be able to be private, protected, public (or no modifier).
    *   Add a thread pool implementation, to compare the two for a publication.
    *   Need to implement a version of the runtime (SynchronousMailboxStage) that is fair. Right now an actor can enter an infinite loop or execute a blocking method which will starve the other actors on that stage.
    *   Implement token arrays in the compiler (have them use the language.ArrayDirector class).
    *   Implement message blocks, ie: { a<-m1(); b<-m2(); } @ { c<-m3(); d<-m4() }
    *   Add more compiler tests for generics 
    *   Add compiler tests for token arrays.
    *   Add compiler tests for message blocks.
    *   Add compiler tests for interfaces
    *   Add tests for nested expression directors, ie: a<-m( b<-m( c<-m() + d<-m(), e<-m() ) * f<-m() )
    *   Add tests for method invocations within expression directors, ie: a<-m( Math.log(o.something() + 10 * b<-m()) )
            -- Actualy: Cannot pass tokens to methods (this actually probably isn't a bug -- similar to not being able to pass tokens to conditionals).
    *   MyActor a = new MyActor() on stage(5) if there aren't 5 stages should make a new stage for it.