📙

TL Language Syntax

Documentation of the tetris language (.tl)

Copyright(c): 2022 Blockbusters

Source: https://github.com/aryan02420/CS_F363-Compiler-Construction

Note: all statements in .tl must end with a ;

1. Variable declaration and assignment:

The programmer can declare different types of variables using the “var” keyword without having to explicitly specify the type. Type of the variable is handled by the python back end. The data types that can be assigned to a variable are:

  1. NUMBER (positive and negative integers)
  1. FLOAT
  1. STRING
  1. LIST (comma separated expressions enclosed within ‘[]’)
  1. BOOLEAN (True or False)

Examples:

Declaration

var name1 := True;
var name2 := 42;
var name3 := "string";
var name4 := [ ];

Assignment

name := value;

2. Operations:

The language supports a range of unary and binary operations. Unary operations require a single operand whereas binary operations require two operands.

2a. Binary Operations:

  1. Addition (+)
  1. Subtraction (-)
  1. Multiplication (*)
  1. Division (/)
  1. Modulo (%)
  1. Less than (<)
  1. Less than or equal to (<=)
  1. Greater than (>)
  1. Greater than or equal to (>=)
  1. Equal (==)
  1. Not equal (!=)
  1. Arithmetic Left Shift (<<)
  1. Arithmetic Right Shift (>>)
  1. Bit-wise AND (&)
  1. Bit-wise OR (|)
  1. Bit-wise XOR (^)
  1. Logical AND (and)
  1. Logical OR (or)

2b. Unary Operations:

  1. Bit-wise negation (~)
  1. Logical Negation (not)

3. Function declaration and call:

A function is a block of code which only runs when it is called. You can pass data, known as parameters, into a function. A function can return data as a result.

The programmer can declare functions using the “function” keyword and specify the arguments enclosed by parentheses and separated by comma. The function body is a block of compound statements that are enclosed within the “begin” and “end” keywords. Sample function declaration and call code is shown below.

Note: Function declarations must compulsorily be a the top of the program.

Declaration

function fname(arg1, arg2) 
begin
	<stmt 1>;
	<stmt 2>;
	.
	.
end

Call

fname(val1, val2);

Example of declaration

function my_function()
begin
  print("Hello from a function");
end

3a. Arguments

Information can be passed into functions as arguments. Arguments are specified after the function name, inside the parentheses. You can add as many arguments as you want, just separate them with a comma.

The following example has a function with one argument (fname). When the function is called, we pass along a first name, which is used inside the function to print the full name:

Example

function my_function(fname)
begin
  print(fname + " Refsnes");
end
my_function("Emil");
my_function("Tobias");
my_function("Linus");

3a.1 Parameters or Arguments?

The terms parameter and argument can be used for the same thing: information that are passed into a function.

From a function's perspective:

A parameter is the variable listed inside the parentheses in the function definition.

An argument is the value that is sent to the function when it is called.

3a.2 Number of Arguments

By default, a function must be called with the correct number of arguments. Meaning that if your function expects 2 arguments, you have to call the function with 2 arguments, not more, and not less.

Example

This function expects 2 arguments, and gets 2 arguments:

function my_function(fname, lname)
begin
  print(fname + " " + lname);
end
my_function("Emil");

If you try to call the function with 1 or 3 arguments, you will get an error:

Example

This function expects 2 arguments, but gets only 1:

function my_function(fname, lname)
begin
  print(fname + " " + lname);
end
my_function("Emil");

4. Conditional Statements:

Our language provides the flexibility of using conditional statements to the programmers in the following manner using the “if”, “else” keywords. The condition must be enclosed with parentheses ‘()’ and the code block that must be executed if a condition is satisfied must be mentioned as a block of compound statements mentioned between the “begin” and “end” keywords.

Usage

if (<expr>) 
begin
	<stmt 1>;
	<stmt 2>;
	.
	.
end

else
begin
	<stmt 1>;
	<stmt 2>;
	.
	.
end

5. Loop Statements:

The programmer can make use of loops for controlling the flow of the code.

Our language has two primitive loop commands:

The loop body must again be mentioned as a block of compound statements mentioned between the “begin” and “end” keywords.

Usage

while(<expr>) 
begin
	<stmt 1>;
	<stmt 2>;
	.
	.
end

for (i := 0 to 10)
begin
	<stmt 1>;
	<stmt 2>;
	.
	.
end

5a. While Loops

Example

Print i as long as i is less than 6:

i := 1;
while (i < 6)
begin
  print(i);
  i := i + 1;
end

Note: remember to increment i, or else the loop will continue forever.

The while loop requires relevant variables to be ready, in this example we need to define an indexing variable, i, which we set to 1.

5a.1 The break Statement in a while loop

With the break statement we can stop the loop even if the while condition is true:

Example

Exit the loop when i is 3:

i := 1;
while (i < 6)
begin
  print(i);
  if (i == 3)
	begin
    break;
	end
  i := i + 1;
end

5a.2 The continue Statement in a while loop

With the continue statement we can stop the current iteration, and continue with the next:

Example

Continue to the next iteration if i is 3:

i := 0;
while (i < 6)
begin
  i := i + 1;
  if (i == 3)
	begin
    continue;
	end
  print(i);
end

5b. For Loops

A for loop is used for iterating over a sequence (that is either a list, a tuple, a dictionary, a set, or a string).

This is less like the for keyword in other programming languages, and works more like an iterator method as found in other object-orientated programming languages.

With the for loop we can execute a set of statements, once for each item in a list, tuple, set etc.

Example

Print each fruit in a fruit list:

fruits := ["apple", "banana", "cherry"];
for (var x := 0 to len(fruits))
begin
  print(fruits[x]);
end

The for loop does not require an indexing variable to set beforehand.

5b.1 The break Statement in for loops

With the break statement we can stop the loop before it has looped through all the items:

Example

Exit the loop when x is "banana":

fruits := ["apple", "banana", "cherry"];
for (var x := 0 to len(fruits))
begin
  print(x);
  if (fruits[x] == "banana")
	begin
    break;
	end
end

5b.2 The continue Statement in for loops

With the continue statement we can stop the current iteration of the loop, and continue with the next:

Example

Do not print banana:

fruits := ["apple", "banana", "cherry"];
for (var x := 0 to len(fruits))
begin
  if (x == "banana")
	begin
    continue;
	end
  print(x);

5c. Nested Loops

A nested loop is a loop inside a loop.

The "inner loop" will be executed one time for each iteration of the "outer loop":

Example

Print each adjective for every fruit:

adj := ["red", "big", "tasty"];
fruits := ["apple", "banana", "cherry"];

for (var x := 0 to len(adj))
begin
  for (var y := 0 to len(fruits))
	begin
    print(adj[x], fruits[y]);
	end
end

6. Built-in engine functions

For a hassle free programming experience, we have given the user certain built-in functions that can help make the process of making a tetris game very smooth. These functions are imported from the Tetris Engine. All documentation regarding the same can be found here. Engine documentation: https://aryan02420.github.io/CS_F363-Compiler-Construction/tetrislang/docs/engine.html