Skip to content

Commit 9e7abb5

Browse files
Python Class compiler
1 parent 4aa731e commit 9e7abb5

File tree

13 files changed

+119
-42
lines changed

13 files changed

+119
-42
lines changed

blueprints/global/communication/chat/models/message.model.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"id": {"type":"id", "required":true},
1010
"conversation": {"type":"conversation", "required":true},
1111
"user":{"type":"__user", "required":true},
12-
"content":{"type":"str", "required":true},
12+
"content":{"type":"str", "max":300, "required":true},
1313
"read_by":{"many":true, "type":"__user", "required":true}
1414
},
1515
"create":{

compiler/compiler.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,12 @@
1111
"nodejs.json.v1": "under development",
1212
"json.v1": json_compiler
1313
}
14-
def compile(compiler_name, project_name):
15-
save_file = ""
14+
def compile(compiler_name, project_name, save_folder=""):
1615
save = False
1716
if len(sys.argv) >= 4:
18-
save_file = sys.argv[4]
1917
save = True
20-
else:
21-
save_file = "build"
22-
compiler = COMPILERS[compiler_name](main_file=project_name, save_file=save_file)
18+
compiler = COMPILERS[compiler_name](main_file=project_name, save_folder=save_folder)
2319
compiled_project = compiler.compile(save=save)
24-
print(compiled_project)
2520
# TODO: propper file extension and format saving
2621
'''
2722
with open(f"./{sys.argv[4]}", "w") as f:
@@ -36,7 +31,7 @@ def main():
3631
# 2 compiler
3732
# 3 project
3833
# 4 destination folder
39-
OPTIONS[sys.argv[1]](sys.argv[2], sys.argv[3])
34+
OPTIONS[sys.argv[1]](*sys.argv[2:])
4035
return
4136

4237
main()
@@ -45,7 +40,7 @@ def main():
4540
# python .\compiler.py c "json.v1" ./sample_blueprints/samples/construct.app.json build
4641
# python .\compiler.py c "json.v1" ../blueprints/examples/calculator/v2/main.app.json build
4742

48-
# python .\compiler.py c "django.json.v1" ../blueprints/examples/facebook/main.app.json build
49-
# python .\compiler.py c "python.json.v1" ../blueprints/examples/calculator/v2/services/processing/operations/sum.code.json build/build
43+
# python .\compiler\compiler.py c "django.json.v1" ./blueprints/examples/facebook/main.app.json compiler/build
44+
# python .\compiler\compiler.py c "python.json.v1" ./blueprints/examples/calculator/v2/services/processing/operations/sum.code.json compiler/build
5045

51-
# python .\compiler\compiler.py c "python.json.v1" ./blueprints/global/utils/code/is_prime.json code.py
46+
# python .\compiler\compiler.py c "python.json.v1" ./blueprints/global/utils/code/is_prime.json compiler/build/code.py

compiler/json_compiler/Compiler.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ def json_global_compile(json_dict, *, args = {}, base_folder=None, base_dict={},
148148
class Compiler:
149149
blueprint: dict = {}
150150

151-
def __init__(self, *, main_file, save_file) -> None:
152-
self.save_file = Path(save_file)
151+
def __init__(self, *, main_file, save_folder) -> None:
152+
self.save_folder = Path(save_folder)
153153
self.main_folder = Path(os.path.dirname(main_file))
154154
self.main_file = Path(main_file)
155155
self.blueprint = load_json_as_dict(self.main_file)
@@ -197,12 +197,14 @@ def compile_services(self, build):
197197
build[SEVICES_FIELD] = services
198198
return build
199199

200-
def compile(self, *, save) -> dict:
200+
def compile(self, *, save:bool=False) -> dict:
201201
build = json_global_compile(self.blueprint, base_folder=self.main_folder)
202202
build = self.compile_models(build)
203203
build = self.compile_services(build)
204204
if save:
205-
with open(self.save_file, "w") as f:
205+
with open(self.save_folder, "w") as f:
206206
json.dump(build, f, indent=4)
207207
#print(build)
208-
return build
208+
files = {}
209+
files[str(self.save_folder)] = build
210+
return files

compiler/python_compiler/Compiler.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import os
22
import json
3+
from pathlib import Path
34

45
from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict
56
from .engines.py3_8.Compiler import compile as py3_9_compiler
67
from utils.CustomLogging import CustomLogging
78

9+
810
FLAG_ENGINE = "engine"
911
ENGINES = {
1012
"python3.8":py3_9_compiler
1113
}
1214
class Compiler:
1315
blueprint: dict = {}
1416

15-
def __init__(self, *, save_file, main_file:str = "", blueprint:dict = {}) -> None:
16-
self.save_file = save_file
17+
def __init__(self, *, save_folder:str="", main_file:str="", blueprint:dict={}) -> None:
18+
self.save_folder = Path(save_folder)
1719
if main_file:
1820
self.main_folder = os.path.dirname(main_file)
1921
self.main_file = main_file
@@ -22,7 +24,7 @@ def __init__(self, *, save_file, main_file:str = "", blueprint:dict = {}) -> Non
2224
self.blueprint = special_flags_processing(raw_blueprint, base_folder=self.main_folder)
2325
if blueprint:
2426
self.blueprint = special_flags_processing(blueprint, base_folder=self.main_folder)
25-
27+
2628
def compile(self, *, save = False) -> dict:
2729
build = ""
2830
if engine_type := self.blueprint.get(FLAG_ENGINE):
@@ -32,7 +34,10 @@ def compile(self, *, save = False) -> dict:
3234
CustomLogging.error(f"Compiler {engine_type} does not exists")
3335
else:
3436
CustomLogging.error(f"Flag {FLAG_ENGINE} not defined")
37+
file_path = str(self.save_folder / (self.blueprint.get("name","main")+".py"))
3538
if save:
36-
with open(self.save_file, "w") as f:
39+
with open(file_path, "w") as f:
3740
f.write(build)
38-
return build
41+
files = {}
42+
files[file_path] = build
43+
return files
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from .Fragment import Fragment
2+
from .FunctionCall import FunctionCall
3+
from utils.flags import *
4+
from utils.CustomLogging import CustomLogging
5+
6+
def get_class_name(fragment) -> str:
7+
if not (class_name := fragment.get(ATTRIBUTE_CLASS_NAME)):
8+
CustomLogging.critical(f"Required Fragment type class 'name' attribute not defined")
9+
return class_name
10+
11+
def get_class_extends(fragment) -> dict:
12+
if not (class_extends := fragment.get(ATTRIBUTE_CLASS_EXTENDS)):
13+
class_extends = {}
14+
return class_extends
15+
16+
def get_class_attributes(fragment) -> dict:
17+
if not (class_attributes := fragment.get(ATTRIBUTE_CLASS_ATTRIBUTES)):
18+
class_attributes = {}
19+
return class_attributes
20+
21+
def get_class_code(fragment) -> list:
22+
if not (class_code := fragment.get(ATTRIBUTE_CLASS_CODE)):
23+
class_code = []
24+
return class_code
25+
26+
class Class(Fragment):
27+
name:str
28+
extends:dict
29+
attributes:dict
30+
code:dict
31+
def __init__(self, blueprint, *args, **kwargs) -> None:
32+
super().__init__( blueprint, *args, **kwargs)
33+
self.name = get_class_name(blueprint)
34+
self.extends = get_class_extends(blueprint)
35+
self.attributes = get_class_attributes(blueprint)
36+
self.code = get_class_code(blueprint)
37+
def extends_compile(self) -> str:
38+
extends_build = ""
39+
if len(self.extends) > 0:
40+
extends_build = f"({', '.join(self.extends)})"
41+
return extends_build
42+
43+
def get_attributes(self) -> list:
44+
lines = []
45+
for attr in self.attributes:
46+
self.attributes[attr]["type"] = "variable"
47+
fc = FunctionCall(self.attributes[attr], compile=self.general_compile)
48+
lines.append(
49+
attr+" = "+fc.compile()
50+
)
51+
return self.tabulate(lines, 1)
52+
53+
def get_lines(self) -> list:
54+
fragment_lines = []
55+
fragment_lines.append(f"class {self.name}{self.extends_compile()}:")
56+
fragment_lines.extend(self.get_attributes())
57+
fragment_lines.extend(self.code_lines_compile(self.code))
58+
fragment_lines = self.tabulate(fragment_lines)
59+
return fragment_lines
60+
61+
def compile(self) -> str:
62+
fragment_build = "\n".join(self.get_lines())
63+
return fragment_build

compiler/python_compiler/engines/py3_8/Conditional.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55

66
def get_conditional_condition(fragment) -> str:
77
if not (condition := fragment.get(ATTRIBUTE_CONDITIONAL_CONDITION)):
8-
CustomLogging.critical(f"Fragment type conditional '{ATTRIBUTE_CONDITIONAL_CONDITION}' attribute does not exist")
8+
CustomLogging.critical(f"Required Fragment type conditional '{ATTRIBUTE_CONDITIONAL_CONDITION}' attribute does not exist")
99
return condition
1010

1111
def get_conditional_code(fragment) -> list:
1212
if not (code := fragment.get(ATTRIBUTE_CONDITIONAL_CODE)):
13-
CustomLogging.critical(f"Fragment type conditional '{ATTRIBUTE_CONDITIONAL_CODE}' attribute does not exist")
13+
CustomLogging.critical(f"Required Fragment type conditional '{ATTRIBUTE_CONDITIONAL_CODE}' attribute does not exist")
1414
return code
1515
class Conditional(Fragment):
1616
condition:str

compiler/python_compiler/engines/py3_8/For.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@
55

66
def get_for_code(fragment) -> str:
77
if not (code := fragment.get(ATTRIBUTE_FOR_CODE)):
8-
CustomLogging.critical(f"Fragment type for '{ATTRIBUTE_FOR_CODE}' attribute does not exist")
8+
CustomLogging.critical(f"Required Fragment type for '{ATTRIBUTE_FOR_CODE}' attribute does not exist")
99
return code
1010

1111
def get_for_else_code(fragment) -> str:
1212
if not (code := fragment.get(ATTRIBUTE_FOR_ELSE_CODE)):
13-
CustomLogging.critical(f"Fragment type for '{ATTRIBUTE_FOR_ELSE_CODE}' attribute does not exist")
13+
CustomLogging.critical(f"Required Fragment type for '{ATTRIBUTE_FOR_ELSE_CODE}' attribute does not exist")
1414
return code
1515

1616
def get_for_iterators(fragment) -> list:
1717
if not (iterators := fragment.get(ATTRIBUTE_FOR_ITERATORS)):
18-
CustomLogging.critical(f"Fragment type for '{ATTRIBUTE_FOR_ITERATORS}' attribute does not exist")
18+
CustomLogging.critical(f"Required Fragment type for '{ATTRIBUTE_FOR_ITERATORS}' attribute does not exist")
1919
return iterators
2020

2121
def get_for_sequence(fragment) -> list:
2222
if not (sequence := fragment.get(ATTRIBUTE_FOR_SEQUENCE)):
23-
CustomLogging.critical(f"Fragment type for '{ATTRIBUTE_FOR_SEQUENCE}' attribute does not exist")
23+
CustomLogging.critical(f"Required Fragment type for '{ATTRIBUTE_FOR_SEQUENCE}' attribute does not exist")
2424
return sequence
2525

2626

compiler/python_compiler/engines/py3_8/Fragment.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ def code_lines_compile(self, fragments) -> list:
2222
code_build_lines.extend(line_build)
2323
return code_build_lines
2424

25-
def tabulate(self, lines) -> list:
25+
def tabulate(self, lines, custom_tabs=0) -> list:
2626
tabulated_lines = []
2727
for line in lines:
28-
tabs = TAB * ( 0 if self.level == 0 else 1)
28+
level = self.level if custom_tabs == 0 else custom_tabs
29+
tabs = TAB * ( 0 if level == 0 else 1)
2930
tabulated_lines.append(tabs+line)
3031
return tabulated_lines
3132

compiler/python_compiler/engines/py3_8/Function.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
def get_function_name(fragment) -> str:
88
if not (function_name := fragment.get(ATTRIBUTE_FUNCTION_NAME)):
9-
CustomLogging.critical(f"Fragment type functions 'name' attribute does not exist")
9+
CustomLogging.critical(f"Required Fragment type functions 'name' attribute does not exist")
1010
return function_name
1111

1212
def get_function_args(fragment) -> dict:
@@ -24,9 +24,9 @@ def get_function_outputs(fragment) -> dict:
2424
function_outputs = {}
2525
return function_outputs
2626

27-
def get_function_code(fragment) -> dict:
27+
def get_function_code(fragment) -> list:
2828
if not (function_code := fragment.get(ATTRIBUTE_FUNCTION_CODE)):
29-
function_code = {}
29+
function_code = []
3030
return function_code
3131

3232
class Function(Fragment):

compiler/python_compiler/engines/py3_8/FunctionCall.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
def get_function_name(fragment) -> str:
77
if not (function_name := fragment.get(ATTRIBUTE_FUNCTION_CALL_NAME)):
8-
CustomLogging.critical(f"Fragment type function_call '{ATTRIBUTE_FUNCTION_CALL_NAME}' attribute does not exist")
8+
CustomLogging.critical(f"Required Fragment type function_call '{ATTRIBUTE_FUNCTION_CALL_NAME}' attribute does not exist")
99
return function_name
1010

1111
def get_function_args(fragment) -> dict:
@@ -33,7 +33,7 @@ def inputs_compile(self) -> str:
3333
inputs = self.args
3434

3535
if self.kwargs:
36-
inputs.extend([ f"{x}:{self.kwargs[x]}" for x in self.kwargs])
36+
inputs.extend([ f"{x}={self.kwargs[x]}" for x in self.kwargs])
3737

3838
inputs_build = ", ".join(inputs)
3939
return inputs_build

compiler/python_compiler/engines/py3_8/Variable.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
def get_variable_name(fragment) -> str:
2525
if not (variable_name := fragment.get(ATTRIBUTE_VARIABLE_NAME)):
26-
CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_NAME}' attribute does not exist")
26+
CustomLogging.critical(f"Required Fragment type variable '{ATTRIBUTE_VARIABLE_NAME}' attribute does not exist")
2727
return variable_name
2828

2929
def get_variable_type(fragment) -> str:
@@ -40,7 +40,7 @@ def get_variable_assign_operator(fragment) -> str:
4040

4141
def get_variable_expression(fragment) -> str:
4242
if not (variable_expression := fragment.get(ATTRIBUTE_VARIABLE_EXPRESSION)):
43-
CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_EXPRESSION}' attribute does not exist")
43+
CustomLogging.critical(f"Required Fragment type variable '{ATTRIBUTE_VARIABLE_EXPRESSION}' attribute does not exist")
4444
return variable_expression
4545

4646

compiler/python_compiler/engines/py3_8/get_fragment_class.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from .Fragment import Fragment
55
from .Function import Function
6+
from .Class import Class
67
from .Variable import Variable
78
from .Conditional import Conditional
89
from .FunctionCall import FunctionCall
@@ -11,9 +12,9 @@
1112

1213

1314
FRAGMENT_TYPES={
15+
"class": Class,
1416
"function": Function,
1517
"function_call":FunctionCall,
16-
"class":Fragment,
1718
"variable":Variable,
1819
"conditional":Conditional,
1920
"return":Return,

compiler/utils/flags.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,20 @@ def to_flag(text:str):
1616

1717
TAB = ["\t", " "*4,"*"][1]
1818

19+
# GLOBAL VARS
20+
ATTRIBUTE_NAME_DEFAULT = "name"
21+
ATTRIBUTE_CODE_DEFAULT = "code"
22+
23+
# FRAGMENT VARS
1924
ATTRIBUTE_FRAGMENT_TYPE = "type"
2025
ATTRIBUTE_TYPE = "type"
2126
ATTRIBUTE_DEFAULT = "default"
2227

23-
ATTRIBUTE_FUNCTION_NAME = "name"
28+
ATTRIBUTE_FUNCTION_NAME = ATTRIBUTE_NAME_DEFAULT
2429
ATTRIBUTE_FUNCTION_ARGS = "args"
2530
ATTRIBUTE_FUNCTION_KWARGS = "kwargs"
2631
ATTRIBUTE_FUNCTION_OUTPUTS = "outputs"
27-
ATTRIBUTE_FUNCTION_CODE = "code"
32+
ATTRIBUTE_FUNCTION_CODE = ATTRIBUTE_CODE_DEFAULT
2833

2934
ATTRIBUTE_FUNCTION_RETURN_ARGS = "args"
3035

@@ -37,8 +42,13 @@ def to_flag(text:str):
3742

3843
ATTRIBUTE_FOR_ITERATORS = "iterators"
3944
ATTRIBUTE_FOR_SEQUENCE = "sequence"
40-
ATTRIBUTE_FOR_CODE = "code"
45+
ATTRIBUTE_FOR_CODE = ATTRIBUTE_CODE_DEFAULT
4146
ATTRIBUTE_FOR_ELSE_CODE = "else"
4247

4348
ATTRIBUTE_CONDITIONAL_CONDITION = "condition"
44-
ATTRIBUTE_CONDITIONAL_CODE = "code"
49+
ATTRIBUTE_CONDITIONAL_CODE = ATTRIBUTE_CODE_DEFAULT
50+
51+
ATTRIBUTE_CLASS_NAME = ATTRIBUTE_NAME_DEFAULT
52+
ATTRIBUTE_CLASS_ATTRIBUTES = "attributes"
53+
ATTRIBUTE_CLASS_EXTENDS = "extends"
54+
ATTRIBUTE_CLASS_CODE = ATTRIBUTE_CODE_DEFAULT

0 commit comments

Comments
 (0)