Skip to content

Commit b23188c

Browse files
committed
Working on AST Generation
1 parent 61f6611 commit b23188c

3 files changed

Lines changed: 136 additions & 35 deletions

File tree

Requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ charset-normalizer==3.4.1
55
click==8.1.8
66
flake8==7.1.2
77
idna==3.10
8-
lionweb-python==0.1.8
8+
lionweb-python==0.1.14
99
mccabe==0.7.0
1010
pycodestyle==2.12.1
1111
pyflakes==3.2.0

pylasu/lionweb/ast_generation.py

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
11
import ast
22
from pathlib import Path
3-
from symtable import Class
4-
from typing import cast
3+
from typing import cast, List, Dict
54

65
import astor # Install with `pip install astor`
76
import click
8-
import os
9-
import sys
10-
117
from lionwebpython.language import Language, Concept, Interface
12-
from lionwebpython.language.classifier import Classifier
8+
from lionwebpython.language.enumeration import Enumeration
139
from lionwebpython.language.primitive_type import PrimitiveType
1410
from lionwebpython.lionweb_version import LionWebVersion
1511
from lionwebpython.serialization.serialization_provider import SerializationProvider
1612

17-
# Define the function AST
18-
func_def = ast.FunctionDef(
19-
name="hello_world",
20-
args=ast.arguments(
21-
posonlyargs=[], args=[], kwonlyargs=[], kw_defaults=[], defaults=[]
22-
),
23-
body=[
24-
ast.Expr(value=ast.Call(
25-
func=ast.Name(id="print", ctx=ast.Load()),
26-
args=[ast.Constant(value="Hello, world!")], keywords=[]
27-
))
28-
],
29-
decorator_list=[],
30-
)
31-
32-
# # Convert AST to code
33-
# module = ast.Module(body=[func_def], type_ignores=[])
34-
# generated_code = astor.to_source(module)
35-
#
36-
# print(generated_code)
37-
#
13+
from pylasu.lionweb.starlasu import StarLasuBaseLanguage
14+
15+
16+
def topological_concepts_sort(concepts: List[Concept]) -> List[Concept]:
17+
id_to_concept = {el.get_id(): el for el in concepts}
18+
19+
# Build graph edges: child -> [parents]
20+
graph: Dict[str, List[str]] = {el.get_id(): [] for el in concepts}
21+
for el in concepts:
22+
if el.get_extended_concept() and el.get_extended_concept().get_id() in id_to_concept:
23+
graph[el.get_id()].append(el.get_extended_concept().get_id())
24+
25+
visited = set()
26+
sorted_list = []
27+
28+
def visit(name: str):
29+
if name in visited:
30+
return
31+
visited.add(name)
32+
for dep in graph[name]:
33+
visit(dep)
34+
sorted_list.append(id_to_concept[name])
35+
36+
for el in concepts:
37+
visit(el.get_id())
38+
39+
return sorted_list
3840

3941
@click.command()
4042
@click.argument("dependencies", nargs=-1, type=click.Path(exists=True, dir_okay=False, readable=True))
@@ -51,27 +53,54 @@ def main(dependencies, lionweb_language, output):
5153
language = cast(Language, serialization.deserialize_string_to_nodes(content)[0])
5254
serialization.register_language(language=language)
5355
serialization.classifier_resolver.register_language(language)
54-
serialization.classifier_resolver.resolve_classifier(language)
56+
serialization.instance_resolver.add_tree(language)
5557

5658
click.echo(f"📄 Processing file: {lionweb_language}")
5759
with open(lionweb_language, "r", encoding="utf-8") as f:
5860
content = f.read()
5961
language = cast(Language, serialization.deserialize_string_to_nodes(content)[0])
6062

61-
module = ast.Module(body=[], type_ignores=[])
63+
import_abc = ast.ImportFrom(
64+
module='abc',
65+
names=[ast.alias(name='ABC', asname=None)],
66+
level=0
67+
)
68+
import_node = ast.ImportFrom(
69+
module='pylasu.model',
70+
names=[ast.alias(name='Node', asname=None)],
71+
level=0
72+
)
73+
module = ast.Module(body=[import_abc, import_node], type_ignores=[])
74+
75+
6276
for element in language.get_elements():
6377
if isinstance(element, Concept):
64-
classdef = ast.ClassDef(element.get_name(), bases=[], # No parent classes
65-
keywords=[],
66-
body=[ast.Pass()],
67-
decorator_list=[])
68-
module.body.append(classdef)
78+
pass
6979
elif isinstance(element, Interface):
7080
pass
7181
elif isinstance(element, PrimitiveType):
7282
pass
83+
elif isinstance(element, Enumeration):
84+
pass
7385
else:
7486
raise ValueError(f"Unsupported {element}")
87+
88+
sorted_concepts = topological_concepts_sort([c for c in language.get_elements() if isinstance(c, Concept)])
89+
90+
for concept in sorted_concepts:
91+
bases = []
92+
if concept.get_extended_concept().id == StarLasuBaseLanguage.get_astnode(LionWebVersion.V2023_1).id:
93+
bases.append('Node')
94+
else:
95+
bases.append(concept.get_extended_concept().get_name())
96+
if concept.is_abstract():
97+
bases.append('ABC')
98+
classdef = ast.ClassDef(concept.get_name(), bases=bases,
99+
keywords=[],
100+
body=[ast.Pass()],
101+
decorator_list=[])
102+
module.body.append(classdef)
103+
75104
click.echo(f"📂 Saving results to: {output}")
76105
generated_code = astor.to_source(module)
77106
output_path = Path(output)

pylasu/lionweb/starlasu.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from typing import TYPE_CHECKING, Dict, Optional, cast
2+
3+
from lionwebpython.language import Language, Concept
4+
from lionwebpython.language.lioncore_builtins import LionCoreBuiltins
5+
from lionwebpython.language.primitive_type import PrimitiveType
6+
from lionwebpython.lionweb_version import LionWebVersion
7+
8+
class StarLasuBaseLanguage(Language):
9+
if TYPE_CHECKING:
10+
from lionwebpython.language.concept import Concept
11+
from lionwebpython.language.interface import Interface
12+
from lionwebpython.language.primitive_type import PrimitiveType
13+
from lionwebpython.language.property import Property
14+
from lionwebpython.lionweb_version import LionWebVersion
15+
from lionwebpython.utils.id_utils import IdUtils
16+
17+
_instances: Dict["LionWebVersion", "LionCoreBuiltins"] = {}
18+
19+
def __init__(self, lion_web_version: "LionWebVersion"):
20+
super().__init__(lion_web_version=lion_web_version, name="com.strumenta.StarLasu")
21+
from lionwebpython.lionweb_version import LionWebVersion
22+
from lionwebpython.utils.id_utils import IdUtils
23+
24+
version_id_suffix = (
25+
f"-{IdUtils.clean_string(lion_web_version.value)}"
26+
if lion_web_version != LionWebVersion.V2023_1
27+
else ""
28+
)
29+
30+
if lion_web_version == LionWebVersion.V2023_1:
31+
version = "1"
32+
elif lion_web_version == LionWebVersion.V2024_1:
33+
version = "2"
34+
else:
35+
raise ValueError()
36+
37+
self.set_id(f"com-strumenta-StarLasu{version_id_suffix}")
38+
self.set_key("com_strumenta_starlasu")
39+
self.set_version(version)
40+
41+
self.char = PrimitiveType(lion_web_version=lion_web_version, language=self,
42+
name="Char", id=f"com-strumenta-StarLasu-Char-id{version_id_suffix}",
43+
key="com_strumenta_starlasu-Char-key")
44+
self.point = PrimitiveType(lion_web_version=lion_web_version, language=self,
45+
name="Point", id=f"com-strumenta-StarLasu-Point-id{version_id_suffix}",
46+
key="com_strumenta_starlasu-Point-key")
47+
self.position = PrimitiveType(lion_web_version=lion_web_version, language=self,
48+
name="Position", id=f"com-strumenta-StarLasu-Position-id{version_id_suffix}",
49+
key="com_strumenta_starlasu-Position-key")
50+
self.astnode = Concept(lion_web_version=lion_web_version, language=self,
51+
name="ASTNode", key="com_strumenta_starlasu-ASTNode-key",
52+
id="com-strumenta-StarLasu-ASTNode-id")
53+
54+
@classmethod
55+
def get_astnode(
56+
cls, lion_web_version: LionWebVersion = LionWebVersion.current_version()
57+
) -> "Concept":
58+
return cls.get_instance(lion_web_version).astnode
59+
60+
@classmethod
61+
def get_instance(
62+
cls, lion_web_version: Optional["LionWebVersion"] = None
63+
) -> "StarLasuBaseLanguage":
64+
if lion_web_version is None:
65+
from lionwebpython.lionweb_version import LionWebVersion
66+
67+
lion_web_version = LionWebVersion.current_version()
68+
69+
if lion_web_version not in cls._instances:
70+
cls._instances[lion_web_version] = StarLasuBaseLanguage(lion_web_version)
71+
72+
return cls._instances[lion_web_version]

0 commit comments

Comments
 (0)