Difference between revisions of "SCL Tutorial"
Line 82: | Line 82: | ||
== Importing functionality from Java == | == Importing functionality from Java == | ||
+ | |||
+ | Java interfaces and classes can be imported to Java with annotated data definitions: | ||
+ | <pre> | ||
+ | @JavaType "java.util.regex.Pattern" | ||
+ | data Pattern | ||
+ | |||
+ | @JavaType "java.util.List" | ||
+ | data List a | ||
+ | </pre> | ||
+ | |||
+ | There are SCL macros for calling constructor and methods of the classes and | ||
+ | accessing fields. These macros are defined in http://www.simantics.org/Java. | ||
+ | <pre> | ||
+ | import "http://www.simantics.org/Java" as Java | ||
+ | |||
+ | compilePattern : String -> Pattern | ||
+ | compilePattern = Java.staticMethod "java.util.regex.Pattern.compile" | ||
+ | |||
+ | @JavaType "java.util.regex.Matcher" | ||
+ | data Pattern | ||
+ | |||
+ | createMatcher: Pattern -> String -> Proc Matcher | ||
+ | createMatcher = Java.methodProc "matcher" | ||
+ | |||
+ | matcherMatches: Matcher -> Proc Boolean | ||
+ | matcherMatches = Java.methodProc "matches" | ||
+ | |||
+ | matches : Pattern -> String -> Boolean | ||
+ | matches pattern text = runProc (createMatcher pattern text >>= matcherMatches) | ||
+ | </pre> | ||
+ | |||
+ | Another example: | ||
+ | <pre> | ||
+ | createArrayList : Proc (List a) | ||
+ | createArrayList = Java.constructorProc "java.util.ArrayList" | ||
+ | |||
+ | createArrayListWithCapacity : Integer -> Proc (List a) | ||
+ | createArrayListWithCapacity = Java.constructorProc "java.util.ArrayList" | ||
+ | |||
+ | sizeList : List a -> Proc Integer | ||
+ | sizeList = Java.methodProc "size" | ||
+ | |||
+ | getList : List a -> Integer -> Proc a | ||
+ | getList = Java.methodProc "get" | ||
+ | |||
+ | setList : List a -> Integer -> a -> Proc () | ||
+ | setList = Java.methodProc "set" | ||
+ | |||
+ | addList : List a -> a -> Proc Boolean | ||
+ | addList = Java.methodProc "add" | ||
+ | </pre> |
Revision as of 13:15, 24 August 2012
Getting started
The easiest way of getting started with SCL is to use SCL console that is included in almost all Simantics-based products. You can open the console by pressing ALT-SHIFT-q and then q and choosing "SCL Console" from the list of views.
SCL console works by executing commands you write into the input box in the bottom of the view. After the command has been written, it can be executed by pressing ENTER. However, this works only if the command contains no syntactic errors. Possible errors are highlighted in the input box and a description of the error is shown when you move mouse on top of the highlighted text.
Multiline commands can be written by pressing CTRL-ENTER (or just ENTER when the current command text contains errors). The command history can be browsed with CTRL-UP and CTRL-DOWN.
If the command you write into console results as an ordinary value, it is just printed to the console. Here are couple of examples you can try:
> 13 13 > 1+2 3 > sin 1 0.8414709848078965 > "Hello " + "world!" Hello world! > [1,3,5] [1, 3, 5]
You can also declare local variables to be used in the commands:
> x = 35 > y = 40 > x + y 75 > x * y 1400
Also new functions can be defined:
> f x = x * x > f 123 15129
If you write a command that has side-effects. It is executed in the console:
> print "Hello" ; print "world!" Hello world!
SCL is a dialect of Haskell and tutorials written for Haskell can be used for learning the details of the language. The main differences between the languages are the strict evaluation strategy used in SCL and somewhat different standard library. Some Haskell tutorials can be found at http://www.haskell.org/haskellwiki/Learning_Haskell.
Extending SCL environment
The SCL values, data types etc. that are available in expressions and commands are defined in SCL modules. Currently all SCL modules must be part of the product plugins (in the future, you can also write modules inside the models). Each module is identified by a URI.
SCL module is a text file ending with extension ".scl". The recommended place for modules is scl/ folder under plugin root, but also other directories can be used:
scl/Test1.scl:
fib :: Integer -> Integer fib x | x <= 1 = 1 | otherwise = fib (x-1) + fib (x-2)
A directory is declared as a SCL package with the following kind of extension defined in org.simantics.scl.runtime:
<extension point="org.simantics.scl.runtime.package"> <package URI="http://www.simantics.org/Tests" directory="scl"> </package> </extension>
The module is not automatically available in the console, but you must run an import declaration:
> import "http://www.simantics.org/Tests/Test1" as Test1 > Test1.fib 13 377
Import declaration can also be used in modules to refer other modules. Cyclic module dependencies are not allowed.
Importing functionality from Java
Java interfaces and classes can be imported to Java with annotated data definitions:
@JavaType "java.util.regex.Pattern" data Pattern @JavaType "java.util.List" data List a
There are SCL macros for calling constructor and methods of the classes and accessing fields. These macros are defined in http://www.simantics.org/Java.
import "http://www.simantics.org/Java" as Java compilePattern : String -> Pattern compilePattern = Java.staticMethod "java.util.regex.Pattern.compile" @JavaType "java.util.regex.Matcher" data Pattern createMatcher: Pattern -> String -> Proc Matcher createMatcher = Java.methodProc "matcher" matcherMatches: Matcher -> Proc Boolean matcherMatches = Java.methodProc "matches" matches : Pattern -> String -> Boolean matches pattern text = runProc (createMatcher pattern text >>= matcherMatches)
Another example:
createArrayList : Proc (List a) createArrayList = Java.constructorProc "java.util.ArrayList" createArrayListWithCapacity : Integer -> Proc (List a) createArrayListWithCapacity = Java.constructorProc "java.util.ArrayList" sizeList : List a -> Proc Integer sizeList = Java.methodProc "size" getList : List a -> Integer -> Proc a getList = Java.methodProc "get" setList : List a -> Integer -> a -> Proc () setList = Java.methodProc "set" addList : List a -> a -> Proc Boolean addList = Java.methodProc "add"