Gossip-lang Documentation
Welcome to the Gossip-lang documentation. Gossip-lang is a Python-compiled programming language that allows you to write neat and whimsical code for your little projects. This documentation provides information on how to install, set up, and use Gossip-lang, as well as details on its syntax, errors, and grammar.
Table of Contents
Installation Guide
Prerequisites
Before installing Gossip-lang, ensure that you have Python 3.10.0
or a higher version installed on your system.
Installation
Clone the Gossip-lang GitHub repository using the following command in your terminal:
git clone https://github.com/plugyawn/gossip.git
Navigate to the
gossip
directory using the following command:
cd gossip
Install the required packages using the following command:
pip install -r requirements.txt
This will install all the required dependencies listed in the requirements.txt
file.
Optionally, you can create a virtual environment using the following command:
pipenv install -r requirements.txt
pipenv shell
This will create a virtual environment and install all the required dependencies listed in the requirements.txt
file.
Congratulations, you have successfully installed Gossip-lang! Head on over to the usage guide to learn how to use Gossip-lang.
Usage Guide
Gossip is written in
.gos
files, which is the officially supported extension for Gossip. To run the intrerpreter with an input file containing Gossip code, use the -f or –from-file option followed by the path to the input file:python main.py -f ./path/to/input.gos
For example, to run the
test.gos
file, use the following command:python main.py -f ./examples/test.gos
python main.py --from-file ./examples/test.gos
.. caution:: Make sure to use a distribution with
dataclass
support in python. In our experience, version3.10.0
works best, and is the officially supported distribution.To update Gossip to the latest version, use the -u or –update option:
python main.py -u
python main.py --update
To start an interactive prompt where you can enter Gossip code directly, use the -i or –interpret option:
python main.py -i
python main.py --interpret
To show feedback whenever a command is entered, use the -s or –show-feedback option:
python main.py -s
python main.py --show-feedback
To show a visualization of the Gossip code, line by line, use the -v or –visualize option:
python main.py -v
python main.py --visualize
.. admonition:: Note We recommend using this along with the –interpret flag so your screen is not overwhelmed with AST visualizations. ..
Once you have finished using Gossip, you can exit the program by pressing CTRL-C
or typing exit
at the prompt. You can also clear
to clean up the screen.
In addition, you can use these expressions in tandem. For example, an interesting operation might be to both interpret and visualize at the same time.
python main.py --interpret --visualize
Head on over to the syntax page to learn more about the Gossip syntax.
Gossip Syntax
Gossip is a dynamically typed, interpreted programming language. This document specifies the syntax of the language.
General Syntax
All statements in gossip compulsorily end with a semicolon. Variables are dynamically typed, and typechecked with a typechecker. Variables, once identified by a type during declaration, cannot be assigned values of other datatypes.
declare a = 9;
print(a);
print(123812073);
assign a = 123;
print(a);
declare t = 5;
print(let r = 100 in let t = 10 in r + t ; ;);
We recommend writing Gossip code as closely as possible to python
’s PEP-8 standards; explicitly, we recommend spaces between operators and operands, declaring variables near the top of the codebase, and separating semicolons in the middle of a line with a whitespace.
Data Types
Gossip has a number of built-in data types: NumLiterals, Booleans, StringLiterals, and Lists.
Numbers
Numbers in Gossip can be integers or floating-point numbers. They can be written in decimal notation. Here are some examples:
10
3.14
In Gossip, all numbers are inherently handled as Fractions, so 2.5 is actually the simplified fraction 5/2, and is calculated as such.
Booleans
Booleans in Gossip are True
and False
, and can arise both explicitly or as the result of a boolean operation.
Variables
Variables in Gossip are dynamically typed, which means that they can be assigned values of any type. A variable is declared using the declare
keyword. Here is an example:
declare x = 10;
Once declared, a variable cannot be re-declared in the same or a child scope. Forward declarations are not allowed, and changing values requires the assign
flag.
assign x = 20;
Once declared with a value, the variable is bound to be assigned values only of that type. This extends to Numbers, Booleans, Strings and Lists.
declare x = 20;
assign x = 'abc';
The above code would throw an error related to Bad Assignment of variables.
Strings
Strings are defined the same way as numbers, and are written exclusively with single quotes (‘). Strings support indexing, concatenation and slicing operations.
Concatenation
declare x = 'Hello World!'
assign x = x+x
print(x)
This prints out HelloWorld!HelloWorld!
, as is expected. Strings cannot be operated upon with numbers.
Slicing
The slice operation takes two indices- the start and the end index. Sliced portion of the string is in the index range [start,end)
.
declare i = 1;
declare word = 'abcdefghi';
print(word[i,i+3]);
This prints out the characters in the string from index 1 to index 3 - bcd
.
Indexing
This is used to access the character at a particular index in the string. Gossip follows 0-indexing (the first index value is 0 and increments by 1).
declare i = 1;
declare word = 'abcdefghi';
print(word[i+3]);
This prints out 'd'
- the element at index 4.
Lists
Lists are declared and assigned using similar methods as other datatypes.
declare x = [1,2,3,4,5];
declare y = ['abc','def','ghi'];
declare z = [True, False, True];
Lists support five operations - head
, tail
, empty
, cons
, indexing
, slicing
.
Head and Tail, Empty
Head returns the first element of a list. Tail returns a list of all elements except the first element. Empty checks whether a list is empty or not. It returns True when it is, and False otherwise.
print(x.head);
print(x.tail);
print(x.empty);
This prints out 1
, [2,3,4,5]
, False
Cons
This method is used to add an element to the head of the list. Lists have fixed types. So, attempting to add an element having type different from those already in the list would throw an error.
x.cons(29);
print(x);
This prints out [29,1,2,3,4,5]
x.cons('abc');
This throws an error.
Indexing
This is used to access elements at a particular index in the list. Gossip follows 0-indexing (the first index value is 0 and increments by 1).
declare l = ['abc','def','ghi','jkl','mno'];
declare ind = 1;
print(l[ind+2]);
The above code prints 'jkl'
as it’s output.
Slicing
The slice operation takes two indices- the start and the end index. Sliced portion of the string is in the index range [start,end)
.
declare i = 1;
declare l = ['abc','def','ghi','jkl','mno'];
print(l[i,i+3]);
This prints out the characters in the list of elements from from index 1 to index 3 - ['def','ghi','jkl']
.
Operators
Gossip has several built-in operators.
Arithmetic Operators
Gossip has the following arithmetic operators:
+ - * ** / %
Here is an example:
10 + 5 * 2
The +
operator is overloaded to also work on Strings, where it handles concatenation.
Comparison Operators
Gossip has the following comparison operators:
< > <= >= == !=
Here is an example:
10 < 20
These return a boolean value, that can be used to evaluate an If-Else construct.
Logical Operators
Gossip has the following logical operators:
and or not
Here is an example:
a > b and a < 2*b
Assignment Operators
Gossip has two assignment operators:
declare assign
Here is an example:
declare x = 10;
assign x = 20;
Control Flow
Gossip has the following control flow statements.
If Statements
An if statement in Gossip looks like this:
if a < b then{
x = 10;
} else {
x = 20;
};
While Loops
A while loop in Gossip looks like this:
while x < 10 do {
x = x + 1;
};
For Loops
A for loop in Gossip looks like this:
for i in range 1 to 10; do {
print(i);
};
Repeat Loops
A repeat loop in Gossip looks like this:
repeat{
x = x + 1;
} until x == 10;
Print Statements
A print statement in Gossip looks like this:
print('Hello, world!');
Grammar
The grammar page provides a detailed description of the Gossip-lang grammar, including information on the different types of expressions, statements, and literals used in the language.
program: expression*
expression:
| "let" atomic_expression "=" expression "in" expression ";"
| "assign" atomic_expression "=" expression ";"
| "print(" expression ");"
| "range" "(" atomic_expression "," atomic_expression ")"
| "if" expression "then" expression
| "if" expression "then" expression "else" expression ";"
| "while" expression "do" expression ";"
| "for" atomic_expression "in" expression "do" expression ";"
| "declare" atomic_expression "=" expression ";"
| "repeat" expression "while" expression ";"
| "deffunct" atomic_expression "(" (atomic_expression,",")* ")" AST_sequence ";"
| "callfun" atomic_expression "(" (expression, ",")* ")" ";"
| "functret" "(" expression ")" ";"
| "'" atomic_expression "'"
| "[" (expression, ",")* "]"
| simple_expression
AST_sequence:
| "{" expression* "}"
simple_expression:
| comparison_expression
| comparison_expression "&&" comparison_expression
| comparison_expression "||" comparison_expression
comparison_expression:
| addition_expression
| addition_expression "+ - * ** / < > <= >= == != = % & && || | !" addition_expression
addition_expression:
| multiplication_expression
| multiplication_expression ("+-", multiplication_expression)*
multiplication_expression:
| modulo_expression
| modulo_expression ("*/", modulo_expression)*
modulo_expression:
| uneg_expression
| uneg_expression ("%", uneg_expression)*
uneg_expression:
| "-" atomic_expression
| atomic_expression
atomic_expression:
| Identifier "." list_op
| Identifier "[" slice "]"
| Number
| Bool
list_op:
| head
| tail
| empty
| cons "(" expression ")"
slice:
| expression
| expression "," expression
Identifier:
| /[a-zA-Z_][a-zA-Z0-9_]*/
Number:
| /[0-9]+(\.[0-9]+)?/
Bool:
| True
| False
Errors And Exceptions
Gossip-lang comes with custom errors to help you debug your code. This page provides details on each of the custom errors that can be raised when using Gossip-lang.
DeclarationError
Raised when a variable is called but has not been defined before. For example,
declare a = 10;
assign a = a * b;
When b
hasn’t been declared.
class DeclarationError(Exception):
def __init__(self, name):
self.name = name
print(f"DeclarationError: {name} is not declared.")
InvalidProgramError
Raised when a program is invalid.
For example,
declare;
Without any other attributes, the declare flag fails.
class InvalidProgramError(Exception):
def __init__(self, message, verbose=True):
self.message = message
print(f"InvalidProgramError: {message}")
InvalidTokenError
Raised when an invalid token is encountered.
For example,
class InvalidTokenError(Exception):
"""
Raised when an invalid token is encountered.
"""
def __init__(self, token, verbose=True):
self.token = token
print(f"{RED}InvalidTokenError{RESET}: {token} is not a valid token.")
EndOfStream
Raised when the end of a stream is reached without any resolution.
For example,
for i in range
Without any further code, this hanging ForLoop construct is meaningless.
class EndOfStream(Exception):
pass
EndOfTokens
Raised when the end of a stream of tokens is reached. This is similar to EndOfStreams
and often occurs together.
class EndOfTokens(Exception):
pass
TokenError
Raised when an invalid token is encountered.
declare a ~ 40;
In the March, 2023 version of Gossip, the tilde (~
) is meaningless.
class TokenError(Exception):
pass
TypeCheckError
Raised when the type of the operands in the operation are not of valid type.
declare sample = True * False
class TypeCheckError(Exception):
def __init__(self, oprtype=None, message=None):
self.oprtype = str(oprtype)
if not message:
print(f"TypeError: Operand(s) should have the type: {oprtype}.")
else:
print(f"TypeError: {message}")
InvalidCondition
Raised when an invalid condition is passed to a while loop.
while a + 2 do {
print(a);
};
class InvalidCondition(Exception):
def __init__(self, cond):
self.error = cond
print(f"Invalid Condition: {cond} is not a valid condition.")
VariableRedeclaration
Raised when a variable is re-declared in the same or a child scope.
declare a = 20;
declare a = 10;
In such a case, one should employ the assign
construct.
class VariableRedeclaration(Exception):
def __init__(self, var):
self.var = var
print(f"Redeclaration Error: {var} has already been declared in the current scope.")
AssignmentUsingNone
Raised when trying to assign using a variable that has no assigned value itself.
assign a = 20;
When a
has not been declared before.
class AssignmentUsingNone(Exception):
def __init__(self, var):
self.var = var
print(f"Trying to assign using {var} which has no assigned value itself.")
InvalidConcatenationError
Raised when a variable is assigned using a variable that has no assigned value itself.
class InvalidConcatenationError(Exception):
def __init__(self):
print(f"{RED}InvalidConcatenationError{RESET}: Invalid attempted concatenation of different operand types.")
IndexOutOfBoundsError
Raised when the index passed to a list is out of bounds.
class IndexOutOfBoundsError(Exception):
def __init__(self, msg=None):
if msg == None:
print(msg)
else:
print(f"{RED}IndexOutOfBoundsError{RESET}: Slice index out of range.")
InvalidOperation
Raised when an invalid operation is performed on an object.
class InvalidOperation(Exception):
def __init__(self, op, opr1, opr2=None):
if opr2 == None:
print(f"{RED}InvalidOperationError{RESET}: Cannot perform {op} on {opr1} objects.")
InvalidArgumentToList
Raised when one or more arguments passed to the list
construct are not of the same type.
class InvalidArgumentToList(Exception):
def __init__(self, list_type):
print(f"{RED}InvalidArgumentToListError{RESET}: One or more inputs to list are not of type {list_type}.")
ListError
Raised if any errors occur when using the list
construct.
class ListError(Exception):
def __init__(self, msg):
print(f"{RED}ListError{RESET}: {msg}")
ReferentialError
Raised when a variable is referenced during assignment but has not been declared before.
class ReferentialError(Exception):
def __init__(self, var):
print(f"{RED}ReferentialError{RESET}: The variable {var} referenced during assignment does not exist.")
BadAssignment
Raised when a variable is assigned a value of a different type.
class BadAssignment(Exception):
def __init__(self,var,var_type,val_type):
print(f"Assignment Error- Trying to assign value of {val_type} to variable {var} of {var_type} type")
StringError
Raised when a string is assigned a value of a different type.
class StringError(Exception):
def __init__(self):
print("Invalid value being assigned to string")
ListOpError
Raised when an invalid operation is performed on a list.
class ListOpError(Exception):
def __init__(self,msg):
print(msg)
InvalidFileExtensionError
Raised when the file extension is not valid.
class InvalidFileExtensionError(Exception):
def __init__(self, ext):
print(f"InvalidFileExtension: {ext} is not a valid file extension for gossip language.")
Refer to the syntax for more information on how to avoid these errors.
Visualizing ASTs
Abstract Syntax Trees (ASTs) are a way of representing the structure of code. They are useful in understanding how code works, especially when you need to analyse, transform or manipulate it.
To visualise the AST for a given code, we can use the Graphviz library. Graphviz is an open-source graph visualization software that allows you to visualise data structures like trees and graphs.
Installing Graphviz
Before we can visualise the AST using Graphviz, we need to install it on our system. The steps to install Graphviz on your system are as follows:
Windows
Download Graphviz from http://www.graphviz.org/download/
Add the following to your PATH environment variable:
C:\Program Files\Graphviz\bin
C:\Program Files\Graphviz\bin\dot.exe
Close any opened Jupyter notebook and the command prompt.
Linux
Run the following commands:
sudo apt-get update
sudo apt-get install graphviz
Alternatively, you can build it manually from http://www.graphviz.org/download/.
Installing the Graphviz module for Python
Once Graphviz is installed on your system, you need to install the Graphviz module for Python. You can install the module using pip or conda:
pip install graphviz
conda install graphviz
Visualising the AST
Now that we have installed Graphviz and the Graphviz module for Python, we can use it to visualise the AST for a Gossip code. Let’s take the following Gossip code as an example:
if 1 < 4 then{
print(4);
} else {
print(1);
};
To visualise the AST for this code, we need to first generate the AST using the main.py
file provided in the Gossip repository. We can do this by running the following command:
python main.py -i -v
This will open the Gossip interpreter. We can then copy and paste the code into the interpreter and press enter. This will generate the AST for the code and display it.
Or it will also be saved as AST.png
in the current directory. Below is the AST for the above code:
Explanantion
The visualizer.py
file in the gossip/utils
directory contains the code for visualizing the AST.
This code defines a class ASTViz
that visualizes an abstract syntax tree (AST) using the graphviz library. The treebuilder
method recursively traverses the AST and creates nodes and edges in the graphviz representation according to the type of each node in the AST. For example, if the node is an If
statement, a diamond-shaped node is created in the graphviz representation with edges to the condition expression and the two possible execution paths. If the node is a While
loop, an inverted triangle-shaped node is created with edges to the loop condition expression and the loop body. If the node is a BinOp
, a node with the operator symbol is created with edges to the left and right operands.
The depth
parameter is used to generate unique IDs for each node in the graphviz representation, and the code
parameter is used as the label for the graph. When the treebuilder
method is called with a depth of 0, the graphviz representation is rendered as a PNG image and displayed using the default viewer.
Gossip Language Tutorial
In this tutorial, we will use the Gossip programming language to solve some of the problems from the first few Euler problems.
Problem 1: Multiples of 3 or 5
Problem
: If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
Solution
:
declare n = 1000;
declare s = 0;
declare i = 1;
while i<n do {
if i%3==0 || i%5==0 then
{assign s = s + i;
}
assign i = i+1;
};
print(s);
Problem 2: Even Fibonacci numbers
Problem
: Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
Solution
:
declare sum = 0;
declare i = 0;
declare j = 1;
declare k = 0;
while j<=4000000 do {
assign k = i + j;
assign i = j;
assign j = k;
if j%2==0 then assign sum = sum + j;
};
print(sum);
Problem 3: Largest prime factor
Problem
: The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 ?
Solution
:
declare n = 600851475143;
declare maxpr = 0;
while n%2==0 do {
assign maxpr = 2;
assign n = n/2;
};
declare i = 3;
while i*i<=n do {
while n%i==0 do {
assign maxpr = i;
assign n = n/i;
};
assign i = i+2;
};
if n>2 then print(n); else print(maxpr);;
Problem 4: Largest palindrome product
Problem
: A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. Find the largest palindrome made from the product of two 3-digit numbers.
Solution
:
deffunct check(n){
declare m = 0;
declare r = n;
declare q = 1;
while r>0 do {
assign m = m*q+r%10;
assign r = r - r%10;
assign r = r/10;
if q==1 then assign q = 10;};
functret(m);};
declare n = 3;
declare m = 0;
declare i = 999;
declare j = 999;
while i>= 100 do {
assign j = 999;
while j>= 900 && m==0 do {
declare prod = i*j;
declare a = callfun check(prod);;
if prod == a then {
assign m = 1;
assign n = prod;
}
assign j = j -1;
};
assign i = i - 1;
};
print(n);
Problem 5: Smallest multiple
Problem
: 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
Solution
:
declare sum = 2;
declare i = 1;
declare j = 2;
declare k = 0;
declare x = [2,3,5,7,11,13,17,19];
declare y = [4,2,1,1, 1, 1, 1, 1];
declare z = 1;
declare c = 0;
for i in range(0, 7) do{
assign c = 0;
while c < y[i] do {
assign z = z*x[i];
assign c = c+1;
};
};
print(z);
That concludes this tutorial on using Gossip to solve some of the Euler problems. We encourage you to try solving the remaining problems on your own.
Installation Guide
The installation guide provides step-by-step instructions on how to install Gossip-lang on your system. It also includes information on the requirements and recommended package management systems.
Please refer to the installation guide for more details.
Usage Guide
The usage guide provides an overview of how to use Gossip-lang, including details on using the built-in command-line interface.
Please refer to the usage guide for more details.
Syntax
The syntax page provides a detailed description of the Gossip-lang syntax, including examples of how to write code using Gossip-lang. It covers topics such as comments, variables, functions, and more.
Please refer to the syntax page for more details.
Errors
The errors page provides information on the custom errors that can be generated when using Gossip-lang. It includes a list of error messages, as well as explanations of what causes each error.
Please refer to the errors page for more details.
Grammar
The grammar page provides a detailed description of the Gossip-lang grammar, including information on the different types of expressions, statements, and literals used in the language.
Please refer to the grammar page for more details.
Visualize
The visualize page provides a visual representation of ASTs generated by Gossip-lang. It includes a list of example programs, as well as the corresponding ASTs.
Please refer to the visualize page for more details.
Tutorial
The tutorial provides a step-by-step guide on how to write a simple program using Gossip-lang. It includes a list of example programs, as well as the corresponding ASTs.
Please refer to the tutorial page for more details.