Skip to content

Commit

Permalink
Better Jac cli
Browse files Browse the repository at this point in the history
  • Loading branch information
marsninja committed Sep 16, 2023
1 parent 9971829 commit ccbdcee
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Getting Started with JacLang
# Getting Started with the Jac Programming Language

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.

Expand Down
4 changes: 2 additions & 2 deletions jaclang/cli/cmds.jac
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import:jac from cli, cmd_registry as cmd_reg;
include:jac impl.cmds_impl;

@cmd_reg.register
can load(filename: str);
can run(filename: str);

@cmd_reg.register
can run(filename: str, entrypoint: str, args: list);
can enter(filename: str, entrypoint: str, args: list);

@cmd_reg.register
can ast_tool(tool: str);
Expand Down
29 changes: 23 additions & 6 deletions jaclang/cli/impl/cli_impl.jac
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,37 @@
cmd = func |> Command;
<s>.registry[name] = cmd;
cmd_parser = name |> <s>.sub_parsers.add_parser;
param_items = cmd.sig.parameters.items;
first = True;
for param_name, param in |> cmd.sig.parameters.items {
if param_name == "args" {
('args', nargs=argparse.REMAINDER)
|> cmd_parser.add_argument;
}
elif param.default is param.empty {
(f"-{param_name[:1]}", f"--{param_name}",
required=True, type=param.annotation|>eval)
|> cmd_parser.add_argument;
if first {
first = False;
(f"{param_name}", type=param.annotation|>eval)
|> cmd_parser.add_argument;
}
else {
(f"-{param_name[:1]}", f"--{param_name}",
required=True, type=param.annotation|>eval)
|> cmd_parser.add_argument;
}

}
else {
(f"-{param_name[:1]}", f"--{param_name}",
default=param.default, type=param.annotation|>eval)
|> cmd_parser.add_argument;
if first {
first = False;
(f"{param_name}", default=param.default, type=param.annotation|>eval)
|> cmd_parser.add_argument;
}
else {
(f"-{param_name[:1]}", f"--{param_name}",
default=param.default, type=param.annotation|>eval)
|> cmd_parser.add_argument;
}
}
}
return func;
Expand Down
6 changes: 3 additions & 3 deletions jaclang/cli/impl/cmds_impl.jac
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import:py os;
import:py shutil;

"""Load a .jac file and return the entrypoint function."""
:a:load
:a:run
(filename: str) {
if filename.endswith(".jac"){
[base, mod] = os.path.split(filename);
base = './' if not base else base;
mod=mod[:-4];
__jac_import__(target=mod, base_path=base);
__jac_import__(target=mod, base_path=base, override_name="__main__");
} else {
"Not a .jac file." :> print;
}
}

"""Run the entrypoint of the given .jac file."""
:a:run
:a:enter
(filename: str, entrypoint: str, args: list) {
if filename.endswith(".jac") {
[base, mod] = os.path.split(filename);
Expand Down
6 changes: 3 additions & 3 deletions jaclang/cli/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_jac_cli_load(self) -> None:
sys.stdout = captured_output

# Execute the function
cmds.load(self.fixture_abs_path("hello.jac")) # type: ignore
cmds.run(self.fixture_abs_path("hello.jac")) # type: ignore

sys.stdout = sys.__stdout__
stdout_value = captured_output.getvalue()
Expand All @@ -35,7 +35,7 @@ def test_jac_cli_err_output(self) -> None:

# Execute the function
try:
cmds.run(self.fixture_abs_path("err.jac"), entrypoint="speak", args=[]) # type: ignore
cmds.enter(self.fixture_abs_path("err.jac"), entrypoint="speak", args=[]) # type: ignore
except Exception as e:
print(f"Error: {e}")

Expand All @@ -55,7 +55,7 @@ def test_jac_cli_alert_based_err(self) -> None:

# Execute the function
try:
cmds.run(self.fixture_abs_path("err2.jac"), entrypoint="speak", args=[]) # type: ignore
cmds.enter(self.fixture_abs_path("err2.jac"), entrypoint="speak", args=[]) # type: ignore
except Exception as e:
print(f"Error: {e}")

Expand Down
28 changes: 22 additions & 6 deletions jaclang/jac/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def import_jac_module(
target: str,
base_path: Optional[str] = None,
cachable: bool = True,
override_name: Optional[str] = None,
) -> Optional[types.ModuleType]:
"""Core Import Process."""
target = path.join(*(target.split("."))) + ".jac"
Expand Down Expand Up @@ -54,7 +55,7 @@ def import_jac_module(

module = types.ModuleType(module_name)
module.__file__ = full_target
module.__name__ = module_name
module.__name__ = override_name if override_name else module_name
module.__dict__["_jac_pycodestring_"] = code_string

if (
Expand All @@ -65,7 +66,12 @@ def import_jac_module(
with open(py_file_path + "c", "rb") as f:
codeobj = marshal.load(f)
else:
codeobj = compile(code_string, f"_jac_py_gen ({module.__file__})", "exec")
try:
codeobj = compile(code_string, f"_jac_py_gen ({module.__file__})", "exec")
except Exception as e:
tb = traceback.extract_tb(e.__traceback__)
err = handle_jac_error(code_string, e, tb)
raise type(e)(str(e) + "\n" + err)
with open(py_file_path + "c", "wb") as f:
marshal.dump(codeobj, f)

Expand Down Expand Up @@ -118,14 +124,24 @@ def handle_jac_error(code_string: str, e: Exception, tb: traceback.StackSummary)


def jac_blue_import(
target: str, base_path: Optional[str] = None, cachable: bool = True
target: str,
base_path: Optional[str] = None,
cachable: bool = True,
override_name: Optional[str] = None,
) -> Optional[types.ModuleType]:
"""Jac Blue Imports."""
return import_jac_module(transpile_jac_blue, target, base_path, cachable)
return import_jac_module(
transpile_jac_blue, target, base_path, cachable, override_name
)


def jac_purple_import(
target: str, base_path: Optional[str] = None, cachable: bool = True
target: str,
base_path: Optional[str] = None,
cachable: bool = True,
override_name: Optional[str] = None,
) -> Optional[types.ModuleType]:
"""Jac Purple Imports."""
return import_jac_module(transpile_jac_purple, target, base_path, cachable)
return import_jac_module(
transpile_jac_purple, target, base_path, cachable, override_name
)
6 changes: 5 additions & 1 deletion jaclang/jac/passes/blue/blue_pygen_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@ def exit_ability(self, node: ast.Ability) -> None:
self.emit(node, node.body.meta["py_code"])
self.indent_level -= 1
self.emit_jac_error_handler(node)
elif node.is_abstract:
self.indent_level += 1
self.emit_ln(node, "pass")
self.indent_level -= 1
else:
self.decl_def_missing(ability_name)
self.indent_level -= 1
Expand Down Expand Up @@ -611,7 +615,7 @@ def exit_enum_block(self, node: ast.EnumBlock) -> None:
if isinstance(i, ast.Name):
self.emit_ln(node, i.meta["py_code"] + " = __jac_auto__()")
else:
self.emit(node, i.meta["py_code"])
self.emit_ln(node, i.meta["py_code"])

def exit_code_block(self, node: ast.CodeBlock) -> None:
"""Sub objects.
Expand Down
2 changes: 1 addition & 1 deletion jaclang/jac/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, msg: str, mod: str, line: int) -> None:

def __str__(self) -> str:
"""Return string representation of alert."""
return f"{self.mod}: Line {self.line}, {self.msg}"
return f"{self.mod}, line {self.line}: {self.msg}"


class TransformError(Exception):
Expand Down

0 comments on commit ccbdcee

Please sign in to comment.