S2 Guide: Language Tutorial
S2 is a programming language designed to be a style system. It has properties in common with Perl, Python, and Java.
Variables
Variables are like containers that hold values. You can put values into them, use their values in your programming, or change their value to something else.
Variables are one of the basic concepts of programming. If you're not familiar with them, you may be able to pick up what they are and do from context here, or you can also look for some more in-depth explanations. Every programming language uses variables slightly differently, and many examples will use a specific language to demonstrate, but the underlying principles are the same.
More about variables (programming) on wikipedia
How to Think Like a Computer Scientist (Python version): Variables, expressions and statements (via intro_to_cs)
Declaring a variable
In S2, variables must be declared ahead of time in order to be used. The basic format goes:
var TYPE variablename;
- var indicates you're creating a new variable
- TYPE describes what type of variable you're making. The type can be one of the basic types, described below, or a previously defined class (to be explained later). This type doesn't change.
- variablename is the name you give the variable in your code. This name must start with a letter and can contain letters, digits, and the underscore character ("_").
You can assign a variable a value when declaring it, or wait until later--but make sure to assign a variable a value before you use it! An example of declaring a variable while assigning it is:
var TYPE variablename = VALUE;
Or, in real code:
var string greetings = "hello";
Note: you can assign the value of a variable to another variable, as well, if they are the same type. Here's an example that gives variable1 the value of variable2:
var TYPE variable1 = $variable2;
Or, in real code:
var string goodbye = $greetings;
Basic Types
Strings
String variables, which are lists of characters, are declared as string in S2. You can define strings in one of two ways.
The first way comes in between double quotes:
var string test = "Testing";
The second way comes in between sets of three double quotes--this is very useful when writing HTML, which can have a lot of single double quotes in it. Here's an example:
"""I am also a string, but I can have "quotes" inside me.""";
The above example demonstrates another property of string values, in that if you don't assign them to a variable name, they'll print to output.
Some characters need to be escaped to show up properly in strings, with a backslash (\):
- If you need a newline, use: \n
- If you need a double quote inside single double quotes (or need to make three or more double quotes inside a triple double quotes), use: \"
- If you need to make a backslash, use: \\
- If you want to make a dollar sign (you'll learn why later in variables), use: \$
Integers
Integers (whole numbers) are another value like strings that the S2 language understands, and are declared with int. This is an example of a variable being assigned a literal integer value:
var int width = 500;
Booleans
A boolean is a variable that is either true or false, and is declared with bool. Here is an example that expresses having candy but no cake as boolean variables:
var bool has_candy = true; var bool has_cake = false;
Arrays
An array is a list of items. They must all be the same type! Declaring an array variable is a little different from the usual variable declaration:
var TYPE[] variablename;
The [] after the type lets the program know this variable is an array.
Here is an example with strings:
var string[] counting = ["one", "two", "three"];
Associative arrays
Instead of an ordered list of items, an associative array gives each item in it a "key" that serves as an identifying label. All keys must be strings, and all the times must be the same type. Keys are unique--you can't have two items with the same key. Like regular arrays, declaring associative arrays is a little different:
var TYPE{} variablename;
The {} after the type lets the program know this variable is an associative array.
Here's an example with strings:
var string{} fruits = {"apple" => "red", "lemon" => "yellow", "grape" => "purple"};
Accessing variables
Putting a $ in front of the variable name lets you access it: $variablename. Remember how in strings, the dollar sign needed to be escaped with \$ to make $ show up properly? That's because when you reference a variable in a string, it's replaced with the value of the variable! For instance, this code:
# declare our greeting variable, assign it the value of "hi" var string greeting = "hi"; # print out a sting containing our greeting print "I greet you with: $greeting\n"; # change the value of our greeting to "hello" $greeting = "hello"; # print out a string containing the new value of the greeting print "I greet you with: $greeting\n"; # print out a string containing $greeting print "I greet you with: \$greeting\n";
Will print out:
I greet you with hi I greet you with hello I greet you with $greeting
For regular arrays, you'll need to refer to the position of the value you want in the array; the count starts at 0. Example:
var string[] counting = ["one", "two", "three"] print "I have $counting[2] bananas and $counting[1] apples and $counting[0] orange.\n";
Will print out:
I have three bananas and two apples and one orange.
For associative arrays, you'll want to use the key of the value you want. Example:
var string{} fruits = {"apple" => "red", "lemon" => "yellow", "grape" => "purple"}; print "I have $fruits{"grape"}-colored pants.\n";
Will print out:
I have purple-colored pants.
Properties
Properties are special global variables that are available between layers. EXPAND
Comments
Comments are a way to leave notes in the program. If the first nonwhite space character on a line is a #, it makes that line into a comment:
# This variable holds the width of the image var int width = 500;
Statements
A statement is an instruction in the program. Statements always end with the ; character. They are usually formed by a combination of expressions, which are a combination of values, variables, operators, and functions that return a value.
Statements can also contain code blocks, which are surrounded by the { and } characters. Code blocks can contain one or more statements.
If/else
if ( EXPRESSION ) BLOCK
if ( EXPRESSION ) BLOCK else BLOCK
if ( EXPRESSION ) BLOCK elseif ( EXPRESSION ) BLOCK else BLOCK
Foreach
The foreach control statement is a good way to apply the same code to each item in an array. The basic outline of the statement is this:
foreach VARIABLE ( EXPRESSION ) BLOCK
Each item takes a turn at becoming VARIABLE and running through the statements in BLOCK.
If the array is an associative array, the key of the array item becomes VARIABLE. If the expression being used is a string, each character will become VARIABLE.
Operators
A binary operator has two items. A unary operator only uses one.
Assignment
Arithmetic operators
Comparison operators
Logical operators
Type operators
String concatenation
Range operator
The conditional operator
The conditional operator is the only ternary operator, meaning that it uses three items! It is very similar to if/else; in fact, you can use if/else instead of the conditional operator in all cases.
Named unary operators
A unary operator takes one argument after the operator, and returns one value.
- isnull returns a true value if the argument is null (has no value) and false otherwise
- defined is the opposite of isnull--it returns true when the argument is defined and false if it hasn't been
- new creates a new instance of the given classname; read more about this in the Classes section.
- null creates an undefined variable of the given classname; chances are, you won't use this
- reverse is used on strings and will return a copy of the given string with all the characters reversed
- size takes an array and returns the number of elements in it
- reverse takes an array and returns an array with all of the same items in reverse order
Operator precedence
Functions
In general, a function is given a list of variables (called arguments) runs a set of statements, and returns a variable. Some functions won't have any arguments, and some don't return a value.
Variables declared inside of a function are only available inside of that function. (This is called scope.)
You can use existing functions by calling them in a statement, or you can define your own functions.
Calling functions
You can call functions in statements. Examples:
# This statement calls a function with one argument and doesn't use # any return value it may give back. The arguments go # inside of parentheses. my_function(2); # This statement calls a function with no arguments. Even though there # aren't any arguments, we still need the parentheses to call the function. my_function(); # This statement calls a function with three arguments; multiple # arguments are separated with commas. my_function(2, "cows"); # You can call a function using variables as arguments, too! my_function($greeting, $farewell); # This statement calls a function with an argument and gets back a # value that it assigns to a variable var int height = proportion(500);
Declaring and implementing functions
In order to declare a function, you'll need this information:
- The name you want to give the function
- The arguments the function takes, as well as the type of each argument
- If the function returns a value, the type of that value
When you declare a function, you can also include a docstring after the rest of the declaration but before the ending semicolon of the statement. Doing this allows your function to be automatically documented when viewing information about a layer.
# This function doesn't return a value function print_hello(string greeting); # This function returns an integer function get_height(int width) : int; # This function is documented with a docstring function print_image(string url, string alt, int width, int height) "This function prints out an image tag.";
However, you probably don't want to just declare a function, but also implement it! You can do that like this:
# This function returns a value function get_height(int width) : int "This function returns a height that is three times the given width." { return 3 * $width; } # This function doesn't return a value function greet(string greeting) "This function prints out a greeting." { print "Here is my greeting: $greeting"; }
If you're not dealing with a class function or built-in function (more on those later), you'll also want to implement your function when you declare it.
Built-in functions
Built-in functions aren't written in S2 but in Perl in the backend. They are then declared in a core layer using the builtin keyword. Example:
function builtin ehtml (string s) : string "Escapes all HTML tags and entities from the text";
Classes
Declaring classes
class Mammal { var string voice; var int legs; }
Using classes
Accessing class variables
If you're working inside of a class function and want to access the value stored in a variable belonging to the function, you can use $.classvar or $this.classvar.
If you have a variable whose type is of a certain class, and want to access a variable belonging to it, you can user $var.classvar.
Calling class functions
Extending classes
A class can be extended.
class Dog extends Mammal { var bool likes_cats; }