forked from Jaseci-Labs/jaclang
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Jaseci-Labs#45 from Jaseci-Labs/manual_roadmap_ex
Manual roadmap ex
- Loading branch information
Showing
18 changed files
with
525 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[flake8] | ||
exclude = fixtures, __jac_gen__, build | ||
exclude = fixtures, __jac_gen__, build, examples | ||
plugins = flake8_import_order, flake8_docstrings, flake8_comprehensions, flake8_bugbear, flake8_annotations, pep8_naming, flake8_simplify | ||
max-line-length = 120 | ||
ignore = E203, W503, ANN101, ANN102 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,197 @@ | ||
# The Jac Programming Language and Jaseci Core | ||
# Getting Started with JacLang | ||
|
||
The next generation is upon us... (In ideation and specification phase) | ||
Welcome to JacLang, a unique and powerful programming language that runs on top of Python. To get you started, this guide will walk you through the process of installation, running Jac files, and importing Jac into existing Python modules. | ||
|
||
Get to the docs, check the guidelines on how to contribute. | ||
## Installation | ||
|
||
## Getting Docs Up Locally | ||
Firstly, you'll need to install JacLang. You can do this easily through Python's package manager, pip. Run the following command: | ||
|
||
Go to `/docs` base dir and run | ||
```bash | ||
pip install jaclang | ||
``` | ||
|
||
And from source simply use, | ||
|
||
```bash | ||
yarn install | ||
yarn start | ||
pip install -e . | ||
``` | ||
|
||
Upon successful installation, you'll have a script named `jac` at your disposal. This script is used to load and run `.jac` files. | ||
|
||
## Running Jac Files | ||
|
||
Here's how you can use `jac`: | ||
|
||
- To simply load a sample Jac module and exit, run: | ||
```bash | ||
jac load -f sample.jac | ||
``` | ||
|
||
- To load a sample Jac module and execute a particular function (considered the entrypoint for execution in Jac), run: | ||
```bash | ||
jac run -f sample.jac -e my_func | ||
``` | ||
|
||
Now Try it with this example jac program with both load and calling `test_run` | ||
|
||
```jac | ||
"""Example of simple walker walking nodes.""" | ||
node item { | ||
has value: int; | ||
} | ||
walker Creator { | ||
has count: int = 0; | ||
can create with <root>|:n:item entry { | ||
<here> ++> spawn :n:item; | ||
<self>.count += 1; | ||
if <self>.count < 10 { | ||
visit -->; | ||
} | ||
} | ||
} | ||
walker Walk { | ||
has count: int = 0; | ||
can skip_root with <root> entry { visit -->; } | ||
can step with :n:item entry { | ||
<here>.value = <self>.count; | ||
<self>.count += 1; | ||
visit --> else { | ||
f"Final Value: {<here>.value-1}" |> print; | ||
"Done walking." |> print; | ||
disengage; | ||
} | ||
f"Value: {<here>.value-1}" |> print; | ||
} | ||
} | ||
can test_run { | ||
spawn :w:Creator |> <root>; | ||
spawn :w:Walk |> <root>; | ||
} | ||
with entry { | ||
|> test_run; | ||
} | ||
``` | ||
For instructions on installing `yarn`, start on that journey with [their instructions](https://yarnpkg.com/getting-started/install). | ||
## Integrating Jac into Python Modules | ||
JacLang also provides a seamless way to import Jac into existing Python modules through library functions. Here's an example: | ||
```python | ||
"""CLI for jaclang.""" | ||
from jaclang import jac_purple_import as jac_import | ||
cli = jac_import("cli") | ||
cmds = jac_import("cmds") | ||
cli.cmd_registry = cmds.cmd_reg # type: ignore | ||
``` | ||
In the above code snippet, `cli` and `cmds` are modules that are imported similar to how you'd typically import modules in Python, i.e., `import cli` or `import cmds`. | ||
Below is a sample `cli.jac` file to provide some insight into how Jac code looks: | ||
```jac | ||
""" | ||
This is the implementation of the command line interface tool for the | ||
Jac language. It's built with the Jac language via bootstraping and | ||
represents the first such complete Jac program. | ||
""" | ||
import:py inspect; | ||
import:py argparse; | ||
import:py cmd; | ||
include:jac impl.cli_impl; | ||
object Command { | ||
has func: callable, | ||
sig: inspect.Signature; | ||
can:private init(func: callable); | ||
can call(*args: list, **kwargs: dict); | ||
} | ||
object CommandRegistry { | ||
has:private registry: dict[str, Command], | ||
sub_parsers: argparse._SubParsersActionp; | ||
has:public parser: argparse.ArgumentParser; | ||
can init; | ||
can register(func: callable); | ||
can get(name: str) -> Command; | ||
can items -> dict[str, Command]; | ||
} | ||
object CommandShell:cmd.Cmd { | ||
static has intro: str = "Welcome to the Jac CLI!", | ||
prompt: str = "jac> "; | ||
has cmd_reg: CommandRegistry; | ||
can init (cmd_reg: CommandRegistry); | ||
can do_exit(arg: list) -> bool; | ||
can default(line: str); | ||
} | ||
global cmd_registry = |> CommandRegistry; | ||
can start_cli; | ||
``` | ||
That's all you need to get started with JacLang. As you delve into this new language, you'll discover how it beautifully combines the power of Python with a modern and intuitive syntax. Happy coding! | ||
## Installing JacLang Extension in Visual Studio Code (VSCode) | ||
In addition to setting up JacLang itself, you may also want to take advantage of the JacLang language extension for Visual Studio Code (VSCode). This will give you enhanced code highlighting, autocomplete, and other useful language features within your VSCode environment. | ||
Here's a step-by-step guide on how to package and install the JacLang VSCode extension. | ||
### Setting Up VSCE | ||
To create the VSIX file for the extension, you'll need `vsce`, a command-line tool for packaging VSCode extensions. If you don't have it installed already, follow these steps: | ||
1. Ensure that you have Node.js (>= 0.10.x) and npm installed on your machine. | ||
2. Open a terminal (or command prompt) and install `vsce` globally by running the following command: | ||
```bash | ||
npm install -g vsce | ||
``` | ||
### Packaging the Extension | ||
Once you have `vsce` set up, navigate to the JacLang extension directory in your local JacLang repository by running: | ||
```bash | ||
cd /path/to/repo/jaclang/support/vscode_ext/jac | ||
``` | ||
In the `jac` directory, package the extension into a VSIX file by running: | ||
```bash | ||
vsce package | ||
``` | ||
This will create a `.vsix` file, which is the packaged extension. | ||
### Installing the VSIX File in VSCode | ||
To install the packaged JacLang extension in VSCode: | ||
1. Open Visual Studio Code. | ||
2. Click on the Extensions view icon on the Sidebar (or press `Ctrl+Shift+X`). | ||
3. Click on the three-dot menu (`...`) in the top-right corner of the Extensions view. | ||
4. Select `Install from VSIX...` from the dropdown menu. | ||
5. In the file picker, find and select the `.vsix` file you created earlier and click `Open`. | ||
6. After a brief moment, the extension will be installed. You might have to reload VSCode for the changes to take effect. | ||
Now, you're all set to use the JacLang language extension in your VSCode editor! Enjoy your enhanced JacLang development experience. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
""" | ||
(Module docstring are Required in a valid Jac) | ||
This module demonstrates a simple circle class and a function to calculate the area of a circle. | ||
""" | ||
import:py math; | ||
|
||
# Module-level global | ||
global RADIUS = 5; | ||
|
||
"""Function to calculate the area of a circle.""" | ||
can calculate_area(radius: float) -> float { | ||
return math.pi * radius * radius; | ||
} | ||
|
||
#* (This is multiline comments in Jac) | ||
Above we have the demonstration of a function to calculate the area of a circle. | ||
Below we have the demonstration of a class to calculate the area of a circle. | ||
*# | ||
|
||
"""Enum for shape types""" | ||
enum ShapeType { | ||
CIRCLE = "Circle", | ||
UNKNOWN = "Unknown" | ||
} | ||
|
||
"""Base class for a shape.""" | ||
object Shape { | ||
has shape_type: ShapeType; | ||
|
||
can <init>(shape_type: ShapeType) { | ||
<self>.shape_type = shape_type; | ||
} | ||
|
||
"""Abstract method to calculate the area of a shape.""" | ||
can area -> float abstract; | ||
} | ||
|
||
|
||
object Circle:Shape { | ||
"""Circle class inherits from Shape.""" | ||
|
||
can <init>(radius: float) { | ||
<super>.<init>(ShapeType.CIRCLE); | ||
self.radius = radius; | ||
} | ||
|
||
"""Overridden method to calculate the area of the circle.""" | ||
can area -> float { | ||
return math.pi * self.radius * self.radius; | ||
} | ||
} | ||
|
||
with entry {c = Circle(RADIUS);} # Global also works here | ||
|
||
with entry:__main__ { # TODO: add name == option abstract feature | ||
# To run the program functionality | ||
print(f"Area of a circle with radius 5: {calculate_area(RADIUS)}"); | ||
print(f"Area of a {c.shape_type.value} with radius 5: {c.area()}"); | ||
} | ||
|
||
test calculate_area | ||
"Tests for the calculate_area function." { | ||
expected_area = 78.53981633974483; | ||
assertAlmostEqual(calculate_area(RADIUS), expected_area); | ||
} | ||
|
||
test circle_area | ||
"Tests for the area method of the Circle class." { | ||
c = Circle(RADIUS); | ||
expected_area = 78.53981633974483; | ||
assertAlmostEqual(c.area(), expected_area); | ||
} | ||
|
||
test circle_type | ||
"Tests for the shape_type attribute of the Circle class." { | ||
c = Circle(RADIUS); | ||
assertEqual(c.shape_type, ShapeType.CIRCLE); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
""" | ||
This module demonstrates a simple circle class and a function to calculate the area of a circle. | ||
(Module docstrings are optional but good practice in python) | ||
""" | ||
from enum import Enum | ||
import math | ||
import unittest | ||
|
||
# Module-level global | ||
RADIUS = 5 | ||
|
||
|
||
def calculate_area(radius: float) -> float: | ||
"""Function to calculate the area of a circle.""" | ||
return math.pi * radius * radius | ||
|
||
|
||
# Multiline comments in python feels like a hack | ||
""" | ||
Above we have the demonstration of a function to calculate the area of a circle. | ||
Below we have the demonstration of a class to calculate the area of a circle. | ||
""" | ||
|
||
|
||
# Enum for shape types | ||
class ShapeType(Enum): | ||
CIRCLE = "Circle" | ||
UNKNOWN = "Unknown" | ||
|
||
|
||
class Shape: | ||
"""Base class for a shape.""" | ||
|
||
def __init__(self, shape_type: ShapeType): | ||
self.shape_type = shape_type | ||
|
||
def area(self) -> float: | ||
"""Returns the area of the shape.""" | ||
pass | ||
|
||
|
||
class Circle(Shape): | ||
"""Circle class inherits from Shape.""" | ||
|
||
def __init__(self, radius: float): | ||
super().__init__(ShapeType.CIRCLE) | ||
self.radius = radius | ||
|
||
def area(self) -> float: | ||
"""Overridden method to calculate the area of the circle.""" | ||
return math.pi * self.radius * self.radius | ||
|
||
|
||
c = Circle(RADIUS) | ||
|
||
if __name__ == "__main__": | ||
# To run the program functionality | ||
print( | ||
f"Area of a circle with radius {RADIUS} using function: {calculate_area(RADIUS)}" | ||
) | ||
print( | ||
f"Area of a {c.shape_type.value} with radius {RADIUS} using class: {c.area()}" | ||
) | ||
|
||
# Uncomment the next line if you want to run the unit tests | ||
# run_tests() | ||
|
||
|
||
# Unit tests below, bad practice in python to have unit tests in the same file as the code | ||
class TestShapesFunctions(unittest.TestCase): | ||
def test_calculate_area(self): | ||
expected_area = 78.53981633974483 | ||
self.assertAlmostEqual(calculate_area(RADIUS), expected_area) | ||
|
||
def test_circle_area(self): | ||
c = Circle(RADIUS) | ||
expected_area = 78.53981633974483 | ||
self.assertAlmostEqual(c.area(), expected_area) | ||
|
||
def test_circle_type(self): | ||
c = Circle(RADIUS) | ||
self.assertEqual(c.shape_type, ShapeType.CIRCLE) |
Oops, something went wrong.