.. index:: Scolvo script ************* Scolvo Script ************* The Scolvo language is a special purpose programming language, designed to be able to define Scolvo applications on all client types. It has JSON as it's first class data model, and borrows concepts from a wide range of languages from JavaScript through Java to Python. The basic concept is that Scolvo is: - dynamically typed, - interpreted, - and designed for rapid application development. The core interpreter can be easily extended with new functions implemented in Java. Numbers ~~~~~~~ Numbers in Scolvo script are represented as BigIntegers and BigDecimals. Operations on them are done, by using the least compatible type to represent the result. For example: .. code-block:: scolvoscript :caption: Example number operations :linenos: // BigInteger / BigInteger = BigInteger var first = 12 / 3; // BigInteger modulus BigInteger = BigInteger var second = 12 % 5; .. Variables ~~~~~~~~~ The keyword *var* is used to define variables. Each variable must be given a name and an initial value using the *=* equals operator. A variable name must adhere to the definition of Java Identifier naming rules. .. code-block:: scolvoscript :caption: Example variable declaration :linenos: var first = 12; .. Variables can be used in place of constants in expressions, like: .. code-block:: scolvoscript :caption: Variables in expression :linenos: var first = 12; var second = 23; var sumOfNumbers = first + second; .. Variable values can be later reassigned: .. code-block:: scolvoscript :caption: Reassign variable :linenos: var first = 12; // ... first = 34; .. If a variable is not defined before first use an exception is thrown: .. code-block:: text :caption: Undeclared variable usage :linenos: com.scolvo.core.interpreter.symbols.SemanticException: Variable 'third' must be declared before first use. at com.scolvo.core.interpreter.visitors.SymbolTableBuilder.visit(SymbolTableBuilder.java:84) at com.scolvo.core.interpreter.ast.Variable.accept(Variable.java:26) at com.scolvo.core.interpreter.visitors.SymbolTableBuilder.visit(SymbolTableBuilder.java:58) at com.scolvo.core.interpreter.ast.Script.accept(Script.java:22) at com.scolvo.core.interpreter.Interpreter.eval(Interpreter.java:153) at com.scolvo.core.interpreter.Main.runCommandLine(Main.java:36) at com.scolvo.core.interpreter.Main.main(Main.java:12) .. Strings ~~~~~~~~~ Textual data, known as String datatype can be used in Scolvo as defined in the Java language between " characters. .. code-block:: scolvoscript :caption: Definition of a String variable :linenos: var stringVar = "Hello, World"; .. To ease the use of String variables, Scolvo defines an overloaded + operator for concatenation: .. code-block:: scolvoscript :caption: Using + operator :linenos: var stringPart1 = "Hello"; var stringPart2 = "World"; var concatenated = stringPart1 + ", " + stringPart2; .. The concatenation works also when non-String operands are present: .. code-block:: scolvoscript :caption: Using + operator with non-String operand :linenos: var concatenated = "John's age is: " + 12; .. Control statements ~~~~~~~~~~~~~~~~~~ Only two of the main general control statement patterns are implemented yet if and for, but using these all the other statements can be achieved. if-then-else ============ The *if* statements are used to define branching in the control flow depending on the state of the current context. The syntax is similar to Java and JavaScript. For example basic truth test: .. code-block:: scolvoscript :caption: If control statement :linenos: var test = 12; if (test == 12) { info("Equals 12"); } .. Testing on truth and processing else when condition not met: .. code-block:: scolvoscript :caption: If-else control statement :linenos: var test = 12; if (test == 13) { info("Equals 13"); } else { info("Not equals 13"); } .. Testing for multiple conditions results in the first true branch being activated: .. code-block:: scolvoscript :caption: If-else if-else control statement :linenos: var test = 12; if (test == 11) { info("Equals 11"); } else if (test == 12) { info("Not equals 12"); } else if (test == 12) { info("Also equals 12"); } else { info("No condition is matched"); } .. for (...;...;...) ... ===================== In Scolvo script, for statements are defined as classic C-style for loops with the syntax: *For syntax* .. for (initial settings ; condition ; post operation ) { list of statements } Where - **initial settings**: Optional. Any variable initialization that needs to be done before running the for loop. - **condition**: Optional. Condition that has to be matched for the loop to enter next cycle. - **post operation**: Optional. Any expression that has to be executed right after the list of statements are executed and before the condition is checked. - **list of statements**: Optional. Any valid sequence of Scolvo program elements. (variable declarations, control statements, function calls, function declarations) The following statements are all valid, but not necessarily useful examples of for statement: An endless for loop that does nothing: .. code-block:: scolvoscript :caption: Endless for loop :linenos: for ( ; ; ) {} .. A classic example: .. code-block:: scolvoscript :caption: Classic for example :linenos: for (var i = 0; i < 12; i += 1) { info("Current loop is: " + i); } .. Initializing variables before for loop: .. code-block:: scolvoscript :caption: For using pre-.defined variables :linenos: var i = 0; for (; i < 12; i += 1) { info("Current loop is: " + i); } .. Modifing variables that are operands of the condition inside the loop body: .. code-block:: scolvoscript :caption: For using pre-.defined variables :linenos: var i2 = 0; for (; i2 < 12; ) { info("Current loop is: "+i2); i2 += 1; } .. There are a few unimplemented features that makes Scolvo for loops differ from other languages: - **++** and **-** prefix and suffix operators are not defined yet - **break** operation is not implemented, so breaking out of loops is possible only through the condition becoming false try-catch-finally and throw =========================== In Scolvo script the *try-catch-finaly* statements are defined as classic Java style syntax (the usage of the **finally** branch is optional): .. code-block:: scolvoscript :caption: try-catch-finally examples :linenos: try { // statements } catch(Exception e) { // statements } catch(Exception1 e) { // statements } finally { // statements } try { throw NotFoundException; } catch(NotFoundException e) { // statements } try { // statements } catch(com.scolvo.core.interpreter.InterpreterException e) { // statements } Declaring functions =================== In Scolvo script, like in most programming languages, constructs that wrap common functionality into reusable components are called *functions*. Function are defined by the **function** keyword followed by the function name, that must adhere to the definition of `Java Identifier naming rules `__, after that between parenthesis a list of formal parameters and ended by a block statement. .. code-block:: scolvoscript :caption: function decalaration example :linenos: function funcName() { // statements } For example a function that calculates fibonacci number on a given position: .. code-block:: scolvoscript :caption: Fubonacci function example :linenos: function calculateFibonacci(count) { if (count == 0) { return 1; } else if (count == 1) { return 1; } return calculateFibonacci(count - 1) + calculateFibonacci(count - 2); } Invoking (calling) a function is done by the function name followed by actual list of parameters: .. code-block:: scolvoscript :caption: Usage of example Fibonacci calcualtor :linenos: function calculateFibonacci(count) { if (count == 0) { return 1; } else if (count == 1) { return 1; } return calculateFibonacci(count - 1) + calculateFibonacci(count - 2); } var result = calculateFibonacci(5); Some rules of function definitions: - The formal parameter list can be empty, but paranthesis is required. For example: function noParam() { doSomething } - The invocation the actual parameter list must have the same size as the formal parameter list, like in Java. There's no way to have more arguments, and have access to the extra in some variables like in JavaScripts arguments. - The parameters are positional and cannot have default values. No such construct as Python's default arguments and keyword arguments. Scoping =================== Scoping is a key part of most programming languages. It means that any entity defined is available for use in the block it was defined in and it's nested blocks, unless redefined there. A block is a statement which starts with a { and ends with the matching }. For example, let's create a demo of nested blocks to better understand the concept: .. code-block:: scolvoscript :caption: Example of nested blocks :linenos: // here we define a global variable available to all sub scopes var global = 1; // left curly bracket defines the start of a new scope function doSomething() { info(global); var local = 2; // prints 2 info(local); global = 3; info(global); } // prints 1 info(global); // prints 1, 2, 3 doSomething(); // prints 3 info(global); The same is true for all constructs that contain blocks as their building elements like *if*, *else if*, *else* and *for*. The Scolvo script functions behave like variables when it comes to scoping. This means that a function defined inside the body of the function cannot be invoked from outside, not even with the classic object property notation (function.internalFunction).