Skip to content

Jac Language Reference#

Introduction#

Welcome to the official reference guide for the Jac programming language. This document is designed to serve as a comprehensive reference manual as well as a formal specification of the language. The mission of this guide is to be a resource for developers seeking to answer the question, "How do I code X in Jac?"

This document is organized around the formal grammar for the language code examples and corresponding grammar snippets being directly generated from the actual grammar and test cases maintained in the official repository. We expect the descriptions may occasionally lag behind the rapid evolution of Jac in the early days. If you notice something, make a pull request and join our contributor community.

Base Module structure#

Code Example

"""A Docstring can be added the head of any module.

Any element in the module can also have a docstring.
If there is only one docstring before the first element,
it is assumed to be a module docstring.
"""

"""A docstring for add function"""
def add(a: int, b: int) -> int {
    return a + b;
}
# No docstring for subtract function

def subtract(a: int, b: int) -> int {
    return a - b;
}

with entry:__main__ {
    print(add(1, subtract(3, 1)));
}
"""A Docstring can be added the head of any module.

Any element in the module can also have a docstring.
If there is only one docstring before the first element,
it is assumed to be a module docstring.
"""

"""A docstring for add function"""


def add(a: int, b: int) -> int:
    return a + b


def subtract(a: int, b: int) -> int:
    return a - b


if __name__ == "__main__":
    print(add(1, subtract(3, 1)))
Jac Grammar Snippet

Description

In Jac, a module is analogous to a Python module, serving as a container for various elements such as functions, classes (referred to as "archetypes" later in this document), global variables, and other constructs that facilitate code organization and reusability. Each module begins with an optional module-level docstring, which provides a high-level overview of the module's purpose and functionality. This docstring, if present, is positioned at the very start of the module, before any other elements.

Docstrings

Jac adopts a stricter approach to docstring usage compared to Python. It mandates the inclusion of a single docstring at the module level and permits individual docstrings for each element within the module. This ensures that both the module itself and its constituent elements are adequately documented. If only one docstring precedes the first element, it is automatically designated as the module-level docstring.

Also Note, that Jac enforces type annotations in function signatures and class fields to promote type safety and ultimately more readable and scalable codebases.

Elements within a Jac module encompass familiar constructs from Python, including functions and classes, with the addition of some unique elements that will be discussed in further detail. Below is a table of module elements in Jac. These constructs are described in detail later in this document.

Module Item Description
Import Statements Same as python with slightly different syntax, works with both .jac and .py files (in addition to packages)
Archetypes Includes traditional python class construct with equiviant semantics, and additionaly introduces a number of new class-like constructs including obj, node, edge, and walker to enable the data spatial programming paradigmn
Function Abilities Equivalent to traditional python function semantics with change of keyword def to can. Type hints are required in parameters and returns
Data Spatial Abilities A function like construct that is triggered by types of nodes or walkers in the data spatial paradigm
Free Floating Code Construct (with entry {...}) to express presence of free floating code within a module that is not part of a function or class-like object. Primarily for code cleanliness, readability, and maintainability.
Global Variables Module level construct to express global module level variables without using with entry syntax. (glob x=5 is equivalent to with entry {x=5;})
Test A language level construct for testing, functionality realized with test and check keywords.
Inline Python Native python code can be inlined alongside jac code at arbitrary locations in a Jac program using ::py:: directive

Moreover, Jac requires that any standalone, module-level code be encapsulated within a with entry {} block. This design choice aims to enhance the clarity and cleanliness of Jac codebase.

Import/Include Statements#

Code Example

import os;
import datetime as dt;
import from math { sqrt as square_root, log }
import from base_module_structure { add }
import from base_module_structure { subtract }
include global_variables;

with entry {
    for i in range(int(square_root(dt.datetime.now().year))) {
        print(
            os.getcwd(),
            add(i, subtract(i, 1)),
            int(log(i + 1))
        );
    }
}
from jaclang import JacMachineInterface as _
import os
import datetime as dt
from math import sqrt as square_root, log

(add, subtract) = _.py_jac_import(
    target="base_module_structure",
    base_path=__file__,
    items={"add": None, "subtract": None},
)

for i in range(int(square_root(dt.datetime.now().year))):
    print(os.getcwd(), add(i, subtract(i, 1)), int(log(i + 1)))
Jac Grammar Snippet

Description

Jac's import and include statements provides a propoer superset of python's import semantics with some improvements for imports of Jac modules. That being said, its important to note an important syntax difference in that from X import Y is reworked into import from X, Y (import X remains in the style of import X in Jac). Also there is a :py or :jac after the import statment to signify which type of import to consider.

  • Python Imports: Utilize import to seamlessly import Python libraries, allowing full access to Python's ecosystem within Jac programs, with the same semantics as python.
  • Jac Imports: Use import for importing Jac-specific modules from .jac files with the same symantics as python files with and additional functionality for Jac's impl separation (described later), and static analysis features.

Archetypes#

Code Example

def print_base_classes(cls: type) -> type {
    print(
        f"Base classes of {cls.__name__}: {[c.__name__ for c in cls.__bases__]}"
    );
    return cls;
}

class Animal {}

obj Domesticated {}

@print_base_classes
node Pet(Animal, Domesticated) {}

walker Person(Animal) {}

walker Feeder(Person) {}

@print_base_classes
walker Zoologist(Feeder) {}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


def print_base_classes(cls: type) -> type:
    print(f"Base classes of {cls.__name__}: {[c.__name__ for c in cls.__bases__]}")
    return cls


class Animal:
    pass


class Domesticated(_.Obj):
    pass


@print_base_classes
class Pet(Animal, Domesticated, _.Node):
    pass


class Person(Animal, _.Walker):
    pass


class Feeder(Person, _.Walker):
    pass


@print_base_classes
class Zoologist(Feeder, _.Walker):
    pass
Jac Grammar Snippet

Description

The provided Jac code snippet demonstrates the use of archetypes (a key concept in Jac programming), which supersets traditional classes in object-oriented programming. In Jac, archetypes can be defined using different keywords to signify their roles and characteristics within the program. These include obj, node, walker, edge, and class, each serving distinct purposes in the design of a Jac application.

Defining Archetypes

  • Object (obj): This keyword is used to define a basic archetype. In the example, Animal and Domesticated are simple archetypes with no inherited or additional members.

  • Node (node): Defines an archetype that can be part of a graph object structure. Pet is declared as a node and inherits features from Animal and Domesticated, demonstrating multiple inheritance.

  • Walker (walker): This keyword is used to define archetypes that perform actions or traverse nodes and edges within a graph. Person, Feeder, and Zoologist are examples of walkers, with Zoologist also including the use of a decorator.

Inheritance

The example illustrates how archetypes can inherit from one or more other archetypes, using the syntax :ParentArchetype:. For instance, Feeder inherits from Person, which in turn inherits from Pet, indicating a chain of inheritance.

Decorators

Decorators in Jac, denoted by @, are used to modify or enhance the behavior of archetypes without altering their code directly. The @print_base_classes decorator is applied to Pet and Zoologist to print their base classes at runtime, demonstrating a practical use of decorators for introspection or debugging purposes.

Archetype bodies#

Code Example

obj Car {
    has make: str,
        model: str,
        year: int;
    static has wheels: int = 4;

    def display_car_info {
        print(f"Car Info: {self.year} {self.make} {self.model}");
    }

    static def get_wheels -> int {
        return Car.wheels;
    }
}

with entry {
    car = Car("Toyota", "Camry", 2020);
    car.display_car_info();
    print("Number of wheels:", Car.get_wheels());
}
class Car:
    wheels: int = 4

    def __init__(self, make: str, model: str, year: int):
        self.make = make
        self.model = model
        self.year = year

    def display_car_info(self):
        print(f"Car Info: {self.year} {self.make} {self.model}")

    @staticmethod
    def get_wheels():
        return Car.wheels


car1 = Car("Toyota", "Camry", 2020)
car1.display_car_info()
print("Number of wheels:", Car.get_wheels())
Jac Grammar Snippet

Description

In Jac, an archetype functions similarly to classes in traditional object-oriented programming languages. It allows the definition of data structures with both state and behavior encapsulated within. The provided Jac code snippet demonstrates the definition and usage of an archetype named Car.

The Car archetype includes three instance variables (make, model, and year) and one class variable (wheels). Instance variables are defined using the has keyword and can have specific types (str for strings and int for integers). The static keyword precedes the class variable definition, indicating that wheels is shared across all instances of Car.

Types are annotated directly after the variable name (required for all has variables) and are followed by a colon. For instance, make: str declares a variable make of type string.

The Car archetype also defines two methods, display_car_info as an instance method and get_wheels as a static method. Methods are introduced with the can keyword. The instance method display_car_info uses a formatted string to print car information, accessing instance variables with the self reference. The static method get_wheels returns the value of the static variable wheels.

An instance of Car is created using the archetype name as a constructor, passing in values for make, model, and year. This instance is assigned to the variable car.

Instance methods are invoked using the dot notation on the instance (car.display_car_info()), and static methods are called directly on the archetype (Car.get_wheels()).

The entry block serves as the entry point of the program, where a Car instance is created, and its methods are invoked to display the car's information and the number of wheels.

Enumerations#

Code Example

import from enum { unique }

@unique
enum Color;

impl Color {
    RED = 1,
    GREEN = 2
}

enum :protect Role {
    ADMIN = 'admin',
    USER = 'user'

    with entry {
        print('Initializing role system..');
        def foo -> str {
            return 'Accessing privileged Data';
        }
    }

}
with entry {
    print(Color.RED.value, Role.foo());
}
from enum import Enum, auto, unique


@unique
class Color(Enum):
    RED = 1
    pencil = auto()


class Role(Enum):
    ADMIN = ("admin",)
    USER = "user"

    print("Initializing role system..")

    def foo():
        return "Accessing privileged Data"


print(Color.RED.value, Role.foo())
Jac Grammar Snippet

Description

Jac has enumerations directly in the language. The enum Color defines an enumeration called Color, which includes two members: RED assigned the value 1 and pencil which implicitly takes the next integer value, 2 (effectively the same as a typical pencil = auto() in Python's enum).

The entry point of the program is defined with with entry, which serves as the main function or starting point for execution. Inside this block, the code prints the value of the RED enumeration member using print(Color.RED.value);. Since RED is assigned the value 1, this statement will output 1 to the console when the program runs.

Abilities#

Code Example

obj Divider {
    def divide(x: float, y: float) -> float {
        return (x / y);
    }
}
#this is an abstract class as it has the abstract method

obj Calculator {
    static def:priv multiply(a: float, b: float) -> float {
        return a * b;
    }
    def substract -> float abs;
    def add(number: float, *a: tuple) -> float;
}

obj Substractor(Calculator) {
    def substract(x: float, y: float) -> float {
        return (x - y);
    }
}

impl Calculator.add
(number: float, *a: tuple) -> float {
    return (number * sum(a));
}

with entry {
    div = Divider();
    sub = Substractor();
    print(div.divide(55, 11));
    print(Calculator.multiply(9, -2));
    print(sub.add(5, 20, 34, 56));
    print(sub.substract(9, -2));
}
from abc import ABC, abstractmethod


class Calculator(ABC):
    @staticmethod
    def multiply(a: float, b: float) -> float:
        return a * b

    @abstractmethod
    def substract(self, x: float, y: float) -> float:
        pass

    def add(self, number: float, *a: float) -> str:
        return str(number * sum(a))


class Substractor(Calculator):
    def substract(self, x: float, y: float) -> float:
        return x - y


class Divider:
    def divide(self, x: float, y: float):
        return x / y


sub = Substractor()
div = Divider()
print(div.divide(55, 11))
print(Calculator.multiply(9, -2))
print(sub.add(5, 20, 34, 56))
print(sub.substract(9, -2))
Jac Grammar Snippet

Description

Implementations#

Code Example

def foo -> str;

obj vehicle;

enum Size; #implementations

impl foo -> str {
    return ("Hello");
}

impl vehicle  {
    has name: str = "Car";
}

impl Size {
    Small=1,
    Medium=2,
    Large=3
}

with entry {
    car = vehicle();
    print(foo());
    print(car.name);
    print(Size.Medium.value);
}
from enum import Enum


def foo() -> None:
    return "Hello"


class vehicle:
    def __init__(self) -> None:
        self.name = "Car"


class Size(Enum):
    Small = 1
    Medium = 2
    Large = 3


car = vehicle()
print(foo())
print(car.name)
print(Size.Medium.value)
Jac Grammar Snippet

Description

Global variables#

Code Example

let:priv a = 5;

glob:pub X = 10;

glob:protect y = 15;

glob z = 20;

obj:priv Myobj{}

with entry:__main__ {
    print(a, X, y, z);
}
1
2
3
4
5
6
7
global a, X, y, z
a = 5
X = 10
y = 15
z = 20

print(a, X, y, z)
Jac Grammar Snippet

Description

Free code#

Code Example

import math;

obj circle {
    def init(radius: float) {
        self.radius = radius;
    }

    def area -> float {
        return math.pi * self.radius * self.radius;
    }
}

def foo(n_1: float) {
    return n_1 ** 2;
}

with entry {
    print("Hello World!");
    print(foo(7));
    print(int(circle(10).area()));

    #code block
}
import math


class Circle:
    def __init__(self, radius: float):
        self.radius = radius

    def area(self):
        return math.pi * self.radius * self.radius


def foo(n_1: float):
    return n_1**2


print("Hello World!")
print(foo(7))
print(int(Circle(10).area()))
Jac Grammar Snippet

Description

Inline python#

Code Example

with entry {
    print("hello ");
}

::py::
def foo():
    print("world")

foo()
::py::
1
2
3
4
5
6
7
8
print("hello ")


def foo():
    print("world")


foo()
Jac Grammar Snippet

Description

Tests#

Code Example

test test1 {
    check almostEqual(4.99999, 4.99999);
}

test test2 {
    check 5 == 5;
}

test test3 {
    check "e" in "qwerty";
}

with entry:__main__ {
    import subprocess;
    result = subprocess.run(
        ["jac", "test", f"{__file__}"],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
    );
    print(result.stderr);
}
import unittest


class TestCases(unittest.TestCase):
    def test_test1(self):
        self.assertAlmostEqual(4.99999, 4.99999)

    def test_test2(self):
        self.assertEqual(5, 5)

    def test_test3(self):
        self.assertIn("e", "qwerty")


if __name__ == "__main__":
    unittest.main()
Jac Grammar Snippet

Description

Codeblocks and Statements#

Code Example

1
2
3
4
5
6
7
with entry {
    print("Welcome to the world of Jaseci!");
    def add(x: int, y: int) -> int {
        return (x + y);
    }
    print(add(10, 89));
}
1
2
3
4
5
6
7
8
print("Welcome to the world of Jaseci!")


def add(x: int, y: int) -> int:
    return x + y


print(add(10, 89))
Jac Grammar Snippet

Description

If statements#

Code Example

with entry {
    x = 15;
    if 0 <= x<= 5 {
        print("Not Bad");
    } elif 6 <= x<= 10 {
        print("Average");
    } else {
        print("Good Enough");
    }
}
1
2
3
4
5
6
7
x = 15
if 0 <= x <= 5:
    print("Not Bad")
elif 6 <= x <= 10:
    print("Average")
else:
    print("Good Enough")
Jac Grammar Snippet

Description

While statements#

Code Example

1
2
3
4
5
6
7
with entry {
    i = 1;
    while i < 6 {
        print(i);
        i+=1;
    }
}
1
2
3
4
i = 1
while i < 6:
    print(i)
    i += 1
Jac Grammar Snippet

Description

For statements#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    for i in "ban" {
        for j in range(1, 3) {
            for k=1 to k<3 by k+=1  {
                print(i, j, k);
            }
        }
    }
}
1
2
3
4
for i in "ban":
    for j in range(1, 3):
        for k in range(1, 3, 1):
            print(i, j, k)
Jac Grammar Snippet

Description

Try statements#

Code Example

1
2
3
4
5
6
7
with entry {
    try  {
        print("Result", 5 / 0);
    } except Exception as e  {
        print(e);
    }
}
1
2
3
4
try:
    print("Result", 5 / 0)
except Exception as e:
    print(e)
Jac Grammar Snippet

Description

Match statements#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    a = 8;
    match a {
        case 7:
            print("doable");
        case _:
            print("Undoable");
    }
}
1
2
3
4
5
6
a = 8
match a:
    case 7:
        print("Doable")
    case _:
        print("Undoable")
Jac Grammar Snippet

Description

Match patterns#

Code Example

obj Point {
    has x: float,
        y: float;
}

def match_example(data: any) {
    match data {
        # MatchValue
        case 42:
            print("Matched the value 42.");

        # MatchSingleton
        case True:
            print("Matched the singleton True.");
        case None:
            print("Matched the singleton None.");

        # MatchSequence
        case [1, 2, 3]:
            print("Matched a specific sequence [1, 2, 3].");

        # MatchStar
        case [1, *rest, 3]:
            print(
                f"Matched a sequence starting with 1 and ending with 3. Middle: {rest}"
            );

        # MatchMapping
        case {"key1" : 1, "key2" : 2, **rest}:
            print(
                f"Matched a mapping with key1 and key2. Rest: {rest}"
            );

        # MatchClass
        case Point(int(a), y = 0):
            print(f"Point with x={a} and y=0");

        # MatchAs
        case [1, 2, rest_val as value]:
            print(
                f"Matched a sequence and captured the last value: {value}"
            );

        # MatchOr
        case [1, 2] | [3, 4]:
            print("Matched either the sequence [1, 2] or [3, 4].");

        case _:
            print("No match found.");
    }
}

with entry {
    match_example(Point(x=9, y=0));
}
class Point:
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y


def match_example(data: any):
    match data:
        # MatchValue
        case 42:
            print("Matched the value 42.")

        # MatchSingleton
        case True:
            print("Matched the singleton True.")
        case None:
            print("Matched the singleton None.")

        # MatchSequence
        case [1, 2, 3]:
            print("Matched a specific sequence [1, 2, 3].")

        # MatchStar
        case [1, *rest, 3]:
            print(
                f"Matched a sequence starting with 1 and ending with 3. Middle: {rest}"
            )

        # MatchMapping
        case {"key1": 1, "key2": 2, **rest}:
            print(f"Matched a mapping with key1 and key2. Rest: {rest}")

        # MatchClass
        case Point(x=int(a), y=0):
            print(f"Point with x={a} and y=0")

        # MatchAs
        case [1, 2, rest_val as value]:
            print(f"Matched a sequence and captured the last value: {value}")

        # MatchOr
        case [1, 2] | [3, 4]:
            print("Matched either the sequence [1, 2] or [3, 4].")

        case _:
            print("No match found.")


match_example(Point(x=9, y=0))
Jac Grammar Snippet

Description

Match litteral patterns#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    num = 89;
    match num {
        case 89:
            print("Correct");
        case 8:
            print("Nope");
    }
}
1
2
3
4
5
6
num = 89
match num:
    case 89:
        print("Correct")
    case 8:
        print("Nope")
Jac Grammar Snippet

Description

Match singleton patterns#

Code Example

with entry {
    data = True;
    match True {

        # MatchSingleton
        case True:
            print("Matched the singleton True.");
        case None:
            print("Matched the singleton None.");
    }
}
1
2
3
4
5
6
7
data = True
match True:
    # MatchSingleton
    case True:
        print("Matched the singleton True.")
    case None:
        print("Matched the singleton None.")
Jac Grammar Snippet

Description

Match capture patterns#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    day = " sunday";
    match day {
        case "monday":
            print("confirmed");
        case _:
            print("other");
    }
}
1
2
3
4
5
6
day = " sunday"
match day:
    case "monday":
        print("confirmed")
    case _:
        print("other")
Jac Grammar Snippet

Description

Match sequence patterns#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    data = [1, 2, 3];
    match data {
        case [1, 2, 3]:
            print("Matched");
        case _:
            print("Not Found");
    }
}
1
2
3
4
5
6
data = [1, 2, 3]
match data:
    case [1, 2, 3]:
        print("Matched")
    case _:
        print("Not Found")
Jac Grammar Snippet

Description

Match mapping patterns#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    data = {"key1": 1, "key2": 2, "232": 3453};
    match data {
        case {"key1" : 1, "key2" : 2, **rest}:
            print(
                f"Matched a mapping with key1 and key2. Rest: {rest}"
            );
    }
}
1
2
3
4
5
data = {"key1": 1, "key2": 2, "232": 3453}

match data:
    case {"key1": 1, "key2": 2, **rest}:
        print(f"Matched a mapping with key1 and key2. Rest: {rest}")
Jac Grammar Snippet

Description

Match class patterns#

Code Example

obj Point {
    has x: float,
        y: float;
}

with entry {
    data = Point(x=9, y=0);
    match data {
        case Point(int(a), y = 0):
            print(f"Point with x={a} and y=0");
        case _:
            print("Not on the x-axis");
    }
}
from jaclang import JacMachineInterface as _


class Point(_.Obj):
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y


data = Point(x=9, y=0)

match data:
    case Point(x=int(a), y=0):
        print(f"Point with x={a} and y=0")
    case _:
        print("Not on the x-axis")
Jac Grammar Snippet

Description

Context managers#

Code Example

1
2
3
4
5
with entry {
    with open(__file__, 'r') as file {
        print(file.read());
    }
}
with open(__file__.replace(".py", ".jac"), "r") as file:
    print(file.read())
Jac Grammar Snippet

Description

Global and nonlocal statements#

Code Example

glob x = "Jaclang ";

def outer_func -> None {
    :g: x;

    x = 'Jaclang is ';
    y = 'Awesome';
    def inner_func -> tuple[str, str] {
        :nl: y;

        y = "Fantastic";
        return (x, y);
    }
    print(x, y);
    print(inner_func());
}

with entry {
    outer_func();
}
x = "Jaclang "


def outer_func() -> None:
    global x
    x = "Jaclang is "
    y = "Awesome"

    def inner_func() -> tuple[str, str]:
        nonlocal y
        y = "Fantastic"
        return (x, y)

    print(x, y)
    print(inner_func())


outer_func()
Jac Grammar Snippet

Description

Data spatial typed context blocks#

Code Example

walker Producer {
    can produce with `root entry;
}

node Product {
    has number: int;

    can make with Producer entry;
}

impl Producer.produce {
    end = here;
    for i=0 to i<3 by i+=1  {
        end ++> (end := Product(number=i + 1));
    }
    visit [-->];
}

impl Product.make {
    print(f"Hi, I am {self} returning a String");
    visit [-->];
}

with entry {
    root spawn Producer();
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Producer(_.Walker):

    @_.entry
    def produce(self, here: _.Root) -> None:
        end = here
        i = 0
        while i < 3:
            _.connect(end, (end := Product(number=i + 1)))
            i += 1
        _.visit(self, _.refs(here))


class Product(_.Node):
    number: int

    @_.entry
    def make(self, here: Producer) -> None:
        print(f"Hi, I am {self} returning a String")
        _.visit(here, _.refs(self))


_.spawn(_.root(), Producer())
Jac Grammar Snippet

Description

Return statements#

Code Example

1
2
3
4
5
6
7
8
def foo -> int{
    a = 42;
    return a;
}

with entry {
    print("Returned:", foo());
}
1
2
3
4
5
6
def foo():
    a = 42
    return a


print("Returned:", foo())
Jac Grammar Snippet

Description

Yield statements#

Code Example

def myFunc {
    yield "Hello";
    yield 91;
    yield "Good Bye";
    yield ;
}

with entry {
    x = myFunc();
    for z in x {
        print(z);
    }
}
def myFunc() -> None:
    yield "Hello"
    yield 91
    yield "Good Bye"
    yield


x = myFunc()

for z in x:
    print(z)
Jac Grammar Snippet

Description

Raise statements#

Code Example

def foo(value: int) {
    if value < 0 {
        raise ValueError("Value must be non-negative");
    }
}

with entry {
    try  {
        foo(-1);
    } except ValueError as e  {
        print("Raised:", e);
    }
}
1
2
3
4
5
6
7
8
9
def foo(value: int):
    if value < 0:
        raise ValueError("Value must be non-negative")


try:
    foo(-1)
except ValueError as e:
    print("Raised:", e)
Jac Grammar Snippet

Description

Assert statements#

Code Example

def foo(value: int) {
    assert value > 0 , "Value must be positive";
}

with entry {
    try  {
        foo(-5);
    } except AssertionError as e  {
        print("Asserted:", e);
    }
}
1
2
3
4
5
6
7
8
def foo(value: int):
    assert value > 0, "Value must be positive"


try:
    foo(-5)
except AssertionError as e:
    print("Asserted:", e)
Jac Grammar Snippet

Description

Check statements#

Code Example

glob a = 5, b = 2;

test test1 {
    check almostEqual(a, 6);
}

test test2 {
    check a != b;
}

test test3 {
    check "d" in "abc";
}

test test4 {
    check a - b == 3;
}
from __future__ import annotations
from jaclang import *

a = 5
b = 2


@jac_test
def test_test1(_check) -> None:
    _check.assertAlmostEqual(a, 6)


@jac_test
def test_test2(_check) -> None:
    _check.assertNotEqual(a, b)


@jac_test
def test_test3(_check) -> None:
    _check.assertIn("d", "abc")


@jac_test
def test_test4(_check) -> None:
    _check.assertEqual(a - b, 3)
Jac Grammar Snippet

Description

Delete statements#

Code Example

1
2
3
4
5
6
with entry {
    x = [2, 4, 5, 7, 9];
    print("Before Delete:", x);
    del x[3];
    print("After Delete:", x);
}
1
2
3
4
x = [2, 4, 5, 7, 9]
print("Before Delete:", x)
del x[3]
print("After Delete:", x)
Jac Grammar Snippet

Description

Report statements#

Code Example

1
2
3
with entry {
    print("Not used.");
}
print("Not used.")
Jac Grammar Snippet

Description

Control statements#

Code Example

with entry {
    for i in range(9) {
        if i > 2 {
            print("loop is stopped!!");
            break;
        }
        print(i);
    }
    for j in "WIN" {
        if j == "W" {
            continue;
        }
        print(j);
    }
}
for i in range(9):
    if i > 2:
        print("loop is stopped!!")
        break
    print(i)

for j in "WIN":
    if j == "W":
        continue
    print(j)
Jac Grammar Snippet

Description

Data spatial Walker statements#

Code Example

walker Visitor {
    can self_destruct with entry {
        print("get's here");
        disengage;
        print("but not here");
    }
}

with entry {
    root spawn Visitor();
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Visitor(_.Walker):

    @_.entry
    def self_destruct(self, here: _.Root) -> None:
        print("get's here")
        return _.disengage(self)
        print("but not here")


_.spawn(_.root(), Visitor())
Jac Grammar Snippet

Description

Visit statements#

Code Example

walker Visitor {
    can travel with `root entry {
        visit [-->] else {
            visit root;
            disengage;
        }
    }
}

node item {
    can speak with Visitor entry {
        print("Hey There!!!");
    }
}

with entry {
    for i=0 to i<5 by i+=1  {
        root ++> item();
    }
    root spawn Visitor();
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Visitor(_.Walker):

    @_.entry
    def travel(self, here: _.Root) -> None:
        if not _.visit(self, _.refs(here)):
            _.visit(self, _.root())
            return _.disengage()


class item(_.Node):

    @_.entry
    def speak(self, here: Visitor) -> None:
        print("Hey There!!!")


i = 0
while i < 5:
    _.connect(_.root(), item())
    i += 1

_.spawn(_.root(), Visitor())
Jac Grammar Snippet

Description

Ignore statements#

Code Example

walker Visitor {
    can travel with `root entry {
        ignore [-->][0];
        visit [-->] else {
            visitroot;
        }
    }
}

node item {
    can speak with Visitor entry {
        print("Hey There!!!");
    }
}

with entry {
    for i=0 to i<5 by i+=1  {
        root ++> item();
    }
    root spawn Visitor();
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Visitor(_.Walker):

    @_.entry
    def travel(self, here: _.Root) -> None:
        _.ignore(self, _.refs(here)[0])
        if not _.visit(self, _.refs(here)):
            _.visit(self, _.root())


class item(_.Node):

    @_.entry
    def speak(self, here: Visitor) -> None:
        print("Hey There!!!")


i = 0
while i < 5:
    _.connect(_.root(), item())
    i += 1

_.spawn(_.root(), Visitor())
Jac Grammar Snippet

Description

Disengage statements#

Code Example

walker Visitor {
    can travel with `root entry {
        visit [-->] else {
            visit root;
        }
    }
}

node item {
    can speak with Visitor entry {
        print("Hey There!!!");
        disengage;
    }
}

with entry {
    for i=0 to i<5 by i+=1  {
        root ++> item();
    }
    root spawn Visitor();
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Visitor(_.Walker):

    @_.entry
    def travel(self, here: _.Root) -> None:
        if not _.visit(self, _.refs(here)):
            _.visit(self, _.root())


class item(_.Node):

    @_.entry
    def speak(self, here: Visitor) -> None:
        print("Hey There!!!")
        return _.disengage(here)


i = 0

while i < 5:
    _.connect(_.root(), item())
    i += 1

_.spawn(_.root(), Visitor())
Jac Grammar Snippet

Description

Assignments#

Code Example

with entry {
    a = b = 16;
    let c = 18;
    print(a, b, c);
    a>>=2;
    print(a);
    a<<=2;
    print(a);
    c//=4;
    print(c);
}
1
2
3
4
5
6
7
8
9
a = b = 16
c = 18
print(a, b, c)
a >>= 2
print(a)
a <<= 2
print(a)
c //= 4
print(c)
Jac Grammar Snippet

Description

Expressions#

Code Example

1
2
3
4
with entry {
    x = 1 if 5 / 2 == 1 else 2;
    print(x);
}
1
2
3
4
5
6
if 5 / 2 == 1:
    x = 1
else:
    x = 2

print(x)
Jac Grammar Snippet

Description

Concurrent expressions#

Code Example

import from time { sleep }

node A {
    has val: int = 0;

    can do with entry {
        print("Started");
        sleep(2);
        print(here);

    }
}

walker B {
    has name: str;

}

def add(x: int, y: int) -> int {
    print(x);
    z = x + y;
    sleep(2);
    print(x);
    return z;
}

with entry {
    t1 = flow A() spawn B("Hi") ;

    task1 = flow add(1, 10) ;
    task2 = flow add(2, 11) ;
    print("All are started");
    res1 = wait task1 ;
    res2 = wait task2 ;
    print("All are done");
    print(res1);
    print(res2);
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _
if _.TYPE_CHECKING:
    from time import sleep
else:
    sleep, = _.py_jac_import('time', __file__, lng='py', items={'sleep': None})

class A(_.Node):
    val: int = 0

    @_.entry
    def do(self, here) -> None:
        print('Started')
        sleep(2)
        print(here)

class B(_.Walker):
    name: str

def add(x: int, y: int) -> int:
    print(x)
    z = x + y
    sleep(2)
    print(x)
    return z
t1 = _.thread_run(lambda: _.spawn(A(), B('Hi')))
task1 = _.thread_run(lambda: add(1, 10))
task2 = _.thread_run(lambda: add(2, 11))
print('All are started')
res1 = _.thread_wait(task1)
res2 = _.thread_wait(task2)
print('All are done')
print(res1)
print(res2)
Jac Grammar Snippet

Description

concurrent expressions#

Concurrent expressions are representing in built concurrency in Jaclang.

Walrus assignments#

Code Example

1
2
3
4
5
6
with entry {
    a = 5;
    if (b := a + a // 2) > 5 {
        print("b is grater than 5");
    }
}
1
2
3
a = 5
if (b := (a + a // 2)) > 5:
    print("b is grater than 5")
Jac Grammar Snippet

Description

Lambda expressions#

Code Example

1
2
3
4
with entry {
    x = lambda a: int, b: int : b + a;
    print(x(5, 4));
}
x = lambda a, b: a + b
print(x(5, 4))
Jac Grammar Snippet

Description

Pipe expressions#

Code Example

1
2
3
4
5
6
7
8
9
def square(x: int) -> int {
    return (x ** 2);
}

with entry {
    number = 5;
    result = number |> square;
    print(result);
}
1
2
3
4
5
6
7
def square(x: int) -> int:
    return x**2


number = 5
result = square(number)
print(result)
Jac Grammar Snippet

Description

Pipe back expressions#

Code Example

1
2
3
4
5
6
7
8
9
def double(x: int) -> int {
    return (x * 2);
}

with entry {
    number = 5;
    result = double <| number;
    print(result);
}
1
2
3
4
5
6
7
def double(x: int) -> int:
    return x * 2


number = 5
result = double(number)
print(result)
Jac Grammar Snippet

Description

Bitwise expressions#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    p = print;
    p("&:", 5 & 3);
    p("|:", 5 | 3);
    p("^:", 5 ^ 3);
    p("~:", ~5);
    p("<<:", 5 << 1);
    p(">>:", 5 >> 1);
}
1
2
3
4
5
6
7
p = print
p("&:", 5 & 3)
p("|:", 5 | 3)
p("^:", 5 ^ 3)
p("~:", ~5)
p("<<:", 5 << 1)
p(">>:", 5 >> 1)
Jac Grammar Snippet

Description

Logical and compare expressions#

Code Example

with entry {
    if 5 > 4 {
        print("True");
    } elif "a" != "b" {
        print("'a' is 'a' ");
    } else {
        print("No");
    }
    a = [1, 2, 3];
    b = [1, 2, 3];
    print(a is b);
    print(3 in a);
    print(True or False);
    print(False and False);
}
if 5 > 4:
    print("True")
elif "a" != "a":
    print("'a' is 'a' ")
else:
    print("False")
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b)
print(3 in a)

print(True or False)
print(False and False)
Jac Grammar Snippet

Description

Arithmetic expressions#

Code Example

1
2
3
4
5
6
7
8
9
with entry {
    p = print;
    p("Multiply:", 7 * 2);
    p("Division:", 15 / 3);
    p("Floor:", 15 // 3);
    p("Modulo:", 17 % 5);
    p("Expon:", 2 ** 3);
    p("combo:", (9 + 2) * 9 - 2);
}
1
2
3
4
5
6
7
8
p = print

p("Multiply:", 7 * 2)
p("Division:", 15 / 3)
p("Floor:", 15 // 3)
p("Modulo:", 17 % 5)
p("Expon:", 2**3)
p("combo:", (9 + 2) * 9 - 2)
Jac Grammar Snippet

Description

Connect expressions#

Code Example

node node_a {
    has value: int;
}

walker Creator {
    can create with `root entry;
    can travel with `root | node_a entry;
}

edge MyEdge {
    has val: int = 5;
}

impl Creator.create {
    end = here;
    for i=0 to i<7 by i+=1  {
        if i % 2 == 0 {
            end ++> (end := node_a(value=i));
        } else {
            end +>:MyEdge:val=i:+> (end := node_a(value=i + 10));
        }
    }
}

impl Creator.travel {
    for i in [->:MyEdge:val <= 6:->] {
        print(i.value);
    }
    visit [-->];
}

with entry :__main__ {
    root spawn Creator();
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class node_a(_.Node):
    value: int


class Creator(_.Walker):

    @_.entry
    @_.impl_patch_filename(
        "/home/boyong/jaseci/jac/examples/reference/connect_expressions.jac"
    )
    def create(self, here: _.Root) -> None:
        end = here
        i = 0
        while i < 7:
            if i % 2 == 0:
                _.connect(end, (end := node_a(value=i)))
            else:
                _.connect(
                    end,
                    (end := node_a(value=i + 10)),
                    edge=MyEdge,
                    conn_assign=(("val",), (i,)),
                )
            i += 1

    @_.entry
    @_.impl_patch_filename(
        "/home/boyong/jaseci/jac/examples/reference/connect_expressions.jac"
    )
    def travel(self, here: _.Root | node_a) -> None:
        for i in _.refs(
            here, filter=lambda item: isinstance(item, MyEdge) and item.val <= 6
        ):
            print(i.value)
        _.visit(self, _.refs(here))


class MyEdge(_.Edge):
    val: int = 5


if __name__ == "__main__":
    _.spawn(_.root(), Creator())
Jac Grammar Snippet

Description

Atomic expressions#

Code Example

1
2
3
4
with entry {
    "Hello world!" :> print;
    "Welcome" :> type :> print;
}
print("Hello world!")
print(type("welcome"))
Jac Grammar Snippet

Description

Atomic pipe back expressions#

Code Example

1
2
3
4
5
6
7
with entry {
    print <: "Hello world!";
    a = [2, 4, 5, 7, 8];
    b = [4, 8, 9, 13, 20];
    c = len <: a + b :> len;
    print(c);
}
1
2
3
4
5
print("Hello world!")
a = [2, 4, 5, 7, 8]
b = [4, 8, 9, 13, 20]
c = len(a) + len(b)
print(c)
Jac Grammar Snippet

Description

Data spatial spawn expressions#

Code Example

walker Adder {
    can do with `root entry;
}

node node_a {
    has x: int = 0,
        y: int = 0;

    can add with Adder entry;
}

impl Adder.do {
    here ++> node_a();
    visit [-->];
}

impl node_a.add {
    self.x = 550;
    self.y = 450;
    print(int(self.x) + int(self.y));
}

with entry {
    # spawn will iniiate the walker Adder from root node
    Adder() spawn root;
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Adder(_.Walker):

    @_.entry
    def do(self, here: _.Root) -> None:
        _.connect(here, node_a())
        _.visit(self, _.refs(here))


class node_a(_.Node):
    x: int = 0
    y: int = 0

    @_.entry
    def add(self, here: Adder) -> None:
        self.x = 550
        self.y = 450
        print(int(self.x) + int(self.y))


_.spawn(Adder(), _.root())
Jac Grammar Snippet

Description

Unpack expressions#

Code Example

def combine_via_func(a: int, b: int, c: int, d: int) -> int {
    return a + b + c + d;
}

with entry {
    first_list = [1, 2, 3, 4, 5];
    second_list = [5, 8, 7, 6, 9];
    combined_list = [*first_list, *second_list];
    print(combined_list);

    # Original dictionary
    first_dict = {'a':1, 'b':2 };

    # Another dictionary
    second_dict = {'c':3, 'd':4 };

    # Combining dictionaries using dictionary unpacking
    combined_dict = {**first_dict, **second_dict };

    # Printing the combined dictionary
    print(combine_via_func(**combined_dict));
    print(combine_via_func(**first_dict, **second_dict));
}
def combine_via_func(a: int, b: int, c: int, d: int) -> int:
    return a + b + c + d


first_list = [1, 2, 3, 4, 5]
second_list = [5, 8, 7, 6, 9]
combined_list = [*first_list, *second_list]
print(combined_list)
first_dict = {"a": 1, "b": 2}
second_dict = {"c": 3, "d": 4}
combined_dict = {**first_dict, **second_dict}
print(combine_via_func(**combined_dict))
print(combine_via_func(**first_dict, **second_dict))
Jac Grammar Snippet

Description

References (unused)#

Code Example

1
2
3
with entry {
    print("Not used.");
}
print("Not used.")
Jac Grammar Snippet

Description

Data spatial calls#

Code Example

walker Creator {
    can func2 with `root entry;
}

node node_1 {
    has val: int;

    can func_1 with Creator entry;
}

impl node_1.func_1 {
    print("visiting ", self);
    visit [-->];
}

impl Creator.func2 {
    end = here;
    for i=0 to i<5 by i+=1  {
        end ++> (end := node_1(val=i + 1));
    }
    visit [-->];
}

with entry {
    root spawn :> Creator;
    root spawn |> Creator;
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Creator(_.Walker):

    @_.entry
    def func2(self, here: _.Root) -> None:
        end = here
        i = 0
        while i < 5:
            _.connect(end, (end := node_1(val=i + 1)))
            i += 1
        _.visit(self, _.refs(here))


class node_1(_.Node):
    val: int

    @_.entry
    def func_1(self, here: Creator) -> None:
        print("visiting ", self)
        _.visit(here, _.refs(self))


_.spawn(_.root(), Creator())
_.spawn(_.root(), Creator())
Jac Grammar Snippet

Description

Subscripted and dotted expressions#

Code Example

obj Sample {
    has my_list: list = [1, 2, 3],
        my_dict: dict = {"name":"John", "age": 30};
}

glob (first, second) = (Sample().my_list[2], Sample().my_dict["name"]);

with entry {
    print(first, second);
}
class Sample:
    def __init__(self):
        self.my_list = [1, 2, 3]
        self.my_dict = {"name": "John", "age": 30}


def main():
    sample_instance = Sample()
    first, second = sample_instance.my_list[2], sample_instance.my_dict["name"]

    print(first, second)


main()
Jac Grammar Snippet

Description

Function calls#

Code Example

1
2
3
4
5
6
7
8
9
def foo(x: int, y: int, z: int) {
    return (x * y, y * z);
}

with entry {
    a = 5;
    output = foo(x=4, y=4 if a % 3 == 2 else 3, z=9);
    print(output);
}
1
2
3
4
5
6
7
def foo(x: int, y: int, z: int) -> tuple[int, int]:
    return (x * y, y * z)


a = 5
output = foo(x=4, y=4 if a % 3 == 2 else 3, z=9)
print(output)
Jac Grammar Snippet

Description

Atom#

Code Example

impl x {
    aa=67,
    y="aaa" + f"b{aa}bbcc"
}

glob c = (3, 4, 5), list1 = [2, 3, 4, 5];

with entry {
    a = "abcde....";
    b = True;
    c = bin(12);
    d = hex(78);
    print(list1, a, b, c, d);

    # pp=0x4e;
    # print(0b1100);

    enum x;
    print(x.y.value);
}
class X:
    a_b = 67
    y = "aaa" + f"b{a_b}bbcc"


c = (3, 4, 5)
l_1 = [2, 3, 4, 5]


def entry():
    x = X

    a = "abcde...."
    b = True
    c = bin(12)
    d = hex(78)
    # e = 0x4E
    print(l_1, a, b, c, d)
    print(x.y)


# Run the entry block
entry()
Jac Grammar Snippet

Description

Collection values#

Code Example

with entry {
    squares = {num: num ** 2  for num in range(1, 6)};
    even_squares_set = {num ** 2  for num in range(1, 11) if num % 2 == 0};
    squares_generator = (num ** 2  for num in range(1, 6));
    squares_list = [num ** 2 for num in squares_generator if num != 9];

    print(
        "\n".join(
            [str(squares), str(even_squares_set), str(squares_list)]
        )
    );

    print(
        {"a": "b", "c": "d"}, # Dictionary
        {"a"}, # Set
        ("a", ), # Tuple
        ['a'] # List
    );
}
squares = {num: num**2 for num in range(1, 6)}
even_squares_set = {num**2 for num in range(1, 11) if num % 2 == 0}
squares_generator = (num**2 for num in range(1, 6))
squares_list = [num**2 for num in squares_generator if num != 9]

print("\n".join([str(squares), str(even_squares_set), str(squares_list)]))

print(
    {"a": "b", "c": "d"},  # Dictionary
    {"a"},  # Set
    ("a",),  # Tuple
    ["a"],  # List
)
Jac Grammar Snippet

Description

Tuples and Jac Tuples#

Code Example

def foo(first: int, second: int) -> None {
    print(first, second);
}

with entry {
    val1 = (3, ) + (4, );
    val2 = (val1[0] * val1[1], val1[0] + val1[1]);

    # Jac-style Tuples
    (second=val2[1], first=val2[0]) |> foo;
    (first=val2[0], second=val2[1]) |> foo;
}
def foo(first: int, second: int) -> None:
    print(first, second)


val1 = (3,) + (4,)
val2 = (val1[0] * val1[1], val1[0] + val1[1])


foo(second=val2[1], first=val2[0])
foo(first=val2[0], second=val2[1])
Jac Grammar Snippet

Description

Data Spatial References#

Code Example

walker Creator {
    can create with `root entry;
}

node node_a {
    has val: int;

    can make_something with Creator entry;
}

edge connector {
    has value: int = 10;
}

impl Creator.create {
    end = here;
    for i=0 to i<3 by i+=1  {
        end ++> (end := node_a(val=i));
    }
    end +>:connector:value=i:+> (end := node_a(val=i + 10));
    root <+:connector:value=i:<+ (end := node_a(val=i + 10));
    visit [-->];
}

impl node_a.make_something {
    i = 0;
    while i < 5 {
        print(f"wlecome to {self}");
        i += 1;
    }
}

with entry {
    root spawn Creator();
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _


class Creator(_.Walker):

    @_.entry
    def create(self, here: _.Root) -> None:
        end = here
        i = 0
        while i < 3:
            _.connect(end, (end := node_a(val=i)))
            i += 1

        _.connect(
            end,
            (end := node_a(val=i + 10)),
            edge=connector,
            conn_assign=(("value",), (i,)),
        )
        _.connect(
            (end := node_a(val=i + 10)),
            _.root(),
            edge=connector,
            conn_assign=(("value",), (i,)),
        )
        _.visit(self, _.refs(here))


class node_a(_.Node):
    val: int

    @_.entry
    def make_something(self, here: Creator) -> None:
        i = 0
        while i < 5:
            print(f"wlecome to {self}")
            i += 1


class connector(_.Edge):
    value: int = 10


_.spawn(_.root(), Creator())
Jac Grammar Snippet

Description

Special Comprehensions#

Code Example

#Filter comprehension
import random;

obj TestObj {
    has x: int = random.randint(0, 15),
        y: int = random.randint(0, 15),
        z: int = random.randint(0, 15);
}

with entry {
    random.seed(42);
    apple = [];
    for i=0 to i<100 by i+=1  {
        apple.append(TestObj());
    }

    # check if all apple's x are random between 0 and 15
    print(apple(?x >= 0, x <= 15) == apple);
}

obj MyObj {
    has apple: int = 0,
        banana: int = 0;
}

with entry {
    x = MyObj();
    y = MyObj();
    mvar = [x, y](=apple=5, banana=7);
    print(mvar);
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _

if _.TYPE_CHECKING:
    import random
else:
    (random,) = _.py_jac_import("random", __file__, lng="py")


class TestObj(_.Obj):
    x: int = random.randint(0, 15)
    y: int = random.randint(0, 15)
    z: int = random.randint(0, 15)


random.seed(42)
apple = []
i = 0
while i < 100:
    apple.append(TestObj())
    i += 1
print(_.filter(apple, lambda i: i.x >= 0 and i.x <= 15) == apple)


class MyObj(_.Obj):
    apple: int = 0
    banana: int = 0


x = MyObj()
y = MyObj()
mvar = _.assign([x, y], (("apple", "banana"), (5, 7)))
print(mvar)
Jac Grammar Snippet

Description

Names and references#

Code Example

obj Animal {
    has species: str;
    has sound: str;

}

obj Dog(Animal) {
    has breed: str;
    has trick: str by postinit;

    def postinit {
        self.trick = "Roll over";
    }
}

obj Cat(Animal) {
    def init(fur_color: str) {
        super.init(species="Cat", sound="Meow!");
        self.fur_color = fur_color;
    }
}

with entry {
    dog = Dog(breed="Labrador", species="Dog", sound="Woof!");
    cat = Cat(fur_color="Tabby");

    print(dog.breed, dog.sound, dog.trick);
    # print(f"The dog is a {dog.breed} and says '{dog.sound}'");
    # print(f"The cat's fur color is {cat.fur_color}");
}
from dataclasses import dataclass, field


@dataclass
class Animal:
    species: str
    sound: str


@dataclass
class Dog(Animal):
    breed: str
    trick: str = field(init=False)

    def __post_init__(self):
        self.trick = "Roll over"


@dataclass
class Cat(Animal):

    def __init__(self, fur_color: str):
        super().__init__(species="Cat", sound="Meow!")
        self.fur_color = fur_color


dog = Dog(breed="Labrador", species="Dog", sound="Woof!")
cat = Cat(fur_color="Tabby")

print(dog.breed, dog.sound, dog.trick)
# print(f'The dog is a {dog.breed} and says "{dog.sound}"')
# print(f"The cat's fur color is {cat.fur_color}")
Jac Grammar Snippet

Description

Builtin types#

Code Example

glob a = 9.2;

glob b = 44;

glob c = [2, 4, 6, 10];

glob d = {'name':'john', 'age':28 };

glob e = ("jaseci", 5, 4, 14);

glob f = True;

glob g = "Jaseci";

glob h = {5, 8, 12, "unique"};

with entry {
    print(type(a), '\n', type(b), '\n', type(c), '\n', type(d), '\n', type(e));
    print(type(f), '\n', type(g), '\n', type(h));
}
a = 9.2
b = 44
c = [2, 4, 6, 10]
d = {"name": "john", "age": 28}
e = ("jaseci", 5, 4, 14)
f = True
g = "Jaseci"
h = {5, 8, 12, "unique"}
print(type(a), "\n", type(b), "\n", type(c), "\n", type(d), "\n", type(e))
print(type(f), "\n", type(g), "\n", type(h))
Jac Grammar Snippet

Description

f-string tokens#

Code Example

with entry {
    x = "a";
    y = 25;
    print(f"Hello {x} {y} {{This is an escaped curly brace}}");
    person = {"name":"Jane", "age":25 };
    print(f"Hello, {person['name']}! You're {person['age']} years old.");
    print("This is the first line.\n This is the second line.");
    print("This will not print.\r This will be printed");
    print("This is \t tabbed.");
    print("Line 1\fLine 2");
    words = ["Hello", "World!", "I", "am", "a", "Jactastic!"];
    print(f"{'\n'.join(words)}");
}
x = "a"
y = 25
print(f"Hello {x} {y} {{This is an escaped curly brace}}")
person = {"name": "Jane", "age": 25}
print(f"Hello, {person['name']}! You're {person['age']} years old.")
print("This is the first line.\n This is the second line.")
print("This will not print.\r This will be printed")
print("This is \t tabbed.")
print("Line 1\x0cLine 2")
words = ["Hello", "World!", "I", "am", "a", "Jactastic!"]
print(
    f'''{"""
""".join(words)}'''
)
Jac Grammar Snippet

Description

Lexer Tokens#

Code Example

1
2
3
with entry {
    print("Example not applicable.");
}
print("Example not applicable.")
Jac Grammar Snippet

Description