Welcome to the official documentation for Sn2, a modern, simple scripting language that runs on a powerful and well-established runtime. Sn2 files use the .sn2
extension.
The name 'Sn2' is derived from its developer, Souvik Nandi (Sn), with the '2' representing the second version of this language concept.
Syntax Basics
Comments: Sn2 supports single-line comments with //
and multi-line comments with /* ... */
.
// This is a single-line comment
/* This is a
multi-line comment. */
Variables: Declare variables using the let
keyword.
let my_variable = "Hello, World!"
let a_number = 123
Printing: Use the show
command to print to the console.
let version = "1.0"
// You can use + for concatenation or use string formatting (see below)
show "Current version: " + version
User Input: Get input from the user with the input()
function.
Null Value: Use the null
keyword to represent the absence of a value. Example: let data = null
Booleans
Sn2 supports boolean logic with the literal values true
and false
.
let is_active = true
if (is_active) { show "System is active." }
Operators
Sn2 supports standard arithmetic and logical operators. It also includes a ternary operator for concise conditional assignments.
Ternary Operator:
let age = 20
let status = (age >= 18) ? "Adult" : "Minor"
show "Status: \${status}" // Output: Status: Adult
Compound Assignment Operators:
let score = 100
score -= 10 // Equivalent to: let score = score - 10
show "New score: \${score}" // Output: New score: 90
Membership Operator:
let my_list = [10, 20, 30]
if (20 in my_list) { show "Found it!" }
Negative Membership Operator:
let my_list = [10, 20, 30]
if (40 not in my_list) { show "40 is not in the list." }
Strict Equality Operators:
let value = 30
if (value === 30) { show "Value is strictly 30." }
if ("30" !== 30) { show "String '30' is not strictly equal to number 30." }
Data Structures
Lists (Arrays): Ordered collections created with square brackets []
.
let my_list = [10, "hello", true]
show my_list[1] // Output: hello
Dictionaries (Maps): Key-value pairs created with curly braces .
let person = {"name": "Alex", "age": 25}
show person["name"] // Output: Alex
Tuples: Ordered, unchangeable collections created with parentheses ()
. They are useful for fixed collections of data.
let point = (10, 20)
show "X coordinate: \${point[0]}" // Output: X coordinate: 10
Sets: Unordered collections of unique items. They are created with curly braces , but without key-value pairs.
let my_set = {1, 2, 2, 3, "hello"}
show my_set // Output: {1, 2, 3, 'hello'} (order may vary)
List Comprehensions
Sn2 supports a concise and powerful syntax for creating new lists based on existing ones. This is often more readable than using a traditional loop.
let numbers = [1, 2, 3, 4, 5]
// Create a new list with each number squared
let squares = [n*n for n in numbers]
show squares // Output: [1, 4, 9, 16, 25]
// Create a new list with only the even numbers, squared
let even_squares = [n*n for n in numbers if n % 2 == 0]
show even_squares // Output: [4, 16]
List Destructuring
Sn2 allows you to unpack values from a list into distinct variables in a single line, which can make your code cleaner and more readable.
let point = [10, 20, 30]
let [x, y, z] = point
show "x=\${x}, y=\${y}, z=\${z}" // Output: x=10, y=20, z=30
Type Casting
Sn2 provides built-in functions to explicitly convert values between different types.
toInt(value)
: Converts a value to an integer.toFloat(value)
: Converts a value to a floating-point number.toString(value)
: Converts a value to a string.
let num_string = "123.45"
let my_float = toFloat(num_string)
let my_int = toInt(my_float) // Note: This will truncate, resulting in 123
show "Integer: \${my_int}, String: \${toString(my_float)}"
Built-in Functions
Sn2 provides several globally available functions for common tasks.
input(prompt)
: Reads a line of input from the user.len(collection)
: Returns the number of items in a collection.iter(collection)
: Returns an iterator object for a collection.next(iterator)
: Retrieves the next item from an iterator.
let my_list = [1, 2, 3, 4]
show "The list has \${len(my_list)} items."
let name = input("Enter your name: ")
show "Your name has \${len(name)} characters."
Control Flow
Conditionals: Use if/else if/else
with conditions in parentheses and blocks in curly braces.
let score = 85
if (score > 90) {
show "Grade: A"
} else if (score > 80) {
show "Grade: B"
} else {
show "Grade: C or lower"
}
Match Statement: Use a match
statement for more complex conditional logic. Use case _:
for a default case.
let status_code = 404
match (status_code) {
case 200: { show "OK" }
case 404: { show "Not Found" }
case 500: { show "Server Error" }
case _: { show "Unknown status" }
}
// Output: Not Found
While Loop:
let count = 3
while (count > 0) {
show count
let count = count - 1
}
For-Each Loop:
let my_items = ["one", "two", "three"]
loop item in my_items {
show "Item: " + item
}
Range Loop: Use the ..
operator for ranges.
// This will print numbers 0 through 9
loop i in 0..10 {
show "Current number: " + i
}
Iterators
For more granular control over looping, create an iterator from a collection using iter()
and get the next item with next()
.
let numbers = [10, 20, 30]
let num_iter = iter(numbers)
show next(num_iter) // Output: 10
show next(num_iter) // Output: 20
Functions
Define functions with the func
keyword.
func add(x, y) {
return x + y
}
let sum = add(10, 5)
show "The sum is: " + sum // Output: The sum is: 15
Decorators
Modify a function's behavior using decorators with the @
symbol.
func simple_logger(fn) {
func wrapper() {
show "Calling function..."
fn()
show "Function call finished."
}
return wrapper
}
@simple_logger
func say_hello() {
show "Hello, Sn2!"
}
say_hello()
Classes and Objects (OOP)
Sn2 supports OOP. The constructor is named init
, and instance members are accessed with this
.
class Dog {
func init(this, name) {
let this.name = name
}
func bark(this) {
show this.name + " says: Woof!"
}
}
let my_dog = Dog("Rex")
my_dog.bark() // Output: Rex says: Woof!
Inheritance
Inherit from a parent class using <
. Call parent methods using super
.
class Animal {
func init(this, name) {
let this.name = name
}
func speak(this) {
return this.name + " makes a sound."
}
}
class Dog < Animal {
func init(this, name, breed) {
super.init(name)
let this.breed = breed
}
func speak(this) {
let parent_sound = super.speak()
show parent_sound + " Specifically, it barks."
}
}
let my_dog = Dog("Buddy", "Golden Retriever")
my_dog.speak()
// Output: Buddy makes a sound. Specifically, it barks.
Lambda Functions
Create small, anonymous functions using the arrow syntax =>
.
let multiply = (a, b) => a * b
let product = multiply(7, 6)
show "The product is: " + product // Output: The product is: 42
Math Library
Sn2 includes a built-in Math
object for mathematical functions and constants.
let num = 64
let square_root = Math.sqrt(num)
show "The square root of " + num + " is " + square_root
String Formatting
Embed variables into strings using the \${...}
syntax.
let user = "Souvik"
let score = 95
let message = "User \${user} has a score of \${score}."
show message // Output: User Souvik has a score of 95.
String Methods
Strings come with a variety of built-in methods for manipulation.
let greeting = " Hello, World! "
show greeting.upper() // " HELLO, WORLD! "
show greeting.lower() // " hello, world! "
show greeting.strip() // "Hello, World!"
let filename = "document.pdf"
if (filename.endsWith(".pdf")) { show "It's a PDF file." }
if (greeting.strip().startsWith("Hello")) { show "It starts with Hello." }
JSON Handling
Use the built-in JSON
object to parse and stringify JSON data.
let json_string = '{"name": "Alice", "id": 123}'
let data = JSON.parse(json_string)
show "Parsed name: \${data["name"]}"
let user_obj = { "user": "Bob", "active": true }
let new_json_string = JSON.stringify(user_obj)
show new_json_string
let pretty_json = JSON.stringify(user_obj, 4)
show pretty_json
Regular Expressions
Use the built-in RegEx
object for pattern matching.
let text = "My email is example@sn2.dev, please write to me."
let emails = RegEx.findall(r"[\\w\\.-]+@[\\w\\.-]+", text)
show "Found emails: \${emails}"
let sanitized_text = RegEx.sub(r"[\\w\\.-]+@[\\w\\.-]+", "[REDACTED]", text)
show sanitized_text
Date & Time
Use the built-in DateTime
object for working with dates and times.
let now = DateTime.now()
let formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
show "The current date and time is: \${formatted_date}"
Modules
Organize code into multiple files and use import
to use them.
math_utils.sn2
:
// File: math_utils.sn2
func add(a, b) {
return a + b
}
let E = 2.71828
main.sn2
:
// File: main.sn2
import "math_utils" as mu
let result = mu.add(5, 3)
show "The result is: \${result}"
Error Handling
Handle potential errors using a try/catch
block.
try {
let result = 10 / 0
} catch (e) {
show "An error occurred: " + e
}
Running Code
To run an Sn2 file, use the runsn
command:
runsn example.sn2