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:

Example number operations
1// BigInteger / BigInteger = BigInteger
2var first = 12 / 3;
3// BigInteger modulus BigInteger = BigInteger
4var 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.

Example variable declaration
1var first = 12;

Variables can be used in place of constants in expressions, like:

Variables in expression
1var first = 12;
2var second = 23;
3var sumOfNumbers = first + second;

Variable values can be later reassigned:

Reassign variable
1var first = 12;
2// ...
3first = 34;

If a variable is not defined before first use an exception is thrown:

Undeclared variable usage
1com.scolvo.core.interpreter.symbols.SemanticException: Variable 'third' must be declared before first use.
2  at com.scolvo.core.interpreter.visitors.SymbolTableBuilder.visit(SymbolTableBuilder.java:84)
3  at com.scolvo.core.interpreter.ast.Variable.accept(Variable.java:26)
4  at com.scolvo.core.interpreter.visitors.SymbolTableBuilder.visit(SymbolTableBuilder.java:58)
5  at com.scolvo.core.interpreter.ast.Script.accept(Script.java:22)
6  at com.scolvo.core.interpreter.Interpreter.eval(Interpreter.java:153)
7  at com.scolvo.core.interpreter.Main.runCommandLine(Main.java:36)
8  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.

Definition of a String variable
1var stringVar = "Hello, World";

To ease the use of String variables, Scolvo defines an overloaded + operator for concatenation:

Using + operator
1var stringPart1 = "Hello";
2var stringPart2 = "World";
3var concatenated = stringPart1 + ", " + stringPart2;

The concatenation works also when non-String operands are present:

Using + operator with non-String operand
1var 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:

If control statement
1var test = 12;
2if (test == 12) {
3   info("Equals 12");
4}

Testing on truth and processing else when condition not met:

If-else control statement
1var test = 12;
2if (test == 13) {
3  info("Equals 13");
4} else {
5  info("Not equals 13");
6}

Testing for multiple conditions results in the first true branch being activated:

If-else if-else control statement
 1var test = 12;
 2if (test == 11) {
 3  info("Equals 11");
 4} else if (test == 12) {
 5  info("Not equals 12");
 6} else if (test == 12) {
 7  info("Also equals 12");
 8} else {
 9  info("No condition is matched");
10}

for (…;…;…) …

In Scolvo script, for statements are defined as classic C-style for loops with the syntax:

For syntax

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:

Endless for loop
1for ( ; ; ) {}

A classic example:

Classic for example
1for (var i = 0; i < 12; i += 1) {
2  info("Current loop is: " + i);
3}

Initializing variables before for loop:

For using pre-.defined variables
1var i = 0;
2for (; i < 12; i += 1) {
3  info("Current loop is: " + i);
4}

Modifing variables that are operands of the condition inside the loop body:

For using pre-.defined variables
1var i2 = 0;
2for (; i2 < 12; ) {
3  info("Current loop is: "+i2);
4  i2 += 1;
5}

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):

try-catch-finally examples
 1try {
 2  // statements
 3} catch(Exception e) {
 4  // statements
 5} catch(Exception1 e) {
 6  // statements
 7} finally {
 8  // statements
 9}
10
11try {
12  throw NotFoundException;
13} catch(NotFoundException e) {
14  // statements
15}
16
17try {
18  // statements
19} catch(com.scolvo.core.interpreter.InterpreterException e) {
20  // statements
21}

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.

function decalaration example
1function funcName() {
2  // statements
3}

For example a function that calculates fibonacci number on a given position:

Fubonacci function example
1function calculateFibonacci(count) {
2  if (count == 0) {
3    return 1;
4  } else if (count == 1) {
5    return 1;
6  }
7  return calculateFibonacci(count - 1) + calculateFibonacci(count - 2);
8}

Invoking (calling) a function is done by the function name followed by actual list of parameters:

Usage of example Fibonacci calcualtor
 1function calculateFibonacci(count) {
 2  if (count == 0) {
 3    return 1;
 4  } else if (count == 1) {
 5    return 1;
 6  }
 7  return calculateFibonacci(count - 1) + calculateFibonacci(count - 2);
 8}
 9
10var 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:

Example of nested blocks
 1// here we define a global variable available to all sub scopes
 2var global = 1;
 3// left curly bracket defines the start of a new scope
 4function doSomething() {
 5  info(global);
 6  var local = 2;
 7  // prints 2
 8  info(local);
 9  global = 3;
10  info(global);
11}
12// prints 1
13info(global);
14// prints 1, 2, 3
15doSomething();
16// prints 3
17info(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).