Difference between revisions of "Guide to NTSL2"

From Aurora Information Uplink
Jump to navigation Jump to search
m (Removed the WIP tag.)
(Fix syntax highlighting issues, add line counts to multi-line codeblocks, removes brackets in code examples, makes bold/italics consistent and disambiguates expressions in the operator section.)
Line 150: Line 150:
* Tables are values that can be indexed and can contain multiple values. They are also sometimes referred to as lists. They are constructed in the following format:
* Tables are values that can be indexed and can contain multiple values. They are also sometimes referred to as lists. They are constructed in the following format:


<source>
<source lang=javascript>
{key1 = value1, key2 = value2, key3 = value3...}
{key1 = value1, key2 = value2, key3 = value3...}
</source>
</source>


The final value can have a comma after it, but it is not mandatory. Tables can be indexed as '''name[index]'''.
The final value can have a comma after it, but it is not mandatory. Tables can be indexed as '''name[index]'''.


* Functions can be made in the following format:  
* Functions can be made in the following format (the default value parameters are optional and can be left out):  
<source>
<source lang=javascript line>
function funcname(arg1[ = defaultvalue1], arg2[ = defaultvalue2]){
function funcname(arg1=defaultvalue1, arg2=defaultvalue2){
...code...
...code...
}  
}  
Line 167: Line 167:
* Varargs are also usable:
* Varargs are also usable:


<source>
<source lang=javascript>
function funcname(... args){...code...}
function funcname(... args){...code...}
</source>
</source>
Line 173: Line 173:
* The various arguments provided to the function will be combined into a list and stored in the local variable args, or whatever name is provided. Brackets for arguments are optional if you have an anonymous function with one argument:  
* The various arguments provided to the function will be combined into a list and stored in the local variable args, or whatever name is provided. Brackets for arguments are optional if you have an anonymous function with one argument:  


<source>
<source lang=javascript>
funcname  = function arg{...code…}
funcname  = function arg{...code...}
</source>
</source>


* They can even be constructed in lambda calculus style:
* They can even be constructed in lambda calculus style (the default value parameters are optional and can be left out):


<source>
<source lang=javascript>
  (arg1[=defaultvalue1], arg2[=defaultvalue2]) => {...code…}
  (arg1=defaultvalue1, arg2=defaultvalue2) => {...code...}
</source>
</source>


In the function style, function can be abbreviated to func. Varargs can also be used in the lambda calculus style. Single variable lambda calculus functions can be further simplified into
In the function style, function can be abbreviated to func. Varargs can also be used in the lambda calculus style. Single variable lambda calculus functions can be further simplified into


<source>
<source lang=javascript>
  arg => {...code...}
  arg => {...code...}
</source>
</source>
Line 200: Line 200:
IF/ELSE conditionals are part of the main program flow:
IF/ELSE conditionals are part of the main program flow:


<source>
<source lang=javascript line>
if(condition){
if(condition){
...code…
...code…
Line 209: Line 209:


* WHEN:
* WHEN:
WHEN conditionals are similar to IF conditionals, but are asynchronous and occur outside of the main program’s flow. They also expose their ‘arguments’ to the scope of its block. A typical case is the topic variable which is set in term.topic events.
WHEN conditionals are similar to IF conditionals, but are asynchronous and occur outside of the main program’s flow. They also expose their arguments to the scope of its block. A typical case is the topic variable which is set in term.topic events.


<source>
<source lang=javascript line>
when(event){
when(event){
...code…
...code…
Line 220: Line 220:
WITH block exposes a list/table to the scope of its block, typically used for making library referencing easier:
WITH block exposes a list/table to the scope of its block, typically used for making library referencing easier:


<source>
<source lang=javascript line>
with(event){
with(event){
...code...
...code...
Line 228: Line 228:
An example is used in Telecomms scripts to save the constant references to tcomm:
An example is used in Telecomms scripts to save the constant references to tcomm:


<source>
<source lang=javascript line>
with(tcomm){
with(tcomm){
when onmessage{
when onmessage{
Line 240: Line 240:
List Iteration FOR Loop:
List Iteration FOR Loop:


<source>
<source lang=javascript line>
for([var] in [list]){
for(var in list){
...code...
...code...
}
}
</source>
</source>
In this form, it iterates over the contents of [list], setting [var] equal to them one at a time. [list] can instead be an iterator function as well, such as string.gmatch
In this form, it iterates over the contents of '''list''', setting '''var''' equal to them one at a time. '''list''' can instead be an iterator function as well, such as '''string.gmatch'''
OR
OR
Variable Iteration FOR Loop:
Variable Iteration FOR Loop:


<source>
<source lang=javascript line>
for([i]=[initial]; [condition]; [step]){
for(i=initial; condition; step){
...code...
...code...
}
}
</source>
</source>


Where [i] is any variable, [initial] is the initial value, [condition] is any condition (presumably involving said variable, but not necessarily), [step] is some form of increment/decrement such as i++ or i--, ++i or --i, etc. This runs the for loop until [condition] is false, executing [step] after every iteration.
Where '''i''' is any variable, '''initial''' is the initial value, '''condition''' is any condition (presumably involving said variable, but not necessarily), '''step''' is some form of increment/decrement such as '''i++''', '''i--''', '''++i''', '''--i''', etc. This runs the for loop until '''condition''' is false, executing '''step''' after every iteration.


* WHILE loop:
* WHILE loop:


<source>
<source lang=javascript line>
while(condition){
while(condition){
...code...
...code...
Line 266: Line 266:


* SWITCH block:
* SWITCH block:
Evaluates [condition], runs whichever code block corresponds to that condition or, if none is found, the default. If a break or return isn’t reached, the program will fall through to the next condition.
Evaluates '''condition''', runs whichever code block's label corresponds to that condition or, if none is found, the block labelled '''default'''. If a break or return isn’t reached, the program will fall through to the next condition.


<source>
<source lang=javascript line>
switch(condition){
switch(condition){
:[default OR expression]
:label1
...code...
...code...
:[default OR expression]
:label2
...code…
...code...
:default
...code...
...
}
}
</source>
</source>


* Ternary:
* Ternary:
Evaluates [expression], if [expression] is true returns [on_true], otherwise returns [on_false].
Evaluates ''expression'', if ''expression'' is true returns ''on_true'', otherwise returns ''on_false''.


<source>
<source lang=javascript>
expression ? on_true : on_false
expression ? on_true : on_false
</source>
</source>


* Eval:
* Eval:
A very powerful, very dangerous function. Produces a function from NTSL2+ code contained in a string. Format is '''eval [expression]'''.
A very powerful, very dangerous function. Produces a function from NTSL2+ code contained in a string. Format is '''eval expression'''.


* The Deoperator:
* The Deoperator:
Line 293: Line 295:
'''+''', '''-''', '''*''', '''/''', '''^''', '''%''', '''and'''/'''&&''', '''or'''/'''||''', '''<''', '''>''', '''<=''', '''>=''', '''==''', and '''!=''' all operate as expected.
'''+''', '''-''', '''*''', '''/''', '''^''', '''%''', '''and'''/'''&&''', '''or'''/'''||''', '''<''', '''>''', '''<=''', '''>=''', '''==''', and '''!=''' all operate as expected.


Concatenation is performed by '''[expr1] .. [expr2]'''.
Concatenation is performed by '''expr1 .. expr2'''.


The length of the text representation of a string, or the number of elements in a list, can be found with '''#[expression]'''.
The length of the text representation of a string, or the number of elements in a list, can be found with '''#expression'''.


Logical negation is performed with '''![expression]''', binary negation is performed with '''~[expression]''', decimal unary negation is performed with '''-[expression]'''.
Logical negation is performed with '''!expression''', binary negation is performed with '''~expression''', decimal unary negation is performed with '''-expression'''.


Integer division can be performed with '''[expression] // [expression]'''.
Integer division can be performed with '''expression1 // expression2'''.


Modulo can be performed with '''[expression] % [expression]'''.
Modulo can be performed with '''expression1 % expression2'''.


Bitwise operators are also available, such as '''|''', '''&''', '''<<''', '''>>''', '''&''', and '''[expression] ~ [expression]''' (xor, do not confuse with unary base 2 negation)
Bitwise operators are also available, such as '''|''', '''&''', '''<<''', '''>>''', '''&''', and '''expression1 ~ expression2''' (xor, do not confuse with unary base 2 negation)

Revision as of 01:15, 27 August 2020

Overview

NTSL2+ is the programming language used aboard the station for modular computers and telecommunications, you can design a lot of interesting things with it, this guide will act as a starting place and reference for enterprising programmers aboard the Aurora.

Functions Reference

Global Functions

Global Functions These functions can typically be used globally.
print(x) Prints its argument to the output and appends a new line.
write(x) Prints its argument to the output.
type(x) Returns the type of x.
tostring(x) Returns X as string.
tonumber(x) Returns X as number.


Math Library

Math Library An assortment of math related functions.
math.sin(x) Returns the sine of X. Probably uses radians, maybe.
math.cos(x) Returns the cosine of X.
math.tan(x) Returns the tangent of X
math.asin(x) Returns the inverse sine of X, as in, what angle gives a sine of X. X is between -1 and 1.
math.acos(x) Inverse cosine function, x is between -1 and 1
math.atan(x, y) OR math.atan(x) Inverse tangent function, either from a pair of coordinates (x and y) or a slope (x)
math.floor(x[, r]) Rounds X to the greatest integer lower than it. Rounds to r places, or after the decimal point by default.
math.atan(x, y) OR math.atan(x) Inverse tangent function, either from a pair of coordinates (x and y) or a slope (x)
math.floor(x[, r]) Rounds X to the greatest integer lower than it. Rounds to r places, or after the decimal point by default.
math.atan(x, y) OR math.atan(x) Inverse tangent function, either from a pair of coordinates (x and y) or a slope (x)
math.floor(x[, r]) Rounds X to the greatest integer lower than it. Rounds to r places, or after the decimal point by default.
math.atan(x, y) OR math.atan(x) Inverse tangent function, either from a pair of coordinates (x and y) or a slope (x)
math.floor(x[, r]) Rounds X to the greatest integer lower than it. Rounds to r places, or after the decimal point by default.
math.acos(x) Inverse cosine function, x is between -1 and 1
math.ceil(x[, r]) Rounds X to the smallest integer greater than it. Rounds to r places, or after the decimal point by default.
math.round(x[, r]) Rounds X according to the principle of "round up on 5 or above, round down otherwise" Rounds to r places, or after the decimal point by default.
math.max(x, y) Returns the largest of its two arguments.
math.clamp(low, num, high) If num is lower than low, returns low. If num is higher than high, returns high. Otherwise, it returns numb. Equivalent to math.max(low, math.min(high, num))
math.random(high o math.random(low, high) math.random(high) returns a random decimal between 0 and high. math.random(low, high) returns a random number between low and high.
math.abs(x) Returns the absolute value of X.
math.deg(x) Converts x from radians to degrees.
math.rad(x) Converts x from degrees to radian.
math.pi Pi.

String Library

String Library

String Library These are strings.
string.sub(string, start[, end]) Returns the substring of string from position start to position end. If end is not specified, it is the end of the string.
string.match(string, pattern) Searches string for instances of pattern and returns the matched value of the matched groups. If there are multiple, then it returns as a list.. Can use regex.
string.gmatch(string, pattern) Returns an iterator function that finds all matches (similar to string.match) in a string.
string.gsub(string, pattern, replacement) Replaces all instances of pattern with replacement. Can use regex.
string.upper(string) Returns string but uppercase.
string.lower(string) Returns string but lowercase.
string.reverse(string) Reverses the string.



Term Library

Term Library These are terms.
term.set_foreground(r, g, b) Sets the text color to (r, g, b). Scaled from 0 - 1.
term.get_foreground() Returns the text color.
term.set_background(r, g, b) Sets the background color to (r, g, b). Scaled from 0 - 1.
term.get_background() Returns the background color.
term.set_cursor(x, y) Sets the cursor to the position x, y. The top left is 0, 0.
term.set_cursor_x(x) Sets the cursor's x position to x. The left side is 0.
term.set_cursor_y(y) Sets the cursor's y position to y. The top line is 0.
term.get_cursor(), term.get_cursor_x(), term.get_cursor_y() Returns the cursor's position, the cursor's x position, or the cursor's y position, respectively.
term.clear() Clears the screen with the preset background colour.
term.write() Same as write().
term.get_size() Gets the size of the terminal.
term.get_width() Returns the width of the terminal.
term.get_height() Returns the height of the terminal.
term.set_topic(x, y, width, height, topic_name) Creates a button/link at (x, y) with width width and height height, and a corresponding topic topic_name. If topic_name begins with ?, it allows you to input text, and the corresponding topic will be "topic_name?input". If text is written over this with write or similar, this will be cleared.



Syntax

  • Variables must start with a letter, but can otherwise contain any alphanumeric character.

Variables can be assigned to with name = value.

Local variables can be made with var name = value or local name = value.

  • Tables are values that can be indexed and can contain multiple values. They are also sometimes referred to as lists. They are constructed in the following format:
{key1 = value1, key2 = value2, key3 = value3...}

The final value can have a comma after it, but it is not mandatory. Tables can be indexed as name[index].

  • Functions can be made in the following format (the default value parameters are optional and can be left out):
function funcname(arg1=defaultvalue1, arg2=defaultvalue2){
	...code...
}
  • Arguments can have any name a variable can take, and can be assigned default values.
  • Varargs are also usable:
	function funcname(... args){...code...}
  • The various arguments provided to the function will be combined into a list and stored in the local variable args, or whatever name is provided. Brackets for arguments are optional if you have an anonymous function with one argument:
funcname  = function arg{...code...}
  • They can even be constructed in lambda calculus style (the default value parameters are optional and can be left out):
 (arg1=defaultvalue1, arg2=defaultvalue2) => {...code...}

In the function style, function can be abbreviated to func. Varargs can also be used in the lambda calculus style. Single variable lambda calculus functions can be further simplified into

 arg => {...code...}
  • Member functions of an object can be called in the form object.function(object, other_arguments) or object::function(other_arguments). These function identically.
  • Strings can be constructed in three ways: "content", ‘content’, or `content`.
  • These are functionally identical except for in the last case, where expressions in square brackets will be evaluated and inserted into the string. This means that `con[expression]tent` is equivalent to instead performing two concatenation operations and one tostring call, "con" .. tostring(expression) .. "tent"

Program Flow/Structure

  • IF/ELSE:

IF/ELSE conditionals are part of the main program flow:

	if(condition){
		...code
	} else {
		...code...
	}
  • WHEN:

WHEN conditionals are similar to IF conditionals, but are asynchronous and occur outside of the main program’s flow. They also expose their arguments to the scope of its block. A typical case is the topic variable which is set in term.topic events.

	when(event){
		...code
	}
  • WITH:

WITH block exposes a list/table to the scope of its block, typically used for making library referencing easier:

	with(event){
		...code...
	}

An example is used in Telecomms scripts to save the constant references to tcomm:

	with(tcomm){
		when onmessage{
			broadcast(...)
		}
	}
  • FOR:

FOR loops have two alternate forms. List Iteration FOR Loop:

	for(var in list){
		...code...
	}

In this form, it iterates over the contents of list, setting var equal to them one at a time. list can instead be an iterator function as well, such as string.gmatch OR Variable Iteration FOR Loop:

	for(i=initial; condition; step){
		...code...
	}

Where i is any variable, initial is the initial value, condition is any condition (presumably involving said variable, but not necessarily), step is some form of increment/decrement such as i++, i--, ++i, --i, etc. This runs the for loop until condition is false, executing step after every iteration.

  • WHILE loop:
	while(condition){
		...code...
	}
  • SWITCH block:

Evaluates condition, runs whichever code block's label corresponds to that condition or, if none is found, the block labelled default. If a break or return isn’t reached, the program will fall through to the next condition.

	switch(condition){
		:label1
			...code...
		:label2
			...code...
		:default
			...code...
		...
	}
  • Ternary:

Evaluates expression, if expression is true returns on_true, otherwise returns on_false.

	expression ? on_true : on_false
  • Eval:

A very powerful, very dangerous function. Produces a function from NTSL2+ code contained in a string. Format is eval expression.

  • The Deoperator:

Takes the form of either @operator or @expression. In the case of an operator, returns a function that behaves like that operator (With priority to binary operators). So @+ is equivalent to (a,b)=>a+b, though runs slightly faster. When an expression is used, this functions as a niladic operator, so is equivalent to ()=>expression.

+, -, *, /, ^, %, and/&&, or/||, <, >, <=, >=, ==, and != all operate as expected.

Concatenation is performed by expr1 .. expr2.

The length of the text representation of a string, or the number of elements in a list, can be found with #expression.

Logical negation is performed with !expression, binary negation is performed with ~expression, decimal unary negation is performed with -expression.

Integer division can be performed with expression1 // expression2.

Modulo can be performed with expression1 % expression2.

Bitwise operators are also available, such as |, &, <<, >>, &, and expression1 ~ expression2 (xor, do not confuse with unary base 2 negation)