Skip to content

Instantly share code, notes, and snippets.

@alob-mtc
Last active November 7, 2023 09:01
Show Gist options
  • Save alob-mtc/8139d4bf955b167cc29024f574286bf6 to your computer and use it in GitHub Desktop.
Save alob-mtc/8139d4bf955b167cc29024f574286bf6 to your computer and use it in GitHub Desktop.
ProScript Language Spec

ProScript

Language Draft

Version: 0.1

Overview: ProScript is an interpreted programming language focused on asynchronous programming. It provides simple and powerful constructs for writing asynchronous code, such as async/await, futures, and promises. ProScript also has a garbage collector to automatically manage memory.

Data types:

  • Integers: int
  • Floats: float
  • Booleans: bool
  • Strings: str
  • Arrays: []T, where T is any of the other data types listed above.
  • Enums: enum
  • Structs: struct
  • Interfaces: interface

Syntax: ProScript has a simple and concise syntax. The following are some of the basic keywords and operators in ProScript:

Keywords:

async
await

int
bool
float
str
enum
interface
struct

let
const
self
fn
if
else
for
in
return
break
continue

Operators:

  • Arithmetic operators: +, -, *, /, %
  • Relational operators: <, >, <=, >=, ==, !=
  • Logical operators: &&, ||, !
  • Pipeline operator: |>
  • Aync operator: <<

Expressions:

ProScript expressions are evaluated from left to right. Expressions can be nested using parentheses.

Variables:

Variables are declared using the let keyword. The value of a variable can be changed using the assignment operator (=).

Constants:

Constants are declared using the const keyword. The value of a constant cannot be changed.

Structs:

Structs are used to represent data structures. Structs are defined using the struct keyword. Structs can have fields of any type, including other structs.

Functions:

Functions are defined using the fn keyword. Functions can take parameters and can return values.

Control flow:

ProScript supports the following control flow statements:

  • if statements: if statements are used to execute code if a condition is true.
  • else statements: else statements are used to execute code if a condition is false.
  • for loops: for loops are used to iterate over a sequence of values.
  • in statements: in statements are used to iterate over the elements of a data structure.

Asynchronous code:

ProScript supports asynchronous programming using the async/await keywords. Asynchronous code allows you to write code that can be executed concurrently.

Futures:

ProScript supports futures, which are objects that represent the eventual result of an asynchronous operation. Interaction with Futures is done using await or <<

Pipelines:

ProScript supports pipelines, which allow you to chain together a series of asynchronous/sync operations. Chaining is done using |>

Garbage collector:

ProScript has a garbage collector to automatically manage memory

Syntax:

  • Integers:
// Declare a constant integer variable
const myInt: int = 10;

// Add two integers together
const sum = myInt + 5;
  • Floats:
// Declare a constant float variable
const myFloat: float = 3.14;

// Multiply two floats together
const product = myFloat * 2;
  • Booleans:
// Declare a constant boolean variable
const myBool: bool = true;

// Check if a boolean condition is true
if (myBool) {
  // Do something
}
  • Strings:
// Declare a constant string variable
const myString: str = "Hello, world!";

// Concatenate two strings together
const greeting = "Hello, " + myString;
  • Arrays:
// Declare a constant array of integers
const myArray: []int = [1, 2, 3, 4, 5];

// Get the element at index 2 in the array
const element = myArray[2];
  • Enums:
// Declare a constant enum
enum MyEnum {
  A,
  B(int),
  C([]str),
};

// Create a constant variable of type MyEnum
const myEnumA: MyEnum = MyEnum.A;
let myEnumB: MyEnum = MyEnum.B(10);
let myEnumC: MyEnum = MyEnum.B(["a", "b", "c"]);

// Check the value of the variable
if (myEnumA == MyEnum.A) {
  // Do something
}
  • Structs & Interface:
// Define a constant struct
struct MyStruct {
  pub field1: int,
  pub field2: str,

  fn getField2(me: self): str {
    return me.field2;
  }
  fn setField1(me: self, x: int) {
    me.field1 = x;
  }
  fn sayHello(): str {
    return "Hello World"
  }
}

// Usage example
const myStruct: MyStruct = MyStruct {
  field1: 10,
  field2: "Hello, world!"
};

// Access the fields of the struct
const field1 = myStruct.field1;
const field2 = myStruct.field2;

// Interface
interface MyInterface {
  doSomething(x: int): int;
}
  • Loops:
// for statement with no condition
for {
    // Do something
}

// For statement with single condition
for (true) {
    // Do something
}

// for statements with iterator 
for (let i in 0..10) {
    // Do something
}

Features:

  • Asynchronous code: Futures:
// Create a constant future
const future = async fn() {
  // Do something asynchronous and return the result
};

// Get the result of the future
const result = await future();
// or
const result = << future();
  • Pipelines:
// Create a pipeline
let pipeline: fn(int): int = fn(x: int): int => x * 2 |> fn(x: int): int => x + 1;

// Apply the pipeline to a value
let pipelinedResult: int = pipeline(10);

println("Pipeline result: ", pipelinedResult); // Should output 21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment