From 8d5cae8060a3a8191c91e77fadeddc773d8c4ff3 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sat, 14 Aug 2021 11:36:03 -0500 Subject: [PATCH 01/12] recursive constructor --- .../v2/services/operate.service.json | 9 ++- .../processing/operations/sum.code.json | 13 ++-- compiler/compiler.py | 1 + compiler/json_compiler/Compiler.py | 67 ++++++++++++++----- .../samples/utils/models/human.model.json | 2 +- 5 files changed, 63 insertions(+), 29 deletions(-) diff --git a/blueprints/examples/calculator/v2/services/operate.service.json b/blueprints/examples/calculator/v2/services/operate.service.json index 3eab944..3d821b5 100644 --- a/blueprints/examples/calculator/v2/services/operate.service.json +++ b/blueprints/examples/calculator/v2/services/operate.service.json @@ -2,12 +2,11 @@ "endpoints": { "sum":{ "request":{"a":{"type":"int"}, "b":{"type":"int"}}, - "response":{"a":{"type":"int"}, "b":{"type":"int"}}, + "response":{"result":{"type":"int"}}, "processing":{ - "from": "processing.operations.sum", - "number_a": "a", - "number_b": "b", - "message": "calculating sum" + "__extends":{ + "__from": "processing.operations.sum" + } } } } diff --git a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json index dc4cac6..1b9974d 100644 --- a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json +++ b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json @@ -1,14 +1,17 @@ { "engine": "python3.8", + "__description": "what seams like a simple sum", "__constructor":{ - "description": "what seams like a simple sum", "number_a":{"type":"str", "default":"number_a"}, "number_b":{"type":"str", "default":"number_b"}, "message":{"type":"str", "default":"adding {__number_a} to {__number_b}"} }, "inputs":{ - "__number_a":{"type":"str", "required":true}, - "__number_b":{"type":"str", "required":true} + "__number_a":{"type":"int", "required":true}, + "__number_b":{"type":"int", "required":true} + }, + "outputs":{ + "result":{"type":"int", "required":true} }, "code": [ { @@ -19,12 +22,12 @@ { "type": "variable", "variable_type": "str", - "name": "sum_result", + "name": "result", "equals": ["__number_a+number_b"] }, { "type": "return", - "args": ["sum_result"] + "args": ["result"] } ] } \ No newline at end of file diff --git a/compiler/compiler.py b/compiler/compiler.py index 6854fac..48c2215 100644 --- a/compiler/compiler.py +++ b/compiler/compiler.py @@ -21,3 +21,4 @@ def main(): # python .\compiler.py c "json.v1" ../blueprints/examples/facebook/main.app.json # python .\compiler.py c "json.v1" ./sample_blueprints/samples/import.app.json # python .\compiler.py c "json.v1" ./sample_blueprints/samples/construct.app.json +# python .\compiler.py c "json.v1" ../blueprints/examples/calculator/v2/main.app.json diff --git a/compiler/json_compiler/Compiler.py b/compiler/json_compiler/Compiler.py index c9b2f3c..5e676bc 100644 --- a/compiler/json_compiler/Compiler.py +++ b/compiler/json_compiler/Compiler.py @@ -6,6 +6,7 @@ from utils.CustomLogging import CustomLogging MODELS_FIELD = "models" +SEVICES_FIELD = "services" SPECIAL_FIELD_FLAG = "__" EXTENDS_FIELD = SPECIAL_FIELD_FLAG+"extends" @@ -23,7 +24,7 @@ def extends(json_dict, *, base_folder=None, base_dict={}, object_route=""): if extends_from[0] in base_dict: attr_build = special_flags_processing(base_dict[extends_from[0]], base_dict=base_dict, object_route = new_route) else: - CustomLogging.error(f"Attribute {extends_from[0]} not found \n{base_dict}") + CustomLogging.error(f"Attribute {extends_from[0]} not found extending {object_route}\n{base_dict}") else: attr_file_name = search_json(json_dict[SPECIAL_FIELD_FLAG+"extends"][SPECIAL_FIELD_FLAG+"from"], base_folder=base_folder) if not attr_file_name: @@ -86,9 +87,13 @@ def cosntructor(json_dict, *, args = {}, object_route=""): if default_attribute.startswith(SPECIAL_FIELD_FLAG): continue args_to_check[default_attribute] = set_type(constructor_dict[default_attribute]["default"], constructor_dict[default_attribute]["type"]) - for arg in args_to_check: - new_value = cosntruct_replace(response_json, SPECIAL_FIELD_FLAG+arg, args_to_check[arg]) - response_json = new_value + updates = True + while updates: # Dangerous Loop + for arg in args_to_check: + new_value = cosntruct_replace(response_json, SPECIAL_FIELD_FLAG+arg, args_to_check[arg]) + if new_value == response_json: + updates = False + response_json = new_value return response_json def special_flags_processing(json_dict, *, args = {}, base_folder=None, base_dict={}, object_route=""): if SPECIAL_FIELD_FLAG+"constructor" in json_dict: @@ -112,27 +117,53 @@ def __init__(self, main_file) -> None: self.main_file = main_file self.blueprint = load_json_as_dict(main_file) - def compile_models(self): - if MODELS_FIELD not in self.blueprint and EXTENDS_FIELD not in self.blueprint: - CustomLogging.error("models is not defined") - build = json_global_compile(self.blueprint, base_folder=self.main_folder) - for model in build["models"].copy(): + def compile_models(self, build): + if MODELS_FIELD not in build: + CustomLogging.error(f"{MODELS_FIELD} field is not defined") + models = build[MODELS_FIELD] + for model in models.copy(): model_file_name = self.main_file - if type(build["models"][model]) == str: + if type(models[model]) == str: model_file_name = search_json( - build["models"][model], base_folder=self.main_folder) + models[model], base_folder=self.main_folder) if not model_file_name: - CustomLogging.error(build["models"][model], "path does not exists in") + CustomLogging.error(models[model], "path does not exists in") continue model_json = load_json_as_dict(model_file_name) - elif type(build["models"][model]) == dict: - model_json = build["models"][model] + elif type(models[model]) == dict: + model_json = models[model] else: CustomLogging.error(f"invalid model {model}") model_build = json_global_compile(model_json, base_folder = os.path.dirname(model_file_name), object_route=model) - build["models"][model] = model_build - pp = pprint.PrettyPrinter(indent=2) - pp.pprint(build) + models[model] = model_build + build[MODELS_FIELD] = models + return build + def compile_services(self, build): + if SEVICES_FIELD not in build: + CustomLogging.error(f"{SEVICES_FIELD} field is not defined") + services = build[SEVICES_FIELD] + for service in services.copy(): + service_file_name = self.main_file + if type(services[service]) == str: + service_file_name = search_json( + services[service], base_folder=self.main_folder) + if not service_file_name: + CustomLogging.error(services[service], "path does not exists in") + continue + service_json = load_json_as_dict(service_file_name) + elif type(services[service]) == dict: + service_json = services[service] + else: + CustomLogging.error(f"invalid service {service}") + service_build = json_global_compile(service_json, base_folder = os.path.dirname(service_file_name), object_route=service) + services[service] = service_build + build[SEVICES_FIELD] = services + return build def compile(self): - self.compile_models() + build = json_global_compile(self.blueprint, base_folder=self.main_folder) + build = self.compile_models(build) + build = self.compile_services(build) + #print(build) + pp = pprint.PrettyPrinter(indent=2) + pp.pprint(build) diff --git a/compiler/sample_blueprints/samples/utils/models/human.model.json b/compiler/sample_blueprints/samples/utils/models/human.model.json index 12a4d45..ec96ec9 100644 --- a/compiler/sample_blueprints/samples/utils/models/human.model.json +++ b/compiler/sample_blueprints/samples/utils/models/human.model.json @@ -8,7 +8,7 @@ "attributes":{ "id": {"type":"id"}, "__name":{"type":"str", "max":20, "required":true}, - "__birth":{"type":"date", "max":20, "required":true}, + "__birth":{"type":"date", "required":true}, "__sector":{"type":"str", "max":100, "required":true} }, "create":{ From 86541123eac4c72fe6adf18a3fb0f67741aefb25 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sun, 15 Aug 2021 08:10:42 -0500 Subject: [PATCH 02/12] django compiler load code template --- blueprints/examples/facebook/main.app.json | 2 +- .../chat/feed/models/feed.model.json | 6 ++- .../chat/feed/models/message.model.json | 6 ++- .../chat/feed/models/reaction.model.json | 6 ++- .../chat/models/conversation.model.json | 9 ++-- .../chat/models/message.model.json | 5 +- .../chat/services/conversation.service.json | 1 + .../utils/auth/user/models/user.model.json | 6 +-- .../auth/user/services/user.service.json | 3 ++ compiler/compiler.py | 6 ++- compiler/django_compiler/Compiler.py | 54 +++++++++++++++++++ .../django_compiler/templates/model.code.json | 19 +++++++ compiler/json_compiler/Compiler.py | 53 +++++++++++------- compiler/utils/flags.py | 4 ++ 14 files changed, 145 insertions(+), 35 deletions(-) create mode 100644 compiler/django_compiler/Compiler.py create mode 100644 compiler/django_compiler/templates/model.code.json create mode 100644 compiler/utils/flags.py diff --git a/blueprints/examples/facebook/main.app.json b/blueprints/examples/facebook/main.app.json index d34bfea..8cbe49b 100644 --- a/blueprints/examples/facebook/main.app.json +++ b/blueprints/examples/facebook/main.app.json @@ -6,7 +6,7 @@ "message":"global.communication.chat.feed.models.message" }, "services": { - "user":"global.utils.services.user", + "user":"global.utils.auth.user.services.user", "conversation":"global.communication.chat.services.conversation", "message":"global.communication.chat.services.message" } diff --git a/blueprints/global/communication/chat/feed/models/feed.model.json b/blueprints/global/communication/chat/feed/models/feed.model.json index 523207f..c96c7c1 100644 --- a/blueprints/global/communication/chat/feed/models/feed.model.json +++ b/blueprints/global/communication/chat/feed/models/feed.model.json @@ -1,8 +1,10 @@ { "__constructor":{ "user":{ - "description":"user to be used" - } + "description":"user to be used", + "type":"str", + "default":"global.communication.chat.models.conversation" + } }, "attributes":{ "id": {"type":"id"}, diff --git a/blueprints/global/communication/chat/feed/models/message.model.json b/blueprints/global/communication/chat/feed/models/message.model.json index 338fac1..605e76b 100644 --- a/blueprints/global/communication/chat/feed/models/message.model.json +++ b/blueprints/global/communication/chat/feed/models/message.model.json @@ -1,8 +1,10 @@ { "__constructor":{ "user":{ - "description":"user to be used" - } + "description":"user to be used", + "type":"str", + "default":"global.communication.chat.models.conversation" + } }, "attributes":{ "feed":{"type":"feed", "required":true, "user":"__user"} diff --git a/blueprints/global/communication/chat/feed/models/reaction.model.json b/blueprints/global/communication/chat/feed/models/reaction.model.json index 943a225..f0f7de9 100644 --- a/blueprints/global/communication/chat/feed/models/reaction.model.json +++ b/blueprints/global/communication/chat/feed/models/reaction.model.json @@ -1,8 +1,10 @@ { "__constructor":{ "user":{ - "description":"user to be used" - } + "description":"user to be used", + "type":"str", + "default":"global.communication.chat.models.conversation" + } }, "attributes":{ "id": {"type":"id"}, diff --git a/blueprints/global/communication/chat/models/conversation.model.json b/blueprints/global/communication/chat/models/conversation.model.json index cdfef90..74a7ac2 100644 --- a/blueprints/global/communication/chat/models/conversation.model.json +++ b/blueprints/global/communication/chat/models/conversation.model.json @@ -1,8 +1,9 @@ { "__constructor":{ "user":{ - "description":"user model to be used", - "default":"global.auth.user.models.user" + "description":"conversation model to be used", + "type": "str", + "default":"global.communication.chat.models.conversation" } }, "attributes":{ @@ -23,8 +24,8 @@ }, "get":{ "__extends":{ - "__from":"create", - "__excludes":[ "id"] + "__from":"attributes", + "__excludes":["id"] } } } \ No newline at end of file diff --git a/blueprints/global/communication/chat/models/message.model.json b/blueprints/global/communication/chat/models/message.model.json index 4374be9..e49da45 100644 --- a/blueprints/global/communication/chat/models/message.model.json +++ b/blueprints/global/communication/chat/models/message.model.json @@ -1,8 +1,9 @@ { "__constructor":{ "user":{ + "description":"route to user to be used", "type":"str", - "description":"route to user to be used" + "default":"global.communication.chat.models.conversation" } }, "attributes":{ @@ -25,7 +26,7 @@ }, "get":{ "__extends":{ - "__from":"create", + "__from":"attributes", "__excludes":[ "id"] } } diff --git a/blueprints/global/communication/chat/services/conversation.service.json b/blueprints/global/communication/chat/services/conversation.service.json index c8b63d4..3648ea7 100644 --- a/blueprints/global/communication/chat/services/conversation.service.json +++ b/blueprints/global/communication/chat/services/conversation.service.json @@ -2,6 +2,7 @@ "__constructor":{ "conversation":{ "description":"conversation model to be used", + "type": "str", "default":"global.communication.chat.models.conversation" } }, diff --git a/blueprints/global/utils/auth/user/models/user.model.json b/blueprints/global/utils/auth/user/models/user.model.json index 06d40ed..0d2a65b 100644 --- a/blueprints/global/utils/auth/user/models/user.model.json +++ b/blueprints/global/utils/auth/user/models/user.model.json @@ -22,7 +22,7 @@ "list":{ "response":{ "__extends":{ - "from":"attributes", + "__from":"attributes", "__excludes":["password"] } } @@ -30,13 +30,13 @@ "get":{ "request":{ "__extends":{ - "from":"attributes", + "__from":"attributes", "__includes":["id"] } }, "response":{ "__extends":{ - "from":"attributes", + "__from":"attributes", "__excludes":["id"] } } diff --git a/blueprints/global/utils/auth/user/services/user.service.json b/blueprints/global/utils/auth/user/services/user.service.json index e69de29..544b7b4 100644 --- a/blueprints/global/utils/auth/user/services/user.service.json +++ b/blueprints/global/utils/auth/user/services/user.service.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/compiler/compiler.py b/compiler/compiler.py index 48c2215..874dbce 100644 --- a/compiler/compiler.py +++ b/compiler/compiler.py @@ -1,7 +1,8 @@ from json_compiler.Compiler import Compiler as json_compiler +from django_compiler.Compiler import Compiler as django_compiler import sys COMPILERS = { - "django-postgres.v1": "under development", + "django-postgres.v1": django_compiler, "flask-mongo.v1": "under development", "nodejs-mongo.v1": "under development", "json.v1": json_compiler @@ -22,3 +23,6 @@ def main(): # python .\compiler.py c "json.v1" ./sample_blueprints/samples/import.app.json # python .\compiler.py c "json.v1" ./sample_blueprints/samples/construct.app.json # python .\compiler.py c "json.v1" ../blueprints/examples/calculator/v2/main.app.json + +# python .\compiler.py c "django-postgres.v1" ../blueprints/examples/facebook/main.app.json + diff --git a/compiler/django_compiler/Compiler.py b/compiler/django_compiler/Compiler.py new file mode 100644 index 0000000..24e60ef --- /dev/null +++ b/compiler/django_compiler/Compiler.py @@ -0,0 +1,54 @@ +import os + +from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict +from utils.CustomLogging import CustomLogging +from utils.flags import * + +def compile_model(model_name:str, model_dict:dict, *, base_folder="", base_dict={}, object_route=""): + print(model_name) + if not model_name == "user": + return + args = { + "model_name":model_name, + "atributes":{ + "test1":"n1", + "test2":"n2" + } + } + model_template = load_json_as_dict("./django_compiler/templates/model.code.json") + processed = special_flags_processing(model_template, args=args, base_folder=base_folder, base_dict=base_dict, object_route=object_route) + print(processed) + + +class Compiler: + blueprint: dict = {} + + def __init__(self, main_file) -> None: + self.main_folder = os.path.dirname(main_file) + self.main_file = main_file + + jcompiler = json_compiler(main_file) + self.blueprint = jcompiler.compile() + + def compile_models(self, build): + if MODELS_FIELD not in build: + CustomLogging.error(f"{MODELS_FIELD} field is not defined") + models = build[MODELS_FIELD] + for model in models.copy(): + compile_model(model, models[model]["attributes"], base_folder=self.main_folder, base_dict=models[model], object_route=model) + build[MODELS_FIELD] = models + return build + def compile_services(self, build): + if SEVICES_FIELD not in build: + CustomLogging.error(f"{SEVICES_FIELD} field is not defined") + services = build[SEVICES_FIELD] + for service in services.copy(): + print(service) + build[SEVICES_FIELD] = services + return build + + def compile(self): + build = self.compile_models(self.blueprint) + #build = self.compile_services(build) + #print(build) + return build diff --git a/compiler/django_compiler/templates/model.code.json b/compiler/django_compiler/templates/model.code.json new file mode 100644 index 0000000..ad2225a --- /dev/null +++ b/compiler/django_compiler/templates/model.code.json @@ -0,0 +1,19 @@ +{ + "engine": "python3.8/django3.2", + "__description": "template for django models", + "__constructor":{ + "model_name":{"type":"str", "default":"DefaultModel"}, + "atributes":{"type":"dict"} + }, + "import":{ + "models":{"from":"django.db"} + }, + "code": [ + { + "type": "class", + "name": "__model_name", + "extends": ["models"], + "attributes":"__atributes" + } + ] +} \ No newline at end of file diff --git a/compiler/json_compiler/Compiler.py b/compiler/json_compiler/Compiler.py index 5e676bc..92ee67b 100644 --- a/compiler/json_compiler/Compiler.py +++ b/compiler/json_compiler/Compiler.py @@ -1,15 +1,14 @@ import json import os -import pprint import copy from utils.searcher import search_json from utils.CustomLogging import CustomLogging +from utils.flags import * -MODELS_FIELD = "models" -SEVICES_FIELD = "services" -SPECIAL_FIELD_FLAG = "__" -EXTENDS_FIELD = SPECIAL_FIELD_FLAG+"extends" - +def object_route_join(old, new): + if old == "": + return new + return ".".join(old.split(".")+[new]) def set_type(object, to_type): # TODO: implement type serialization return object @@ -20,7 +19,7 @@ def extends(json_dict, *, base_folder=None, base_dict={}, object_route=""): extends_from = json_dict[SPECIAL_FIELD_FLAG+"extends"][SPECIAL_FIELD_FLAG+"from"].split(".") attr_build = {} if len(extends_from) == 1: - new_route = ".".join(object_route.split(".")+[extends_from[0]]) + new_route = object_route_join(object_route,extends_from[0]) if extends_from[0] in base_dict: attr_build = special_flags_processing(base_dict[extends_from[0]], base_dict=base_dict, object_route = new_route) else: @@ -52,28 +51,41 @@ def extends(json_dict, *, base_folder=None, base_dict={}, object_route=""): if exclude in attr_build: attr_build.pop(exclude) else: - CustomLogging.warning(f"exclude error: attribute {exclude} not in {json_dict[SPECIAL_FIELD_FLAG+'extends'][SPECIAL_FIELD_FLAG+'from']}") + CustomLogging.warning(f"exclude error {object_route}: attribute {exclude} not in {json_dict[SPECIAL_FIELD_FLAG+'extends'][SPECIAL_FIELD_FLAG+'from']}") json_dict.update(attr_build) json_dict.pop(SPECIAL_FIELD_FLAG+"extends") return json_dict -def cosntruct_replace(main_object, arg_replace, value): +def cosntruct_replace(main_object, arg_replace, value , *, object_route=""): if type(main_object) == str: - return main_object.replace(arg_replace, value) + if(type(value) == str): + return main_object.replace(arg_replace, value) + if(arg_replace == main_object): + return value + return main_object response_json = {} for attribute in main_object: - attribute_new_name = attribute.replace(arg_replace, value) + if type(value) == str: + attribute_new_name = attribute.replace(arg_replace, value) + else: + if arg_replace in attribute: + CustomLogging.warning(f"{attribute} can not be constructed since is an attribute name and the value of {arg_replace} is not a string") + attribute_new_name = attribute attribute_new_value = main_object[attribute] + current_object_route = object_route_join(object_route,attribute) if type(attribute_new_value) == dict: - attribute_new_value = cosntruct_replace(attribute_new_value, arg_replace, value) + attribute_new_value = cosntruct_replace(attribute_new_value, arg_replace, value, object_route=current_object_route) elif type(attribute_new_value) == list: - attribute_new_value = [ cosntruct_replace(element, arg_replace, value) for element in attribute_new_value ] + attribute_new_value = [ cosntruct_replace(element, arg_replace, value , object_route=object_route_join(current_object_route, str(i))) for i, element in enumerate(attribute_new_value) ] + elif type(attribute_new_value) == str: + attribute_new_value = cosntruct_replace(attribute_new_value, arg_replace, value, object_route=current_object_route) response_json[attribute_new_name] = attribute_new_value return response_json def cosntructor(json_dict, *, args = {}, object_route=""): constructor_dict = json_dict.pop(SPECIAL_FIELD_FLAG+"constructor") response_json = copy.deepcopy(json_dict) args_to_check = copy.deepcopy(args) - args_to_check.pop(SPECIAL_FIELD_FLAG+"from") + if SPECIAL_FIELD_FLAG+"from" in args_to_check: + args_to_check.pop(SPECIAL_FIELD_FLAG+"from") if SPECIAL_FIELD_FLAG+"excludes" in args_to_check: args_to_check.pop(SPECIAL_FIELD_FLAG+"excludes") if SPECIAL_FIELD_FLAG+"includes" in args_to_check: @@ -90,7 +102,7 @@ def cosntructor(json_dict, *, args = {}, object_route=""): updates = True while updates: # Dangerous Loop for arg in args_to_check: - new_value = cosntruct_replace(response_json, SPECIAL_FIELD_FLAG+arg, args_to_check[arg]) + new_value = cosntruct_replace(response_json, SPECIAL_FIELD_FLAG+arg, args_to_check[arg], object_route=object_route) if new_value == response_json: updates = False response_json = new_value @@ -103,7 +115,13 @@ def special_flags_processing(json_dict, *, args = {}, base_folder=None, base_dic json_dict = extends(json_dict, base_folder=base_folder, base_dict=base_dict, object_route=object_route) for attribute in json_dict: if type(json_dict[attribute]) == dict: - json_dict[attribute] = special_flags_processing(json_dict[attribute], args=args, base_folder=base_folder, base_dict=base_dict, object_route=f"{object_route}.{attribute}") + json_dict[attribute] = special_flags_processing( + json_dict[attribute], + args=args, + base_folder=base_folder, + base_dict=base_dict, + object_route=object_route_join(object_route, attribute) + ) return copy.deepcopy(json_dict) def json_global_compile(json_dict, *, args = {}, base_folder=None, base_dict={}, object_route= ""): @@ -165,5 +183,4 @@ def compile(self): build = self.compile_models(build) build = self.compile_services(build) #print(build) - pp = pprint.PrettyPrinter(indent=2) - pp.pprint(build) + return build diff --git a/compiler/utils/flags.py b/compiler/utils/flags.py new file mode 100644 index 0000000..fa45e3f --- /dev/null +++ b/compiler/utils/flags.py @@ -0,0 +1,4 @@ +MODELS_FIELD = "models" +SEVICES_FIELD = "services" +SPECIAL_FIELD_FLAG = "__" +EXTENDS_FIELD = SPECIAL_FIELD_FLAG+"extends" \ No newline at end of file From 013f8b38c9b42be07bc480caea4520ca80d1df00 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sun, 15 Aug 2021 11:20:59 -0500 Subject: [PATCH 03/12] django model compiling --- blueprints/examples/facebook/main.app.json | 26 ++++-- .../chat/feed/models/feed.model.json | 5 +- .../chat/feed/models/message.model.json | 12 +-- .../chat/feed/models/reaction.model.json | 5 +- .../chat/models/conversation.model.json | 5 +- .../chat/models/message.model.json | 5 +- .../chat/services/conversation.service.json | 3 +- compiler/django_compiler/Compiler.py | 86 ++++++++++++++++--- .../django_compiler/templates/model.code.json | 9 +- compiler/json_compiler/Compiler.py | 21 ++++- compiler/utils/CustomLogging.py | 2 + 11 files changed, 137 insertions(+), 42 deletions(-) diff --git a/blueprints/examples/facebook/main.app.json b/blueprints/examples/facebook/main.app.json index 8cbe49b..736898d 100644 --- a/blueprints/examples/facebook/main.app.json +++ b/blueprints/examples/facebook/main.app.json @@ -2,12 +2,28 @@ "name": "facebook", "models": { "user":"global.utils.auth.user.models.user", - "conversation":"global.communication.chat.models.conversation", - "message":"global.communication.chat.feed.models.message" + "conversation":{"__extends":{ + "__from":"global.communication.chat.models.conversation", + "user":"user" + }}, + "message":{"__extends":{ + "__from":"global.communication.chat.feed.models.message", + "user":"user" + }} }, "services": { - "user":"global.utils.auth.user.services.user", - "conversation":"global.communication.chat.services.conversation", - "message":"global.communication.chat.services.message" + "user":{"__extends":{ + "__from":"global.utils.auth.user.services.user", + "user":"user" + }}, + "conversation":{"__extends":{ + "__from":"global.communication.chat.services.conversation", + "user":"user", + "conversation":"conversation" + }}, + "message":{"__extends":{ + "__from":"global.communication.chat.services.message", + "user":"user" + }} } } \ No newline at end of file diff --git a/blueprints/global/communication/chat/feed/models/feed.model.json b/blueprints/global/communication/chat/feed/models/feed.model.json index c96c7c1..3b14176 100644 --- a/blueprints/global/communication/chat/feed/models/feed.model.json +++ b/blueprints/global/communication/chat/feed/models/feed.model.json @@ -1,9 +1,8 @@ { "__constructor":{ "user":{ - "description":"user to be used", - "type":"str", - "default":"global.communication.chat.models.conversation" + "description":"user model to be used", + "type":"str" } }, "attributes":{ diff --git a/blueprints/global/communication/chat/feed/models/message.model.json b/blueprints/global/communication/chat/feed/models/message.model.json index 605e76b..f2863a4 100644 --- a/blueprints/global/communication/chat/feed/models/message.model.json +++ b/blueprints/global/communication/chat/feed/models/message.model.json @@ -1,15 +1,15 @@ { "__constructor":{ "user":{ - "description":"user to be used", - "type":"str", - "default":"global.communication.chat.models.conversation" + "description":"user model to be used", + "type":"str" } }, + "__extends":{ + "__from":"global.communication.chat.models.message", + "user":"__user" + }, "attributes":{ "feed":{"type":"feed", "required":true, "user":"__user"} - }, - "__extends":{ - "__from":"global.communication.chat.models.message" } } \ No newline at end of file diff --git a/blueprints/global/communication/chat/feed/models/reaction.model.json b/blueprints/global/communication/chat/feed/models/reaction.model.json index f0f7de9..60ca37a 100644 --- a/blueprints/global/communication/chat/feed/models/reaction.model.json +++ b/blueprints/global/communication/chat/feed/models/reaction.model.json @@ -1,9 +1,8 @@ { "__constructor":{ "user":{ - "description":"user to be used", - "type":"str", - "default":"global.communication.chat.models.conversation" + "description":"user model to be used", + "type":"str" } }, "attributes":{ diff --git a/blueprints/global/communication/chat/models/conversation.model.json b/blueprints/global/communication/chat/models/conversation.model.json index 74a7ac2..a76c497 100644 --- a/blueprints/global/communication/chat/models/conversation.model.json +++ b/blueprints/global/communication/chat/models/conversation.model.json @@ -1,9 +1,8 @@ { "__constructor":{ "user":{ - "description":"conversation model to be used", - "type": "str", - "default":"global.communication.chat.models.conversation" + "description":"user model to be used", + "type":"str" } }, "attributes":{ diff --git a/blueprints/global/communication/chat/models/message.model.json b/blueprints/global/communication/chat/models/message.model.json index e49da45..ce83e85 100644 --- a/blueprints/global/communication/chat/models/message.model.json +++ b/blueprints/global/communication/chat/models/message.model.json @@ -1,9 +1,8 @@ { "__constructor":{ "user":{ - "description":"route to user to be used", - "type":"str", - "default":"global.communication.chat.models.conversation" + "description":"user model to be used", + "type":"str" } }, "attributes":{ diff --git a/blueprints/global/communication/chat/services/conversation.service.json b/blueprints/global/communication/chat/services/conversation.service.json index 3648ea7..ef023f6 100644 --- a/blueprints/global/communication/chat/services/conversation.service.json +++ b/blueprints/global/communication/chat/services/conversation.service.json @@ -2,8 +2,7 @@ "__constructor":{ "conversation":{ "description":"conversation model to be used", - "type": "str", - "default":"global.communication.chat.models.conversation" + "type": "str" } }, "endpoints":{ diff --git a/compiler/django_compiler/Compiler.py b/compiler/django_compiler/Compiler.py index 24e60ef..a549fd7 100644 --- a/compiler/django_compiler/Compiler.py +++ b/compiler/django_compiler/Compiler.py @@ -1,23 +1,83 @@ import os +import json -from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict +from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict, object_route_join from utils.CustomLogging import CustomLogging from utils.flags import * -def compile_model(model_name:str, model_dict:dict, *, base_folder="", base_dict={}, object_route=""): - print(model_name) - if not model_name == "user": +DJANGO_FIELD_TYPES = { + "email":{ + "name":"CharField", + "max":"max_length" + }, + "id":{ + "name":"BigAutoField", + "required":{ + "primary_key": True + } + }, + "str":{ + "name":"CharField", + "max":"max_length" + }, + "password":{ + "name":"CharField", + "max":"max_length" + }, + "email":{ + "name":"CharField", + "max":"max_length" + }, + "foreign":{ + "name":"ForeignKey", + "required":{ + "on_delete": "models.CASCADE" + } + }, +} + +def compile_field(field_dict, model_names, *, base_folder="", object_route=""): + #compiled = "" + if field_dict["type"] == "id": + #models.BigAutoField(primary_key=True) + CustomLogging.log(f"skipping id since django already defines it") return + field_type_name = field_dict['type'] + field_args = [] + if field_dict['type'] in model_names: + field_type_name = "foreign" + field_args = [field_dict['type']] + field_type = DJANGO_FIELD_TYPES.get(field_type_name, False) + + if not field_type: + CustomLogging.error(f"{object_route} {field_dict['type']} type is not defined") + + field_kwargs = {} + if "max" in field_dict and "max" in field_type: + field_kwargs[field_type["max"]] = field_dict["max"] + field_call_definition = { + "type":"function_call", + "function":f"models.{field_type['name']}", + "kwargs":field_kwargs, + "args":field_args + } + #field_compiled_args = ", ".join([ f"{x}={field_args[x]}" for x in field_args]) + #compiled = f"models.{field_type['name']}({field_compiled_args})" + return field_call_definition#compiled +def compile_model(model_name:str, model_dict:dict, model_names:list, *, base_folder="", base_dict={}, object_route=""): + atributes = {} + for field_name in model_dict: + compiled_field = compile_field(model_dict[field_name], model_names, base_folder=base_folder, object_route=object_route_join(object_route, field_name)) + if compiled_field: + atributes[field_name] = compiled_field args = { - "model_name":model_name, - "atributes":{ - "test1":"n1", - "test2":"n2" - } + "model_name":model_name.title(), + "atributes": atributes, + "desc":"__model_name model class" # recursive constructor } model_template = load_json_as_dict("./django_compiler/templates/model.code.json") processed = special_flags_processing(model_template, args=args, base_folder=base_folder, base_dict=base_dict, object_route=object_route) - print(processed) + return processed class Compiler: @@ -34,8 +94,10 @@ def compile_models(self, build): if MODELS_FIELD not in build: CustomLogging.error(f"{MODELS_FIELD} field is not defined") models = build[MODELS_FIELD] + self.model_names = list(models.keys()) for model in models.copy(): - compile_model(model, models[model]["attributes"], base_folder=self.main_folder, base_dict=models[model], object_route=model) + compiled_model = compile_model(model, models[model]["attributes"], self.model_names, base_folder=self.main_folder, base_dict=models[model], object_route=model) + models[model] = compiled_model build[MODELS_FIELD] = models return build def compile_services(self, build): @@ -51,4 +113,6 @@ def compile(self): build = self.compile_models(self.blueprint) #build = self.compile_services(build) #print(build) + with open(f"{self.blueprint['name']}.build.json", "w") as f: + json.dump(build, f, indent=4) return build diff --git a/compiler/django_compiler/templates/model.code.json b/compiler/django_compiler/templates/model.code.json index ad2225a..db99da2 100644 --- a/compiler/django_compiler/templates/model.code.json +++ b/compiler/django_compiler/templates/model.code.json @@ -1,10 +1,11 @@ { "engine": "python3.8/django3.2", - "__description": "template for django models", "__constructor":{ - "model_name":{"type":"str", "default":"DefaultModel"}, - "atributes":{"type":"dict"} + "model_name":{"type":"str", "default":"CharField"}, + "atributes":{"type":"dict"}, + "desc":{"type":"str", "default":"template for django models"} }, + "description": "__desc", "import":{ "models":{"from":"django.db"} }, @@ -12,7 +13,7 @@ { "type": "class", "name": "__model_name", - "extends": ["models"], + "extends": ["models.Model"], "attributes":"__atributes" } ] diff --git a/compiler/json_compiler/Compiler.py b/compiler/json_compiler/Compiler.py index 92ee67b..b41810d 100644 --- a/compiler/json_compiler/Compiler.py +++ b/compiler/json_compiler/Compiler.py @@ -98,7 +98,13 @@ def cosntructor(json_dict, *, args = {}, object_route=""): for default_attribute in constructor_dict: if default_attribute.startswith(SPECIAL_FIELD_FLAG): continue - args_to_check[default_attribute] = set_type(constructor_dict[default_attribute]["default"], constructor_dict[default_attribute]["type"]) + if not constructor_dict[default_attribute].get("required", False): + if "default" not in constructor_dict[default_attribute]: + CustomLogging.error(f"{object_route} non required input should have default value") + args_to_check[default_attribute] = set_type(constructor_dict[default_attribute]["default"], constructor_dict[default_attribute]["type"]) + else: + if default_attribute not in args_to_check: + CustomLogging.error(f"{object_route} {default_attribute} is required") updates = True while updates: # Dangerous Loop for arg in args_to_check: @@ -109,7 +115,7 @@ def cosntructor(json_dict, *, args = {}, object_route=""): return response_json def special_flags_processing(json_dict, *, args = {}, base_folder=None, base_dict={}, object_route=""): if SPECIAL_FIELD_FLAG+"constructor" in json_dict: - json_dict = cosntructor(json_dict, args=args) + json_dict = cosntructor(json_dict, args=args, object_route=object_route) base_dict = copy.deepcopy(json_dict) if SPECIAL_FIELD_FLAG+"extends" in json_dict: json_dict = extends(json_dict, base_folder=base_folder, base_dict=base_dict, object_route=object_route) @@ -124,6 +130,17 @@ def special_flags_processing(json_dict, *, args = {}, base_folder=None, base_dic ) return copy.deepcopy(json_dict) +def get_object(route, base_folder): + attr_file_name=search_json(route, base_folder=base_folder) + if not attr_file_name: + CustomLogging.error(f"{route} path does not exists") + attr_json = load_json_as_dict(attr_file_name) + attr_build = json_global_compile( + attr_json, + base_folder = os.path.dirname(attr_file_name), + object_route=route + ) + return attr_build def json_global_compile(json_dict, *, args = {}, base_folder=None, base_dict={}, object_route= ""): data = special_flags_processing(json_dict, args=args, base_folder=base_folder, base_dict=json_dict, object_route=object_route) return data diff --git a/compiler/utils/CustomLogging.py b/compiler/utils/CustomLogging.py index abd5b66..ba724de 100644 --- a/compiler/utils/CustomLogging.py +++ b/compiler/utils/CustomLogging.py @@ -1,4 +1,6 @@ class CustomLogging(object): + def log(msg:str): + print("LOG:",msg) def error(msg:str): raise NameError(msg) def warning(msg:str): From bcf23ea3a20ede800536be62bec3149372e1c453 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Wed, 18 Aug 2021 08:21:02 -0500 Subject: [PATCH 04/12] path handling --- compiler/compiler.py | 33 ++++++++++++++++++---------- compiler/django_compiler/Compiler.py | 13 ++++++----- compiler/json_compiler/Compiler.py | 7 +++--- compiler/python_compiler/Compiler.py | 15 +++++++++++++ compiler/utils/searcher.py | 9 +++++--- 5 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 compiler/python_compiler/Compiler.py diff --git a/compiler/compiler.py b/compiler/compiler.py index 874dbce..3264c6a 100644 --- a/compiler/compiler.py +++ b/compiler/compiler.py @@ -1,28 +1,39 @@ +import json +import sys from json_compiler.Compiler import Compiler as json_compiler from django_compiler.Compiler import Compiler as django_compiler -import sys -COMPILERS = { - "django-postgres.v1": django_compiler, - "flask-mongo.v1": "under development", - "nodejs-mongo.v1": "under development", +from python_compiler.Compiler import Compiler as python_compiler + +COMPILERS = { # "framework.language.version: compiler" + "django.json.v1": django_compiler, + "python.json.v1": django_compiler, + "flask.json.v1": "under development", + "nodejs.json.v1": "under development", "json.v1": json_compiler } def compile(compiler_name, project_name): compiler = COMPILERS[compiler_name](project_name) - compiler.compile() + compiled_project = compiler.compile() + with open(f"./{sys.argv[4]}/{compiled_project.get('name', 'project')}.build.json", "w") as f: + json.dump(compiled_project, f, indent=4) OPTIONS = { "compile": compile, "c": compile } def main(): + # 1 action + # 2 compiler + # 3 project + # 4 destination folder OPTIONS[sys.argv[1]](sys.argv[2], sys.argv[3]) return main() -# python .\compiler.py c "json.v1" ../blueprints/examples/facebook/main.app.json -# python .\compiler.py c "json.v1" ./sample_blueprints/samples/import.app.json -# python .\compiler.py c "json.v1" ./sample_blueprints/samples/construct.app.json -# python .\compiler.py c "json.v1" ../blueprints/examples/calculator/v2/main.app.json +# python .\compiler.py c "json.v1" ../blueprints/examples/facebook/main.app.json build +# python .\compiler.py c "json.v1" ./sample_blueprints/samples/import.app.json build +# python .\compiler.py c "json.v1" ./sample_blueprints/samples/construct.app.json build +# python .\compiler.py c "json.v1" ../blueprints/examples/calculator/v2/main.app.json build -# python .\compiler.py c "django-postgres.v1" ../blueprints/examples/facebook/main.app.json +# python .\compiler.py c "django.json.v1" ../blueprints/examples/facebook/main.app.json build +# python .\compiler.py c "python.json.v1" ../blueprints/examples/facebook/main.app.json build diff --git a/compiler/django_compiler/Compiler.py b/compiler/django_compiler/Compiler.py index a549fd7..1882d48 100644 --- a/compiler/django_compiler/Compiler.py +++ b/compiler/django_compiler/Compiler.py @@ -1,5 +1,6 @@ import os import json +from pathlib import Path from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict, object_route_join from utils.CustomLogging import CustomLogging @@ -75,7 +76,9 @@ def compile_model(model_name:str, model_dict:dict, model_names:list, *, base_fol "atributes": atributes, "desc":"__model_name model class" # recursive constructor } - model_template = load_json_as_dict("./django_compiler/templates/model.code.json") + dir = Path(os.path.dirname(__file__)) + model_path = dir / "templates" / "model.code.json" + model_template = load_json_as_dict(model_path) processed = special_flags_processing(model_template, args=args, base_folder=base_folder, base_dict=base_dict, object_route=object_route) return processed @@ -84,10 +87,10 @@ class Compiler: blueprint: dict = {} def __init__(self, main_file) -> None: - self.main_folder = os.path.dirname(main_file) - self.main_file = main_file + self.main_folder = Path(os.path.dirname(main_file)) + self.main_file = Path(main_file) - jcompiler = json_compiler(main_file) + jcompiler = json_compiler(self.main_file) self.blueprint = jcompiler.compile() def compile_models(self, build): @@ -113,6 +116,4 @@ def compile(self): build = self.compile_models(self.blueprint) #build = self.compile_services(build) #print(build) - with open(f"{self.blueprint['name']}.build.json", "w") as f: - json.dump(build, f, indent=4) return build diff --git a/compiler/json_compiler/Compiler.py b/compiler/json_compiler/Compiler.py index b41810d..53bf43e 100644 --- a/compiler/json_compiler/Compiler.py +++ b/compiler/json_compiler/Compiler.py @@ -1,6 +1,7 @@ import json import os import copy +from pathlib import Path from utils.searcher import search_json from utils.CustomLogging import CustomLogging from utils.flags import * @@ -148,9 +149,9 @@ class Compiler: blueprint: dict = {} def __init__(self, main_file) -> None: - self.main_folder = os.path.dirname(main_file) - self.main_file = main_file - self.blueprint = load_json_as_dict(main_file) + self.main_folder = Path(os.path.dirname(main_file)) + self.main_file = Path(main_file) + self.blueprint = load_json_as_dict(self.main_file) def compile_models(self, build): if MODELS_FIELD not in build: diff --git a/compiler/python_compiler/Compiler.py b/compiler/python_compiler/Compiler.py new file mode 100644 index 0000000..c43edd3 --- /dev/null +++ b/compiler/python_compiler/Compiler.py @@ -0,0 +1,15 @@ +import os +import json + +from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict, object_route_join +from utils.CustomLogging import CustomLogging + +class Compiler: + blueprint: dict = {} + + def __init__(self, main_file) -> None: + self.main_folder = os.path.dirname(main_file) + self.main_file = main_file + self.blueprint = load_json_as_dict(main_file) + def compile(self): + return diff --git a/compiler/utils/searcher.py b/compiler/utils/searcher.py index 7756344..7e9e358 100644 --- a/compiler/utils/searcher.py +++ b/compiler/utils/searcher.py @@ -1,13 +1,16 @@ import os -GLOBAL_ROUTE = "../blueprints" +from pathlib import Path +dir = Path(os.path.dirname(__file__)) +GLOBAL_ROUTE = dir / ".." / ".." / "blueprints" + def list_dir(path): return [ x.split(".") for x in os.listdir(path)] -def get_json_file(splitted_route, dir_path): +def get_json_file(splitted_route, dir_path): # dir_path:pathlib.Path files_names = list_dir(dir_path) for file_name in files_names: if splitted_route[0] == file_name[0]: - new_path = dir_path+"/"+".".join(file_name) + new_path = dir_path / ".".join(file_name) if os.path.isfile(new_path): return new_path else: From 628b16d3da0d7bd19dfcb52a843862729eddb086 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Mon, 23 Aug 2021 21:03:22 -0500 Subject: [PATCH 05/12] generalize flag constants --- README.md | 3 ++ .../processing/operations/sum.code.json | 13 ++++--- compiler/json_compiler/Compiler.py | 34 +++++++++---------- compiler/python_compiler/Compiler.py | 13 ++++--- compiler/utils/flags.py | 10 +++++- 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index d10d21f..ccaba12 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # App architect +```sh +python .\compiler\compiler.py c "django.json.v1" ./blueprints/examples/facebook/main.app.json ./compiler/build +``` Design your application in a json like structure, this way the resulting project is going to be easily understood both by human and by machine. This json like structure will let you: diff --git a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json index 1b9974d..1d95d1d 100644 --- a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json +++ b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json @@ -4,8 +4,12 @@ "__constructor":{ "number_a":{"type":"str", "default":"number_a"}, "number_b":{"type":"str", "default":"number_b"}, - "message":{"type":"str", "default":"adding {__number_a} to {__number_b}"} + "message":{"type":"str", "default":"adding {__number_a} to {__number_b}"}, + "function_name":{"type":"str", "default":"sum"} }, + "type": "function", + "name": "__function_name", + "args": ["f\"__message\""], "inputs":{ "__number_a":{"type":"int", "required":true}, "__number_b":{"type":"int", "required":true} @@ -14,16 +18,11 @@ "result":{"type":"int", "required":true} }, "code": [ - { - "type": "function", - "name": "print", - "args": ["f\"__message\""] - }, { "type": "variable", "variable_type": "str", "name": "result", - "equals": ["__number_a+number_b"] + "equals": "__number_a+number_b" }, { "type": "return", diff --git a/compiler/json_compiler/Compiler.py b/compiler/json_compiler/Compiler.py index 53bf43e..0ba3be7 100644 --- a/compiler/json_compiler/Compiler.py +++ b/compiler/json_compiler/Compiler.py @@ -17,7 +17,7 @@ def load_json_as_dict(file_name): with open(file_name, "r") as f: return json.load(f) def extends(json_dict, *, base_folder=None, base_dict={}, object_route=""): - extends_from = json_dict[SPECIAL_FIELD_FLAG+"extends"][SPECIAL_FIELD_FLAG+"from"].split(".") + extends_from = json_dict[FLAG_EXTENDS][FLAG_FROM].split(".") attr_build = {} if len(extends_from) == 1: new_route = object_route_join(object_route,extends_from[0]) @@ -26,35 +26,35 @@ def extends(json_dict, *, base_folder=None, base_dict={}, object_route=""): else: CustomLogging.error(f"Attribute {extends_from[0]} not found extending {object_route}\n{base_dict}") else: - attr_file_name = search_json(json_dict[SPECIAL_FIELD_FLAG+"extends"][SPECIAL_FIELD_FLAG+"from"], base_folder=base_folder) + attr_file_name = search_json(json_dict[FLAG_EXTENDS][FLAG_FROM], base_folder=base_folder) if not attr_file_name: - CustomLogging.error(f"{json_dict[SPECIAL_FIELD_FLAG+'extends'][SPECIAL_FIELD_FLAG+'from']} path does not exists in") + CustomLogging.error(f"{json_dict[FLAG_EXTENDS][FLAG_FROM]} path does not exists in") attr_json = load_json_as_dict(attr_file_name) attr_build = json_global_compile( attr_json, - args = json_dict[SPECIAL_FIELD_FLAG+"extends"], + args = json_dict[FLAG_EXTENDS], base_folder = os.path.dirname(attr_file_name), - object_route=json_dict[SPECIAL_FIELD_FLAG+"extends"][SPECIAL_FIELD_FLAG+"from"] + object_route=json_dict[FLAG_EXTENDS][FLAG_FROM] ) - is_excluding = SPECIAL_FIELD_FLAG+"excludes" in json_dict[SPECIAL_FIELD_FLAG+"extends"] - is_including = SPECIAL_FIELD_FLAG+"includes" in json_dict[SPECIAL_FIELD_FLAG+"extends"] + is_excluding = FLAG_EXCLUDES in json_dict[FLAG_EXTENDS] + is_including = FLAG_INCLUDES in json_dict[FLAG_EXTENDS] if is_including and is_excluding: CustomLogging.error("can not use excludes and includes in a same block") if is_including: new_attr_build = {} - for include in json_dict[SPECIAL_FIELD_FLAG+"extends"][SPECIAL_FIELD_FLAG+"includes"]: + for include in json_dict[FLAG_EXTENDS][FLAG_INCLUDES]: if include not in attr_build: CustomLogging.error(f"{object_route} include error: attribute {include} not in {json_dict[SPECIAL_FIELD_FLAG+'extends'][SPECIAL_FIELD_FLAG+'from']}") new_attr_build[include] = attr_build[include] attr_build = new_attr_build if is_excluding: - for exclude in json_dict[SPECIAL_FIELD_FLAG+"extends"][SPECIAL_FIELD_FLAG+"excludes"]: + for exclude in json_dict[FLAG_EXTENDS][FLAG_EXCLUDES]: if exclude in attr_build: attr_build.pop(exclude) else: CustomLogging.warning(f"exclude error {object_route}: attribute {exclude} not in {json_dict[SPECIAL_FIELD_FLAG+'extends'][SPECIAL_FIELD_FLAG+'from']}") json_dict.update(attr_build) - json_dict.pop(SPECIAL_FIELD_FLAG+"extends") + json_dict.pop(FLAG_EXTENDS) return json_dict def cosntruct_replace(main_object, arg_replace, value , *, object_route=""): if type(main_object) == str: @@ -85,12 +85,12 @@ def cosntructor(json_dict, *, args = {}, object_route=""): constructor_dict = json_dict.pop(SPECIAL_FIELD_FLAG+"constructor") response_json = copy.deepcopy(json_dict) args_to_check = copy.deepcopy(args) - if SPECIAL_FIELD_FLAG+"from" in args_to_check: - args_to_check.pop(SPECIAL_FIELD_FLAG+"from") - if SPECIAL_FIELD_FLAG+"excludes" in args_to_check: - args_to_check.pop(SPECIAL_FIELD_FLAG+"excludes") - if SPECIAL_FIELD_FLAG+"includes" in args_to_check: - args_to_check.pop(SPECIAL_FIELD_FLAG+"includes") + if FLAG_FROM in args_to_check: + args_to_check.pop(FLAG_FROM) + if FLAG_EXCLUDES in args_to_check: + args_to_check.pop(FLAG_EXCLUDES) + if FLAG_INCLUDES in args_to_check: + args_to_check.pop(FLAG_INCLUDES) for arg_to_check in args_to_check: if arg_to_check not in constructor_dict: CustomLogging.warning(f"error in constructor: invalid parameter {arg_to_check}") @@ -118,7 +118,7 @@ def special_flags_processing(json_dict, *, args = {}, base_folder=None, base_dic if SPECIAL_FIELD_FLAG+"constructor" in json_dict: json_dict = cosntructor(json_dict, args=args, object_route=object_route) base_dict = copy.deepcopy(json_dict) - if SPECIAL_FIELD_FLAG+"extends" in json_dict: + if FLAG_EXTENDS in json_dict: json_dict = extends(json_dict, base_folder=base_folder, base_dict=base_dict, object_route=object_route) for attribute in json_dict: if type(json_dict[attribute]) == dict: diff --git a/compiler/python_compiler/Compiler.py b/compiler/python_compiler/Compiler.py index c43edd3..5e05af8 100644 --- a/compiler/python_compiler/Compiler.py +++ b/compiler/python_compiler/Compiler.py @@ -7,9 +7,14 @@ class Compiler: blueprint: dict = {} - def __init__(self, main_file) -> None: - self.main_folder = os.path.dirname(main_file) - self.main_file = main_file - self.blueprint = load_json_as_dict(main_file) + def __init__(self, *, main_file:str = "", blueprint:dict = {}) -> None: + if blueprint: + self.blueprint = blueprint + if main_file: + if not blueprint: + self.blueprint = load_json_as_dict(main_file) + self.main_folder = os.path.dirname(main_file) + self.main_file = main_file + def compile(self): return diff --git a/compiler/utils/flags.py b/compiler/utils/flags.py index fa45e3f..c6c7035 100644 --- a/compiler/utils/flags.py +++ b/compiler/utils/flags.py @@ -1,4 +1,12 @@ MODELS_FIELD = "models" SEVICES_FIELD = "services" SPECIAL_FIELD_FLAG = "__" -EXTENDS_FIELD = SPECIAL_FIELD_FLAG+"extends" \ No newline at end of file +def is_flag(text:str): + return text.startswith(SPECIAL_FIELD_FLAG) +def to_flag(text:str): + return SPECIAL_FIELD_FLAG+text + +FLAG_EXTENDS = to_flag("extends") +FLAG_EXCLUDES = to_flag("excludes") +FLAG_INCLUDES = to_flag("includes") +FLAG_FROM = to_flag("from") From d0a9eef0c45d57d4e96b81d3706861318483b9d0 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Wed, 25 Aug 2021 07:22:27 -0500 Subject: [PATCH 06/12] python engines structure --- compiler/compiler.py | 6 ++-- compiler/django_compiler/Compiler.py | 4 +-- compiler/json_compiler/Compiler.py | 4 +-- compiler/python_compiler/Compiler.py | 28 ++++++++++++++----- .../python_compiler/engines/py3_8/Compiler.py | 18 ++++++++++++ 5 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 compiler/python_compiler/engines/py3_8/Compiler.py diff --git a/compiler/compiler.py b/compiler/compiler.py index 3264c6a..a9b7f32 100644 --- a/compiler/compiler.py +++ b/compiler/compiler.py @@ -6,13 +6,13 @@ COMPILERS = { # "framework.language.version: compiler" "django.json.v1": django_compiler, - "python.json.v1": django_compiler, + "python.json.v1": python_compiler, "flask.json.v1": "under development", "nodejs.json.v1": "under development", "json.v1": json_compiler } def compile(compiler_name, project_name): - compiler = COMPILERS[compiler_name](project_name) + compiler = COMPILERS[compiler_name](main_file=project_name) compiled_project = compiler.compile() with open(f"./{sys.argv[4]}/{compiled_project.get('name', 'project')}.build.json", "w") as f: json.dump(compiled_project, f, indent=4) @@ -35,5 +35,5 @@ def main(): # python .\compiler.py c "json.v1" ../blueprints/examples/calculator/v2/main.app.json build # python .\compiler.py c "django.json.v1" ../blueprints/examples/facebook/main.app.json build -# python .\compiler.py c "python.json.v1" ../blueprints/examples/facebook/main.app.json build +# python .\compiler.py c "python.json.v1" ../blueprints/examples/calculator/v2/services/processing/operations/sum.code.json build diff --git a/compiler/django_compiler/Compiler.py b/compiler/django_compiler/Compiler.py index 1882d48..e193a8e 100644 --- a/compiler/django_compiler/Compiler.py +++ b/compiler/django_compiler/Compiler.py @@ -86,7 +86,7 @@ def compile_model(model_name:str, model_dict:dict, model_names:list, *, base_fol class Compiler: blueprint: dict = {} - def __init__(self, main_file) -> None: + def __init__(self, *, main_file) -> None: self.main_folder = Path(os.path.dirname(main_file)) self.main_file = Path(main_file) @@ -112,7 +112,7 @@ def compile_services(self, build): build[SEVICES_FIELD] = services return build - def compile(self): + def compile(self) -> dict: build = self.compile_models(self.blueprint) #build = self.compile_services(build) #print(build) diff --git a/compiler/json_compiler/Compiler.py b/compiler/json_compiler/Compiler.py index 0ba3be7..ed670d5 100644 --- a/compiler/json_compiler/Compiler.py +++ b/compiler/json_compiler/Compiler.py @@ -148,7 +148,7 @@ def json_global_compile(json_dict, *, args = {}, base_folder=None, base_dict={}, class Compiler: blueprint: dict = {} - def __init__(self, main_file) -> None: + def __init__(self, *, main_file) -> None: self.main_folder = Path(os.path.dirname(main_file)) self.main_file = Path(main_file) self.blueprint = load_json_as_dict(self.main_file) @@ -196,7 +196,7 @@ def compile_services(self, build): build[SEVICES_FIELD] = services return build - def compile(self): + def compile(self) -> dict: build = json_global_compile(self.blueprint, base_folder=self.main_folder) build = self.compile_models(build) build = self.compile_services(build) diff --git a/compiler/python_compiler/Compiler.py b/compiler/python_compiler/Compiler.py index 5e05af8..091e5d5 100644 --- a/compiler/python_compiler/Compiler.py +++ b/compiler/python_compiler/Compiler.py @@ -1,20 +1,34 @@ import os import json -from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict, object_route_join +from json_compiler.Compiler import Compiler as json_compiler, special_flags_processing, load_json_as_dict +from .engines.py3_8.Compiler import compile as py3_9_compiler from utils.CustomLogging import CustomLogging +FLAG_ENGINE = "engine" +ENGINES = { + "python3.8":py3_9_compiler +} class Compiler: blueprint: dict = {} def __init__(self, *, main_file:str = "", blueprint:dict = {}) -> None: - if blueprint: - self.blueprint = blueprint if main_file: - if not blueprint: - self.blueprint = load_json_as_dict(main_file) self.main_folder = os.path.dirname(main_file) self.main_file = main_file + if not blueprint: + raw_blueprint = load_json_as_dict(main_file) + self.blueprint = special_flags_processing(raw_blueprint, base_folder=self.main_folder) + if blueprint: + self.blueprint = special_flags_processing(blueprint, base_folder=self.main_folder) - def compile(self): - return + def compile(self) -> dict: + build = {} + if engine_type := self.blueprint.get(FLAG_ENGINE): + if engine_compiler := ENGINES.get(engine_type): + build = engine_compiler(self.blueprint) + else: + CustomLogging.error(f"Compiler {engine_type} does not exists") + else: + CustomLogging.error(f"Flag {FLAG_ENGINE} not defined") + return build diff --git a/compiler/python_compiler/engines/py3_8/Compiler.py b/compiler/python_compiler/engines/py3_8/Compiler.py new file mode 100644 index 0000000..d538890 --- /dev/null +++ b/compiler/python_compiler/engines/py3_8/Compiler.py @@ -0,0 +1,18 @@ +from utils.CustomLogging import CustomLogging +FLAG_FRAGMENT_TYPE = "type" +FRAGMENT_TYPES={ + "function":print, + "class":print, + "variable":print, + "conditional":print +} +def compile(blueprint:dict): + build = {} + if fragment_type := blueprint.get(FLAG_FRAGMENT_TYPE): + if fragment_compiler := FRAGMENT_TYPES[fragment_type]: + build = fragment_compiler(blueprint) + else: + CustomLogging.error(f"Fragment type {fragment_type} does not exists") + else: + CustomLogging.error(f"Flag {FLAG_FRAGMENT_TYPE} not defined in blueprint") + return build From 4c409b9a2197ae4f57ce49df795f579e824ad832 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sat, 28 Aug 2021 12:40:53 -0500 Subject: [PATCH 07/12] basic funtion compiler --- .../processing/operations/sum.code.json | 3 +- compiler/compiler.py | 5 +- compiler/django_compiler/Compiler.py | 2 +- .../django_compiler/templates/model.code.json | 15 ++-- .../python_compiler/engines/py3_8/Compiler.py | 25 ++----- .../python_compiler/engines/py3_8/Fragment.py | 7 ++ .../python_compiler/engines/py3_8/Function.py | 72 +++++++++++++++++++ .../engines/py3_8/FunctionArgs.py | 23 ++++++ .../engines/py3_8/get_fragment_class.py | 20 ++++++ .../python_compiler/engines/utils/types.py | 13 ++++ compiler/utils/flags.py | 12 ++++ 11 files changed, 165 insertions(+), 32 deletions(-) create mode 100644 compiler/python_compiler/engines/py3_8/Fragment.py create mode 100644 compiler/python_compiler/engines/py3_8/Function.py create mode 100644 compiler/python_compiler/engines/py3_8/FunctionArgs.py create mode 100644 compiler/python_compiler/engines/py3_8/get_fragment_class.py create mode 100644 compiler/python_compiler/engines/utils/types.py diff --git a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json index 1d95d1d..46e4fd3 100644 --- a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json +++ b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json @@ -9,8 +9,7 @@ }, "type": "function", "name": "__function_name", - "args": ["f\"__message\""], - "inputs":{ + "args":{ "__number_a":{"type":"int", "required":true}, "__number_b":{"type":"int", "required":true} }, diff --git a/compiler/compiler.py b/compiler/compiler.py index a9b7f32..a203b1f 100644 --- a/compiler/compiler.py +++ b/compiler/compiler.py @@ -14,7 +14,8 @@ def compile(compiler_name, project_name): compiler = COMPILERS[compiler_name](main_file=project_name) compiled_project = compiler.compile() - with open(f"./{sys.argv[4]}/{compiled_project.get('name', 'project')}.build.json", "w") as f: + print(compiled_project) + with open(f"./{sys.argv[4]}.build.json", "w") as f: json.dump(compiled_project, f, indent=4) OPTIONS = { "compile": compile, @@ -35,5 +36,5 @@ def main(): # python .\compiler.py c "json.v1" ../blueprints/examples/calculator/v2/main.app.json build # python .\compiler.py c "django.json.v1" ../blueprints/examples/facebook/main.app.json build -# python .\compiler.py c "python.json.v1" ../blueprints/examples/calculator/v2/services/processing/operations/sum.code.json build +# python .\compiler.py c "python.json.v1" ../blueprints/examples/calculator/v2/services/processing/operations/sum.code.json build/build diff --git a/compiler/django_compiler/Compiler.py b/compiler/django_compiler/Compiler.py index e193a8e..76ba73e 100644 --- a/compiler/django_compiler/Compiler.py +++ b/compiler/django_compiler/Compiler.py @@ -73,7 +73,7 @@ def compile_model(model_name:str, model_dict:dict, model_names:list, *, base_fol atributes[field_name] = compiled_field args = { "model_name":model_name.title(), - "atributes": atributes, + "args": atributes, "desc":"__model_name model class" # recursive constructor } dir = Path(os.path.dirname(__file__)) diff --git a/compiler/django_compiler/templates/model.code.json b/compiler/django_compiler/templates/model.code.json index db99da2..7e924fd 100644 --- a/compiler/django_compiler/templates/model.code.json +++ b/compiler/django_compiler/templates/model.code.json @@ -2,19 +2,16 @@ "engine": "python3.8/django3.2", "__constructor":{ "model_name":{"type":"str", "default":"CharField"}, - "atributes":{"type":"dict"}, + "args":{"type":"dict"}, "desc":{"type":"str", "default":"template for django models"} }, "description": "__desc", "import":{ "models":{"from":"django.db"} }, - "code": [ - { - "type": "class", - "name": "__model_name", - "extends": ["models.Model"], - "attributes":"__atributes" - } - ] + "type": "class", + "name": "__model_name", + "extends": ["models.Model"], + "args":"__args", + "code": [] } \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/Compiler.py b/compiler/python_compiler/engines/py3_8/Compiler.py index d538890..54e1d59 100644 --- a/compiler/python_compiler/engines/py3_8/Compiler.py +++ b/compiler/python_compiler/engines/py3_8/Compiler.py @@ -1,18 +1,7 @@ -from utils.CustomLogging import CustomLogging -FLAG_FRAGMENT_TYPE = "type" -FRAGMENT_TYPES={ - "function":print, - "class":print, - "variable":print, - "conditional":print -} -def compile(blueprint:dict): - build = {} - if fragment_type := blueprint.get(FLAG_FRAGMENT_TYPE): - if fragment_compiler := FRAGMENT_TYPES[fragment_type]: - build = fragment_compiler(blueprint) - else: - CustomLogging.error(f"Fragment type {fragment_type} does not exists") - else: - CustomLogging.error(f"Flag {FLAG_FRAGMENT_TYPE} not defined in blueprint") - return build +from utils.flags import * +from .get_fragment_class import get_fragment_class + + +def compile(blueprint:dict)->str: + build = get_fragment_class(blueprint) + return build.compile() diff --git a/compiler/python_compiler/engines/py3_8/Fragment.py b/compiler/python_compiler/engines/py3_8/Fragment.py new file mode 100644 index 0000000..3333e4d --- /dev/null +++ b/compiler/python_compiler/engines/py3_8/Fragment.py @@ -0,0 +1,7 @@ +class Fragment: + blueprint:dict + def __init__(self, blueprint) -> None: + self.blueprint = blueprint + def compile(self)->str: + fragment_build = self.blueprint.get("type","") + return fragment_build \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/Function.py b/compiler/python_compiler/engines/py3_8/Function.py new file mode 100644 index 0000000..4b04876 --- /dev/null +++ b/compiler/python_compiler/engines/py3_8/Function.py @@ -0,0 +1,72 @@ +from .Fragment import Fragment +from .FunctionArgs import FunctionArgs +from utils.flags import * +from utils.CustomLogging import CustomLogging +from python_compiler.engines.utils.types import get_python_type_str, ANY + +def get_function_name(fragment) -> str: + if not (function_name := fragment.get(ATTRIBUTE_FUNCTION_NAME)): + CustomLogging.critical(f"Fragment type functions 'name' attribute does not exists") + return function_name + +def get_function_args(fragment) -> dict: + if not (function_args := fragment.get(ATTRIBUTE_FUNCTION_ARGS)): + function_args = {} + return function_args + +def get_function_kwargs(fragment) -> dict: + if not (function_kwargs := fragment.get(ATTRIBUTE_FUNCTION_KWARGS)): + function_kwargs = {} + return function_kwargs + +def get_function_outputs(fragment) -> dict: + if not (function_outputs := fragment.get(ATTRIBUTE_FUNCTION_OUTPUTS)): + function_outputs = {} + return function_outputs + +def get_function_code(fragment) -> dict: + if not (function_code := fragment.get(ATTRIBUTE_FUNCTION_CODE)): + function_code = {} + return function_code + +class Function(Fragment): + name:str + args:dict + kwargs:dict + outputs:dict + def __init__(self, blueprint) -> None: + super().__init__(blueprint) + self.name = get_function_name(blueprint) + self.args = get_function_args(blueprint) + self.kwargs = get_function_kwargs(blueprint) + self.outputs = get_function_outputs(blueprint) + self.code = get_function_code(blueprint) + def inputs_compile(self) -> str: + inputs_build = "" + if self.args: + function_args = FunctionArgs(self.args) + inputs_build += function_args.compile() + + if self.kwargs: + function_kwargs = FunctionArgs(self.kwargs) + inputs_build += f" *, {function_kwargs.compile()}" + return inputs_build + def outputs_compile(self) -> str: + outputs_build = "" + if len(self.outputs) == 1: + if not (arg_type_name := self.outputs[list(self.outputs)[0]].get(ATTRIBUTE_TYPE)): # TODO: Temporal Outoput test + arg_type_name = ANY + outputs_build += f" -> {get_python_type_str(arg_type_name)} " + return outputs_build + def code_lines_compile(self) -> list: + code_build_lines = [] + for line in self.code: + code_build_lines.append("\t"+line["type"]) + return code_build_lines + def compile(self)->str: + fragment_lines = [] + fragment_lines.append(f"def {self.name}({self.inputs_compile()}){self.outputs_compile()}:") + fragment_lines.extend(self.code_lines_compile()) + fragment_build = "\n".join(fragment_lines) + + return fragment_build \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/FunctionArgs.py b/compiler/python_compiler/engines/py3_8/FunctionArgs.py new file mode 100644 index 0000000..8db7fe1 --- /dev/null +++ b/compiler/python_compiler/engines/py3_8/FunctionArgs.py @@ -0,0 +1,23 @@ +from .Fragment import Fragment +from utils.flags import * +from utils.CustomLogging import CustomLogging +from python_compiler.engines.utils.types import get_python_type_str, ANY + + +class FunctionArgs(Fragment): + def __init__(self, blueprint) -> None: + super().__init__(blueprint) + def compile(self)->str: + fragment_build = "" + cleaned_args = [] + for arg in self.blueprint: + if not (arg_type_name := self.blueprint[arg].get(ATTRIBUTE_TYPE)): + arg_type_name = ANY + cleaned_arg = "" + if arg_type := get_python_type_str(arg_type_name): + cleaned_arg = f"{arg}:{arg_type}" + else: + cleaned_arg = arg + cleaned_args.append(cleaned_arg) + fragment_build = ", ".join(cleaned_args) + return fragment_build \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/get_fragment_class.py b/compiler/python_compiler/engines/py3_8/get_fragment_class.py new file mode 100644 index 0000000..66e492f --- /dev/null +++ b/compiler/python_compiler/engines/py3_8/get_fragment_class.py @@ -0,0 +1,20 @@ +from .Fragment import Fragment +from .Function import Function +from utils.flags import * +from utils.CustomLogging import CustomLogging +FRAGMENT_TYPES={ + "function": Function, + "class":Fragment, + "variable":Fragment, + "conditional":Fragment, + "return":Fragment +} + +def get_fragment_class(blueprint): + if fragment_type := blueprint.get(ATTRIBUTE_FRAGMENT_TYPE): + if fragment_class := FRAGMENT_TYPES[fragment_type]: + return fragment_class(blueprint) + else: + CustomLogging.error(f"Fragment type {fragment_type} does not exists") + else: + CustomLogging.error(f"Flag {ATTRIBUTE_FRAGMENT_TYPE} not defined in blueprint") \ No newline at end of file diff --git a/compiler/python_compiler/engines/utils/types.py b/compiler/python_compiler/engines/utils/types.py new file mode 100644 index 0000000..44f4ddb --- /dev/null +++ b/compiler/python_compiler/engines/utils/types.py @@ -0,0 +1,13 @@ +ANY = "any" +PYTHON_TYPE_NAMES={ + ANY:False, + "str":"str", #{"name":"str", "type":str} + "int":"int", + "bool":"bool", + "list":"list", + "tuple":"tuple", + "dict":"dict", + +} +def get_python_type_str(type_name:str) -> str: + return PYTHON_TYPE_NAMES.get(type_name) \ No newline at end of file diff --git a/compiler/utils/flags.py b/compiler/utils/flags.py index c6c7035..0f6d258 100644 --- a/compiler/utils/flags.py +++ b/compiler/utils/flags.py @@ -9,4 +9,16 @@ def to_flag(text:str): FLAG_EXTENDS = to_flag("extends") FLAG_EXCLUDES = to_flag("excludes") FLAG_INCLUDES = to_flag("includes") + FLAG_FROM = to_flag("from") + + + +ATTRIBUTE_FRAGMENT_TYPE = "type" +ATTRIBUTE_TYPE = "type" + +ATTRIBUTE_FUNCTION_NAME = "name" +ATTRIBUTE_FUNCTION_ARGS = "args" +ATTRIBUTE_FUNCTION_KWARGS = "kwargs" +ATTRIBUTE_FUNCTION_OUTPUTS = "outputs" +ATTRIBUTE_FUNCTION_CODE = "code" From c1c8c37c772e30c75a232ffad04186466d30e9ea Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sat, 28 Aug 2021 16:11:34 -0500 Subject: [PATCH 08/12] Variable Compiler --- .../processing/operations/sum.code.json | 15 ++++- .../python_compiler/engines/py3_8/Compiler.py | 2 +- .../engines/py3_8/Conditional.py | 0 .../python_compiler/engines/py3_8/Fragment.py | 4 +- .../python_compiler/engines/py3_8/Function.py | 14 +++-- .../engines/py3_8/FunctionArgs.py | 12 ++-- .../engines/py3_8/FunctionCall.py | 0 .../python_compiler/engines/py3_8/Return.py | 0 .../python_compiler/engines/py3_8/Variable.py | 61 +++++++++++++++++++ .../engines/py3_8/get_fragment_class.py | 22 ++++--- compiler/utils/CustomLogging.py | 2 + compiler/utils/flags.py | 15 ++++- 12 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 compiler/python_compiler/engines/py3_8/Conditional.py create mode 100644 compiler/python_compiler/engines/py3_8/FunctionCall.py create mode 100644 compiler/python_compiler/engines/py3_8/Return.py create mode 100644 compiler/python_compiler/engines/py3_8/Variable.py diff --git a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json index 46e4fd3..570e6f4 100644 --- a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json +++ b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json @@ -13,6 +13,9 @@ "__number_a":{"type":"int", "required":true}, "__number_b":{"type":"int", "required":true} }, + "kwargs":{ + "debug":{"type":"bool", "default":false} + }, "outputs":{ "result":{"type":"int", "required":true} }, @@ -21,7 +24,17 @@ "type": "variable", "variable_type": "str", "name": "result", - "equals": "__number_a+number_b" + "expression": "__number_a+number_b" + }, + { + "type": "conditional", + "condition": "debug", + "code": [ + { + "type": "function_call", + "args": ["result"] + } + ] }, { "type": "return", diff --git a/compiler/python_compiler/engines/py3_8/Compiler.py b/compiler/python_compiler/engines/py3_8/Compiler.py index 54e1d59..2b19e08 100644 --- a/compiler/python_compiler/engines/py3_8/Compiler.py +++ b/compiler/python_compiler/engines/py3_8/Compiler.py @@ -3,5 +3,5 @@ def compile(blueprint:dict)->str: - build = get_fragment_class(blueprint) + build = get_fragment_class(blueprint, compile) return build.compile() diff --git a/compiler/python_compiler/engines/py3_8/Conditional.py b/compiler/python_compiler/engines/py3_8/Conditional.py new file mode 100644 index 0000000..e69de29 diff --git a/compiler/python_compiler/engines/py3_8/Fragment.py b/compiler/python_compiler/engines/py3_8/Fragment.py index 3333e4d..52a39b0 100644 --- a/compiler/python_compiler/engines/py3_8/Fragment.py +++ b/compiler/python_compiler/engines/py3_8/Fragment.py @@ -1,6 +1,8 @@ class Fragment: blueprint:dict - def __init__(self, blueprint) -> None: + general_compile=None#:function + def __init__(self, blueprint, *, compile) -> None: + self.general_compile = compile self.blueprint = blueprint def compile(self)->str: fragment_build = self.blueprint.get("type","") diff --git a/compiler/python_compiler/engines/py3_8/Function.py b/compiler/python_compiler/engines/py3_8/Function.py index 4b04876..0e1c913 100644 --- a/compiler/python_compiler/engines/py3_8/Function.py +++ b/compiler/python_compiler/engines/py3_8/Function.py @@ -34,8 +34,8 @@ class Function(Fragment): args:dict kwargs:dict outputs:dict - def __init__(self, blueprint) -> None: - super().__init__(blueprint) + def __init__(self, blueprint, *args, **kwargs) -> None: + super().__init__( blueprint, *args, **kwargs) self.name = get_function_name(blueprint) self.args = get_function_args(blueprint) self.kwargs = get_function_kwargs(blueprint) @@ -44,11 +44,13 @@ def __init__(self, blueprint) -> None: def inputs_compile(self) -> str: inputs_build = "" if self.args: - function_args = FunctionArgs(self.args) + function_args = FunctionArgs(self.args, compile=self.general_compile) inputs_build += function_args.compile() if self.kwargs: - function_kwargs = FunctionArgs(self.kwargs) + function_kwargs = FunctionArgs(self.kwargs, compile=self.general_compile) + if self.args: + inputs_build += "," inputs_build += f" *, {function_kwargs.compile()}" return inputs_build def outputs_compile(self) -> str: @@ -56,12 +58,12 @@ def outputs_compile(self) -> str: if len(self.outputs) == 1: if not (arg_type_name := self.outputs[list(self.outputs)[0]].get(ATTRIBUTE_TYPE)): # TODO: Temporal Outoput test arg_type_name = ANY - outputs_build += f" -> {get_python_type_str(arg_type_name)} " + outputs_build += f"->{get_python_type_str(arg_type_name)}" return outputs_build def code_lines_compile(self) -> list: code_build_lines = [] for line in self.code: - code_build_lines.append("\t"+line["type"]) + code_build_lines.append(TAB+self.general_compile(line)) return code_build_lines def compile(self)->str: fragment_lines = [] diff --git a/compiler/python_compiler/engines/py3_8/FunctionArgs.py b/compiler/python_compiler/engines/py3_8/FunctionArgs.py index 8db7fe1..2dd6437 100644 --- a/compiler/python_compiler/engines/py3_8/FunctionArgs.py +++ b/compiler/python_compiler/engines/py3_8/FunctionArgs.py @@ -5,19 +5,19 @@ class FunctionArgs(Fragment): - def __init__(self, blueprint) -> None: - super().__init__(blueprint) + def __init__(self, blueprint, *args, **kwargs) -> None: + super().__init__(blueprint, *args, **kwargs) def compile(self)->str: fragment_build = "" cleaned_args = [] for arg in self.blueprint: if not (arg_type_name := self.blueprint[arg].get(ATTRIBUTE_TYPE)): arg_type_name = ANY - cleaned_arg = "" + if (arg_default_value := self.blueprint[arg].get(ATTRIBUTE_DEFAULT, "")) != "": + arg_default_value = "="+str(arg_default_value) if arg_type := get_python_type_str(arg_type_name): - cleaned_arg = f"{arg}:{arg_type}" - else: - cleaned_arg = arg + arg_type = ":"+arg_type + cleaned_arg = f"{arg}{arg_type}{arg_default_value}" cleaned_args.append(cleaned_arg) fragment_build = ", ".join(cleaned_args) return fragment_build \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/FunctionCall.py b/compiler/python_compiler/engines/py3_8/FunctionCall.py new file mode 100644 index 0000000..e69de29 diff --git a/compiler/python_compiler/engines/py3_8/Return.py b/compiler/python_compiler/engines/py3_8/Return.py new file mode 100644 index 0000000..e69de29 diff --git a/compiler/python_compiler/engines/py3_8/Variable.py b/compiler/python_compiler/engines/py3_8/Variable.py new file mode 100644 index 0000000..966fb8e --- /dev/null +++ b/compiler/python_compiler/engines/py3_8/Variable.py @@ -0,0 +1,61 @@ +from .Fragment import Fragment +from utils.flags import * +from utils.CustomLogging import CustomLogging +#from python_compiler.engines.utils.types import get_python_type_str, ANY + + +DEFAULT_ASSIGN_OPERATOR = "=" +ASSIGN_OPERATORS = { + "=":"=", + "+=":"+=", + "-=":"-=", + "*=":"*=", + "/=":"/=", + "//=":"//=", + "%=":"%=", + "**=":"**=", + "&=":"&=", + "|=":"|=", + "^=":"^=", + ">>=":">>=", + "<<=":"<<=", +} + +def get_variable_name(fragment) -> str: + if not (variable_name := fragment.get(ATTRIBUTE_VARIABLE_NAME)): + CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_NAME}' attribute does not exists") + return variable_name + +def get_variable_type(fragment) -> str: + if not (variable_type := fragment.get(ATTRIBUTE_VARIABLE_TYPE)): + variable_type = "" + else: + variable_type = ":"+variable_type + return variable_type + +def get_variable_assign_operator(fragment) -> str: + if not (variable_assign_operator := fragment.get(ATTRIBUTE_VARIABLE_ASSIGN_OPERATOR)): + variable_assign_operator = DEFAULT_ASSIGN_OPERATOR + return ASSIGN_OPERATORS.get(variable_assign_operator) + +def get_variable_expression(fragment) -> str: + if not (variable_expression := fragment.get(ATTRIBUTE_VARIABLE_EXPRESSION)): + CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_EXPRESSION}' attribute does not exists") + return variable_expression + + +class Variable(Fragment): + name:str + variable_type:str + assign_operator:str + expression:str + def __init__(self, blueprint, *args, **kwargs) -> None: + super().__init__(blueprint, *args, **kwargs) + self.name = get_variable_name(blueprint) + self.variable_type = get_variable_type(blueprint) + self.assign_operator = get_variable_assign_operator(blueprint) + self.expression = get_variable_expression(blueprint) + def compile(self)->str: + fragment_build = "" + fragment_build = f"{self.name}{self.variable_type} {self.assign_operator} {self.expression}" + return fragment_build \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/get_fragment_class.py b/compiler/python_compiler/engines/py3_8/get_fragment_class.py index 66e492f..6a3390a 100644 --- a/compiler/python_compiler/engines/py3_8/get_fragment_class.py +++ b/compiler/python_compiler/engines/py3_8/get_fragment_class.py @@ -1,19 +1,27 @@ -from .Fragment import Fragment -from .Function import Function from utils.flags import * from utils.CustomLogging import CustomLogging + +from .Fragment import Fragment +from .Function import Function +from .Variable import Variable +from .Conditional import Conditional +from .FunctionCall import FunctionCall +from .Return import Return + + FRAGMENT_TYPES={ "function": Function, + "function_call":FunctionCall, "class":Fragment, - "variable":Fragment, - "conditional":Fragment, - "return":Fragment + "variable":Variable, + "conditional":Conditional, + "return":Return } -def get_fragment_class(blueprint): +def get_fragment_class(blueprint, compile): if fragment_type := blueprint.get(ATTRIBUTE_FRAGMENT_TYPE): if fragment_class := FRAGMENT_TYPES[fragment_type]: - return fragment_class(blueprint) + return fragment_class(blueprint, compile=compile) else: CustomLogging.error(f"Fragment type {fragment_type} does not exists") else: diff --git a/compiler/utils/CustomLogging.py b/compiler/utils/CustomLogging.py index ba724de..81ade3f 100644 --- a/compiler/utils/CustomLogging.py +++ b/compiler/utils/CustomLogging.py @@ -3,5 +3,7 @@ def log(msg:str): print("LOG:",msg) def error(msg:str): raise NameError(msg) + def critical(msg:str): + raise NameError(msg) def warning(msg:str): print("WARNING:",msg) \ No newline at end of file diff --git a/compiler/utils/flags.py b/compiler/utils/flags.py index 0f6d258..5912519 100644 --- a/compiler/utils/flags.py +++ b/compiler/utils/flags.py @@ -1,11 +1,12 @@ -MODELS_FIELD = "models" -SEVICES_FIELD = "services" SPECIAL_FIELD_FLAG = "__" def is_flag(text:str): return text.startswith(SPECIAL_FIELD_FLAG) def to_flag(text:str): return SPECIAL_FIELD_FLAG+text +MODELS_FIELD = "models" +SEVICES_FIELD = "services" + FLAG_EXTENDS = to_flag("extends") FLAG_EXCLUDES = to_flag("excludes") FLAG_INCLUDES = to_flag("includes") @@ -13,12 +14,22 @@ def to_flag(text:str): FLAG_FROM = to_flag("from") +TAB = "\t" ATTRIBUTE_FRAGMENT_TYPE = "type" ATTRIBUTE_TYPE = "type" +ATTRIBUTE_DEFAULT = "default" ATTRIBUTE_FUNCTION_NAME = "name" ATTRIBUTE_FUNCTION_ARGS = "args" ATTRIBUTE_FUNCTION_KWARGS = "kwargs" ATTRIBUTE_FUNCTION_OUTPUTS = "outputs" ATTRIBUTE_FUNCTION_CODE = "code" + +ATTRIBUTE_FUNCTION_RETURN_ARGS = "args" + + +ATTRIBUTE_VARIABLE_NAME = "name" +ATTRIBUTE_VARIABLE_TYPE = "variable_type" +ATTRIBUTE_VARIABLE_EXPRESSION = "expression" +ATTRIBUTE_VARIABLE_ASSIGN_OPERATOR = "assign_operator" \ No newline at end of file From be2301fd6c976e5360b76cdee9a357af590d3de6 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sat, 28 Aug 2021 16:12:46 -0500 Subject: [PATCH 09/12] python return object --- .../python_compiler/engines/py3_8/Return.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/compiler/python_compiler/engines/py3_8/Return.py b/compiler/python_compiler/engines/py3_8/Return.py index e69de29..a0b87a0 100644 --- a/compiler/python_compiler/engines/py3_8/Return.py +++ b/compiler/python_compiler/engines/py3_8/Return.py @@ -0,0 +1,20 @@ +from .Fragment import Fragment +from utils.flags import * +from utils.CustomLogging import CustomLogging +from python_compiler.engines.utils.types import get_python_type_str, ANY + +def get_return_attributes(fragment) -> list: + if not (return_attributes := fragment.get(ATTRIBUTE_FUNCTION_RETURN_ARGS)): + return_attributes = [] + return return_attributes + +class Return(Fragment): + return_attributes:list + def __init__(self, blueprint, *args, **kwargs) -> None: + super().__init__( blueprint, *args, **kwargs) + self.return_attributes = get_return_attributes(blueprint) + def compile(self)->str: + fragment_build = "" + return_attributes_build = ", ".join(self.return_attributes) + fragment_build = f"return {return_attributes_build}" + return fragment_build \ No newline at end of file From d57302ed477f0f4b9ce0d5a49dd2f612ea70f467 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sat, 28 Aug 2021 20:26:12 -0500 Subject: [PATCH 10/12] python conditional and function call compilers --- .../v2/services/processing/operations/sum.code.json | 1 + compiler/python_compiler/engines/py3_8/Compiler.py | 4 ++-- compiler/python_compiler/engines/py3_8/Fragment.py | 4 +++- compiler/python_compiler/engines/py3_8/Function.py | 6 +++--- compiler/python_compiler/engines/py3_8/Variable.py | 4 ++-- .../python_compiler/engines/py3_8/get_fragment_class.py | 6 +++--- compiler/utils/flags.py | 6 +++++- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json index 570e6f4..f7dbfd4 100644 --- a/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json +++ b/blueprints/examples/calculator/v2/services/processing/operations/sum.code.json @@ -32,6 +32,7 @@ "code": [ { "type": "function_call", + "function":"print", "args": ["result"] } ] diff --git a/compiler/python_compiler/engines/py3_8/Compiler.py b/compiler/python_compiler/engines/py3_8/Compiler.py index 2b19e08..4188e0b 100644 --- a/compiler/python_compiler/engines/py3_8/Compiler.py +++ b/compiler/python_compiler/engines/py3_8/Compiler.py @@ -2,6 +2,6 @@ from .get_fragment_class import get_fragment_class -def compile(blueprint:dict)->str: - build = get_fragment_class(blueprint, compile) +def compile(blueprint:dict, *, level = 0)->str: + build = get_fragment_class(blueprint, compile, level=level) return build.compile() diff --git a/compiler/python_compiler/engines/py3_8/Fragment.py b/compiler/python_compiler/engines/py3_8/Fragment.py index 52a39b0..889db66 100644 --- a/compiler/python_compiler/engines/py3_8/Fragment.py +++ b/compiler/python_compiler/engines/py3_8/Fragment.py @@ -1,9 +1,11 @@ class Fragment: blueprint:dict general_compile=None#:function - def __init__(self, blueprint, *, compile) -> None: + level=0 + def __init__(self, blueprint, *, compile, level=0) -> None: self.general_compile = compile self.blueprint = blueprint + self.level = level def compile(self)->str: fragment_build = self.blueprint.get("type","") return fragment_build \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/Function.py b/compiler/python_compiler/engines/py3_8/Function.py index 0e1c913..d8b8b88 100644 --- a/compiler/python_compiler/engines/py3_8/Function.py +++ b/compiler/python_compiler/engines/py3_8/Function.py @@ -6,7 +6,7 @@ def get_function_name(fragment) -> str: if not (function_name := fragment.get(ATTRIBUTE_FUNCTION_NAME)): - CustomLogging.critical(f"Fragment type functions 'name' attribute does not exists") + CustomLogging.critical(f"Fragment type functions 'name' attribute does not exist") return function_name def get_function_args(fragment) -> dict: @@ -50,7 +50,7 @@ def inputs_compile(self) -> str: if self.kwargs: function_kwargs = FunctionArgs(self.kwargs, compile=self.general_compile) if self.args: - inputs_build += "," + inputs_build += "," # TODO: disguisting but effective inputs_build += f" *, {function_kwargs.compile()}" return inputs_build def outputs_compile(self) -> str: @@ -63,7 +63,7 @@ def outputs_compile(self) -> str: def code_lines_compile(self) -> list: code_build_lines = [] for line in self.code: - code_build_lines.append(TAB+self.general_compile(line)) + code_build_lines.append(TAB*(self.level+1)+self.general_compile(line, level=self.level+1)) return code_build_lines def compile(self)->str: fragment_lines = [] diff --git a/compiler/python_compiler/engines/py3_8/Variable.py b/compiler/python_compiler/engines/py3_8/Variable.py index 966fb8e..297a9db 100644 --- a/compiler/python_compiler/engines/py3_8/Variable.py +++ b/compiler/python_compiler/engines/py3_8/Variable.py @@ -23,7 +23,7 @@ def get_variable_name(fragment) -> str: if not (variable_name := fragment.get(ATTRIBUTE_VARIABLE_NAME)): - CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_NAME}' attribute does not exists") + CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_NAME}' attribute does not exist") return variable_name def get_variable_type(fragment) -> str: @@ -40,7 +40,7 @@ def get_variable_assign_operator(fragment) -> str: def get_variable_expression(fragment) -> str: if not (variable_expression := fragment.get(ATTRIBUTE_VARIABLE_EXPRESSION)): - CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_EXPRESSION}' attribute does not exists") + CustomLogging.critical(f"Fragment type variable '{ATTRIBUTE_VARIABLE_EXPRESSION}' attribute does not exist") return variable_expression diff --git a/compiler/python_compiler/engines/py3_8/get_fragment_class.py b/compiler/python_compiler/engines/py3_8/get_fragment_class.py index 6a3390a..893d803 100644 --- a/compiler/python_compiler/engines/py3_8/get_fragment_class.py +++ b/compiler/python_compiler/engines/py3_8/get_fragment_class.py @@ -18,11 +18,11 @@ "return":Return } -def get_fragment_class(blueprint, compile): +def get_fragment_class(blueprint, compile, *, level=0): if fragment_type := blueprint.get(ATTRIBUTE_FRAGMENT_TYPE): if fragment_class := FRAGMENT_TYPES[fragment_type]: - return fragment_class(blueprint, compile=compile) + return fragment_class(blueprint, compile=compile, level=level) else: - CustomLogging.error(f"Fragment type {fragment_type} does not exists") + CustomLogging.error(f"Fragment type {fragment_type} does not exist") else: CustomLogging.error(f"Flag {ATTRIBUTE_FRAGMENT_TYPE} not defined in blueprint") \ No newline at end of file diff --git a/compiler/utils/flags.py b/compiler/utils/flags.py index 5912519..1754c76 100644 --- a/compiler/utils/flags.py +++ b/compiler/utils/flags.py @@ -28,8 +28,12 @@ def to_flag(text:str): ATTRIBUTE_FUNCTION_RETURN_ARGS = "args" +ATTRIBUTE_FUNCTION_CALL_NAME = "function" ATTRIBUTE_VARIABLE_NAME = "name" ATTRIBUTE_VARIABLE_TYPE = "variable_type" ATTRIBUTE_VARIABLE_EXPRESSION = "expression" -ATTRIBUTE_VARIABLE_ASSIGN_OPERATOR = "assign_operator" \ No newline at end of file +ATTRIBUTE_VARIABLE_ASSIGN_OPERATOR = "assign_operator" + +ATTRIBUTE_CONDITIONAL_CONDITION = "condition" +ATTRIBUTE_CONDITIONAL_CODE = "code" \ No newline at end of file From c005fa73b10df2ab908d717ef2249f8f06a0cb31 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sat, 28 Aug 2021 20:27:34 -0500 Subject: [PATCH 11/12] changes --- .../engines/py3_8/Conditional.py | 33 ++++++++++++++ .../engines/py3_8/FunctionCall.py | 43 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/compiler/python_compiler/engines/py3_8/Conditional.py b/compiler/python_compiler/engines/py3_8/Conditional.py index e69de29..1e9377c 100644 --- a/compiler/python_compiler/engines/py3_8/Conditional.py +++ b/compiler/python_compiler/engines/py3_8/Conditional.py @@ -0,0 +1,33 @@ +from .Fragment import Fragment +from utils.flags import * +from utils.CustomLogging import CustomLogging +from python_compiler.engines.utils.types import get_python_type_str, ANY + +def get_conditional_condition(fragment) -> str: + if not (condition := fragment.get(ATTRIBUTE_CONDITIONAL_CONDITION)): + CustomLogging.critical(f"Fragment type conditional '{ATTRIBUTE_CONDITIONAL_CONDITION}' attribute does not exist") + return condition + +def get_conditional_code(fragment) -> list: + if not (code := fragment.get(ATTRIBUTE_CONDITIONAL_CODE)): + CustomLogging.critical(f"Fragment type conditional '{ATTRIBUTE_CONDITIONAL_CODE}' attribute does not exist") + return code +class Conditional(Fragment): + condition:str + code:list + def __init__(self, blueprint, *args, **kwargs) -> None: + super().__init__( blueprint, *args, **kwargs) + self.condition = get_conditional_condition(blueprint) + self.code = get_conditional_code(blueprint) + def code_lines_compile(self) -> list: + code_build_lines = [] + for line in self.code: + code_build_lines.append(TAB*(self.level+1)+self.general_compile(line)) + return code_build_lines + def compile(self)->str: + fragment_lines = [] + fragment_lines.append(f"if {self.condition}:") + fragment_lines.extend(self.code_lines_compile()) + fragment_build = "\n".join(fragment_lines) + + return fragment_build \ No newline at end of file diff --git a/compiler/python_compiler/engines/py3_8/FunctionCall.py b/compiler/python_compiler/engines/py3_8/FunctionCall.py index e69de29..182a46b 100644 --- a/compiler/python_compiler/engines/py3_8/FunctionCall.py +++ b/compiler/python_compiler/engines/py3_8/FunctionCall.py @@ -0,0 +1,43 @@ +from .Fragment import Fragment +from utils.flags import * +from utils.CustomLogging import CustomLogging +from python_compiler.engines.utils.types import get_python_type_str, ANY + +def get_function_name(fragment) -> str: + if not (function_name := fragment.get(ATTRIBUTE_FUNCTION_CALL_NAME)): + CustomLogging.critical(f"Fragment type function_call '{ATTRIBUTE_FUNCTION_CALL_NAME}' attribute does not exist") + return function_name + +def get_function_args(fragment) -> dict: + if not (function_args := fragment.get(ATTRIBUTE_FUNCTION_ARGS)): + function_args = {} + return function_args + +def get_function_kwargs(fragment) -> dict: + if not (function_kwargs := fragment.get(ATTRIBUTE_FUNCTION_KWARGS)): + function_kwargs = {} + return function_kwargs + +class FunctionCall(Fragment): + name:str + args:dict + kwargs:dict + def __init__(self, blueprint, *args, **kwargs) -> None: + super().__init__( blueprint, *args, **kwargs) + self.name = get_function_name(blueprint) + self.args = get_function_args(blueprint) + self.kwargs = get_function_kwargs(blueprint) + def inputs_compile(self) -> str: + inputs = [] + if self.args: + inputs = self.args + + if self.kwargs: + inputs.extend([ f"{x}:{self.kwargs[x]}" for x in self.kwargs]) + + inputs_build = ", ".join(inputs) + return inputs_build + def compile(self)->str: + fragment_build = f"{self.name}({self.inputs_compile()})" + + return fragment_build \ No newline at end of file From f9237f74d137c576429d939d062181d57bd071f9 Mon Sep 17 00:00:00 2001 From: unknowncoder05 <49960321+unknowncoder05@users.noreply.github.com> Date: Sat, 28 Aug 2021 20:43:29 -0500 Subject: [PATCH 12/12] basic documentation --- README.md | 27 ++++++++++++++++++++++++++- compiler/compiler.py | 5 ++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccaba12..c0e022b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,33 @@ # App architect +### Python Compiler +There is no faster way for understanding than trying it yourself. +you can execute the next command in the root of the project (this folder) and a simple code wil be generated. ```sh -python .\compiler\compiler.py c "django.json.v1" ./blueprints/examples/facebook/main.app.json ./compiler/build +python .\compiler\compiler.py c "python.json.v1" ./blueprints/examples/calculator/v2/services/processing/operations/sum.code.json code.py ``` + +You can check the base blueprint for this project in the route examples/calculator/v2/services/processing/operations/sum.code.json + +```py +def sum(number_a:int, number_b:int, *, debug:bool=False)->int: + result:str = number_a+number_b + if debug: + print(result) + return result +``` +This is the expected answer, a simple function with all that we specified in the code.json file and ready to be used. + +#### What is so special about this? +This is a basic format for you to generate code in any language, in any framework as long as the correct compiler is available. + +### Current roadmap for this project + +- Finish the basic Python compiler +- Add tests +- Work in the JS Express compiler +- Create a UI from where to Edit code and generate the proper code.json, then you can choose from your saved snippets or those that other people had made public +### App Compiler Design your application in a json like structure, this way the resulting project is going to be easily understood both by human and by machine. This json like structure will let you: diff --git a/compiler/compiler.py b/compiler/compiler.py index a203b1f..740fec8 100644 --- a/compiler/compiler.py +++ b/compiler/compiler.py @@ -15,8 +15,11 @@ def compile(compiler_name, project_name): compiler = COMPILERS[compiler_name](main_file=project_name) compiled_project = compiler.compile() print(compiled_project) - with open(f"./{sys.argv[4]}.build.json", "w") as f: + # TODO: propper file extension and format saving + ''' + with open(f"./{sys.argv[4]}", "w") as f: json.dump(compiled_project, f, indent=4) + ''' OPTIONS = { "compile": compile, "c": compile