diff --git a/src/pycropml/cyml.py b/src/pycropml/cyml.py index fb22348..0be8adc 100644 --- a/src/pycropml/cyml.py +++ b/src/pycropml/cyml.py @@ -17,6 +17,7 @@ from pycropml.transpiler.antlr_py.fortran.run import run_fortran from pycropml.transpiler.antlr_py.python.run import run_python from pycropml.transpiler.antlr_py.apsim.run import run_apsim +from pycropml.transpiler.antlr_py.csharp.run import run_csharp from pycropml import render_cyml, nameconvention from pycropml.pparse import model_parser from pycropml.writeTest import WriteTest @@ -68,7 +69,7 @@ "sirius2": 'cs' } -cymltx_languages = ['dssat', "simplace", "bioma", "openalea", "f90", "stics", "py", "apsim"] +cymltx_languages = ['dssat', "simplace", "bioma", "openalea", "f90", "stics", "py", "apsim","cs"] langs = ["cs", "cpp", "java", "f90", "r", "py"] domain_class = ["cs", "java", "sirius", "cpp", "cpp2", "bioma", "sirius2", "apsim"] diff --git a/src/pycropml/topology.py b/src/pycropml/topology.py index 574736e..74a35ef 100644 --- a/src/pycropml/topology.py +++ b/src/pycropml/topology.py @@ -97,19 +97,23 @@ def __init__(self, name, pkg=None): self.pkg = input(f"Give the path of package {self.name}") self.data = Path(self.pkg)/"crop2ml" self.diff_in, self.diff_out = {}, {} - composite_file = self.data.glob("composition*.xml")[0] - self.mu = model_parser(self.pkg) - self.model, = composition.model_parser(composite_file) - self.pkgs[self.name] = [self.pkg, self.model] - self.model.inputs = self.meta_inp(self.name) - self.model.outputs = self.meta_out(self.name) - self.model.ext = self.meta_ext(self.name) - self.model.states = self.findstates(self.model.inputs, self.model.outputs) - self.model.path = Path(self.pkg) - self.minout() - self.path_pkg = None - self.model.diff_in = self.diff_in - self.model.diff_out = self.diff_out + composite_file = None + composite_files = self.data.glob("composition*.xml") + if composite_files: + composite_file = composite_files[0] + self.mu = model_parser(self.pkg) + self.model, = composition.model_parser(composite_file) + self.pkgs[self.name] = [self.pkg, self.model] + self.model.inputs = self.meta_inp(self.name) + self.model.outputs = self.meta_out(self.name) + self.model.ext = self.meta_ext(self.name) + self.model.states = self.findstates(self.model.inputs, self.model.outputs) + self.model.path = Path(self.pkg) + self.minout() + self.path_pkg = None + self.model.diff_in = self.diff_in + self.model.diff_out = self.diff_out + self.composite_file = composite_file def isPackage(self, name): if sys.version_info[0] >= 3: diff --git a/src/pycropml/transpiler/antlr_py/apsim/run.py b/src/pycropml/transpiler/antlr_py/apsim/run.py index 4f28001..11a88f5 100644 --- a/src/pycropml/transpiler/antlr_py/apsim/run.py +++ b/src/pycropml/transpiler/antlr_py/apsim/run.py @@ -2,6 +2,7 @@ from __future__ import absolute_import from __future__ import print_function +from os.path import isdir from path import Path import os from pycropml.transpiler.antlr_py.to_CASG import to_dictASG, to_CASG @@ -236,9 +237,6 @@ def action_custom_call(self, tree): if len(trees.args) != len(inps): trees.args.extend(inps[len(trees.args):]) - """if f.name == "Divide": - print("Divideeeeeeee", [t.y for t in inps]) - print("Divide", [t.y for t in trees.args])""" for num1, ar1 in enumerate(trees.args): for num2, ar2 in enumerate(inps): if num1 == num2: @@ -573,19 +571,19 @@ def action_for_statement(self, tree): def create_package(output): crop2ml_rep = Path(os.path.join(output, 'crop2ml')) - if not crop2ml_rep.isdir(): + if not isdir(crop2ml_rep): crop2ml_rep.mkdir() algo_rep = Path(os.path.join(crop2ml_rep, 'algo')) - if not algo_rep.isdir(): + if not isdir(algo_rep): algo_rep.mkdir() cyml_rep = Path(os.path.join(algo_rep, 'pyx')) - if not cyml_rep.isdir(): + if not isdir(cyml_rep): cyml_rep.mkdir() return crop2ml_rep, cyml_rep + - def function_dependency(st, f): r = [f] z = ApsimExtraction() @@ -684,8 +682,6 @@ def run_apsim(component, output): files = repowalk.walk(component, "cs" ) xfiles = repowalk.walk(component, "xml" ) - modelp = ModelParser() - mp = modelp.parse(component) res = {} stra = {} straNames = [] @@ -735,7 +731,6 @@ def run_apsim(component, output): kk = ApsimExtraction() #all_var = kk.getAllVar(vinfo) all_var = extract_io(list(xfiles.values())[0]) - #print("all", all_var) for k, st in enumerate(strats): print(k, st) mod = source_codes[k] @@ -945,10 +940,13 @@ def run_apsim(component, output): description["url"] = "" description["ExtendedDescription"]="Soil Temperature" description["ShortDescription"]="Soil Temperature" + + modelp = ModelParser() + mp = modelp.parse(output) mc = createObjectCompo(description,mp) xml_ = Pl2Crop2ml(mc, "APSIM_").run_compo() - filename = os.path.join(pkg, "crop2ml", "composition.%s.xml"%(mp[0].name)) + filename = os.path.join(output, "crop2ml", "composition.%s.xml"%(mp[0].name)) with open(filename, "wb") as xml_file: r = '\n' r += '\n' diff --git a/src/pycropml/transpiler/antlr_py/bioma/run.py b/src/pycropml/transpiler/antlr_py/bioma/run.py index c1753e9..5a9c3c3 100644 --- a/src/pycropml/transpiler/antlr_py/bioma/run.py +++ b/src/pycropml/transpiler/antlr_py/bioma/run.py @@ -43,7 +43,8 @@ "DATELIST":"List", "BOOLEAN":"bool", "DOUBLEARRAY":"array", - "INTARRAY":"array"} + "INTARRAY":"array", + "STRINGARRAY":["array", "string"]} pseudo_type_={ "DOUBLE":"double", diff --git a/src/pycropml/transpiler/antlr_py/createXml.py b/src/pycropml/transpiler/antlr_py/createXml.py index fc9e0c3..c93ac01 100644 --- a/src/pycropml/transpiler/antlr_py/createXml.py +++ b/src/pycropml/transpiler/antlr_py/createXml.py @@ -112,7 +112,7 @@ def run_unit(self): def run_compo(self): """ Generate Crop2ML specification of a CompositeModel from a workflow. """ md = self.md - name = md.name[:-9] if md.name.endswith("Component") else md.name + name = md.name.replace("Component", "") if md.name.endswith("Component") else md.name # ModelComposition name id version timestep xml = ns.ModelComposition(name=name, id=self.pkgname + "." + name, version=md.version, timestep=md.timestep) diff --git a/src/pycropml/transpiler/antlr_py/csharp/api_transform.py b/src/pycropml/transpiler/antlr_py/csharp/api_transform.py index 060897e..ff18894 100644 --- a/src/pycropml/transpiler/antlr_py/csharp/api_transform.py +++ b/src/pycropml/transpiler/antlr_py/csharp/api_transform.py @@ -326,7 +326,8 @@ def integr_expander(type, message, args): }, 'array':{ - 'array': StandardMethodCall('numpy', 'array', expander = array_expander ) + 'array': StandardMethodCall('numpy', 'array', expander = array_expander ), + 'ConstrainedCopy': StandardMethodCall('array', 'constrained_copy', expander = constrained_copy_expander) } , 'Array':{ 'Copy': StandardMethodCall('array', 'copy', expander = copyarray_expander ), @@ -391,7 +392,8 @@ def integr_expander(type, message, args): 'append': StandardMethodCall('array', 'append'), 'Length': StandardMethodCall('array', 'len', expander=len_expander), 'CopyTo': StandardMethodCall('array', 'copyto', expander=copyto_expander), - 'Except': StandardMethodCall('array', 'except') + 'Except': StandardMethodCall('array', 'except')#, + #'ConstrainedCopy': StandardMethodCall('array', 'ConstrainedCopy') }, 'tuple': { @@ -405,6 +407,9 @@ def integr_expander(type, message, args): }, "array":{ "Length": StandardMethodCall("array", "len", expander=len_expander) + }, + "Array":{ + "Length": StandardMethodCall("array", "len", expander=len_expander) } } diff --git a/src/pycropml/transpiler/antlr_py/csharp/cs_cyml.py b/src/pycropml/transpiler/antlr_py/csharp/cs_cyml.py index 5821836..afa9025 100644 --- a/src/pycropml/transpiler/antlr_py/csharp/cs_cyml.py +++ b/src/pycropml/transpiler/antlr_py/csharp/cs_cyml.py @@ -234,7 +234,7 @@ def visit_array(self, node): return res def visit_List(self, node): - if "value" not in dir(node) and "elements" not in dir(node): + if "init" not in dir(node) and "value" not in dir(node) and "elements" not in dir(node): z = [] elif "elements" in dir(node): z = self.visit(node.elements) diff --git a/src/pycropml/transpiler/antlr_py/csharp/csharpExtraction.py b/src/pycropml/transpiler/antlr_py/csharp/csharpExtraction.py new file mode 100644 index 0000000..774319a --- /dev/null +++ b/src/pycropml/transpiler/antlr_py/csharp/csharpExtraction.py @@ -0,0 +1,604 @@ + +from pycropml.transpiler.antlr_py.extract_metadata import MetaExtraction +from pycropml.description import Description +from pycropml.composition import ModelComposition +from pycropml.transpiler.antlr_py.extract_metadata_from_comment_ori import ExtractComments, extract, extract_compo +from pycropml.transpiler.antlr_py.extraction import ExtractComments +from pycropml.transpiler.antlr_py.codeExtraction import extraction +import re +import copy +from pycropml.transpiler.antlr_py.api_declarations import Middleware + +description_tags = ["//%%CyML Description Begin%%", "//%%CyML Description End%%"] + + +# coding: utf-8 +""" A simple Strategy class + In the constructor (Parameters description, Input and Output name, category) + In SetPublisherData method (author, institution) + In Domain property (Composite name) + In URL property (URL) + In Description property (Description) + + """ +from pycropml.transpiler.pseudo_tree import Node +from pycropml.transpiler.antlr_py.extract_metadata import MetaExtraction +from pycropml.modelunit import ModelUnit +from pycropml.description import Description +from pycropml.inout import Input, Output +from pycropml.function import Function +from pycropml.composition import ModelComposition +from collections import defaultdict + +class CsharpExtraction(MetaExtraction): + def __init__(self, code=""): + MetaExtraction.__init__(self) + self.inputs = [] + self.outputs = [] + self.model = None + self.mc = None + self.dclassdict = {} + self.code = code + + def getAlgo(self, tree): + meth = self.getmethod(tree, "CalculateModel") + if not meth: meth = self.getmethod(tree, "Estimate") + return meth + + def getInit(self, tree): + meth = self.getmethod(tree, "Init") + return meth + + + def getStrategyVar(self): + commentsPart = extraction(self.code, description_tags[0], description_tags[1]) + mdata = extract(commentsPart[0]+"\n\n") + inputs = mdata.inputs + outputs = mdata.outputs + parameters = [p for p in inputs if p.inputtype == "parameter"] + return (parameters, inputs, outputs) + + def getFromVarInfo(self, tree1, tree, dclass): + """get metadata from strategy classes and varinfo domain classes + + Args: + tree1 (Node): A strategy class transformed to Node + tree (Node): list of varinfo domain classes transformed to Nodes + dclass (Node): list of domain classes + + Returns: + Tuple: metadata (inputs, parameters, outputs) + """ + self.getTypeNode(tree, "methodDef") + methNode = self.getTree + descMeth = self.getAttNode(methNode,**{"name":"CalculateModel"}) + pass + + + def getAllVar(self, source_codes): + """get metadata from source_codes of strategy classes + + Args: + source_codes (list): list of source codes of strategy classes + + Returns: + Tuple: metadata (inputs, parameters, outputs) + + Result: + {'Q': {'Name': b'Q', 'category': 'AuxiliaryVarInfo', 'Description': b'Total moisture', + 'MaxValue': '100D', 'MinValue': '0D', 'DefaultValue': '50D', + 'Units': b'%', 'URL': b'http://', 'ValueType': 'DOUBLE'}, + 'Q2': {...} ... + } + """ + res = {} + for mod in source_codes: + commentsPart = extraction(mod, description_tags[0], description_tags[1]) + mdata = extract(commentsPart[0]+"\n\n") + for m in mdata.inputs + mdata.outputs: + res.update({ensure_text(m.name):m}) + return res + + + def description(self, tree): + + d = ["name", "authors", "institution", "description", "url", "reference"] + desc = {} + # get an instance of PublisherData + meth = self.getmethod(tree, "SetPublisherData") + ass = self.getAttNode(meth.block,**{"type":"assignment"}) + target = ass[0].target.name + addMeth = self.getAttNode(meth.block, **{"type":"custom_call"}) + for v in addMeth: + if v.args[0].value==b"Creator": desc["authors"] = v.args[1].value + if v.args[0].value==b"Publisher": desc["institution"] = v.args[1].value + property = self.getTypeNode(tree, "propertyDef") + pro = self.getAttNode(self.getTree,**{"name":"Description"} ) + desc["description"] = pro[0].get[0].value.value + pro = self.getAttNode(self.getTree,**{"name":"URL"} ) + desc["url"] = pro[0].get[0].value.value + desc["reference"] = pro[0].get[0].value.value + constr = self.getTypeNode(tree, "constructorDef") + desc["name"] = self.getTree[0].name + + return desc + + def getAlgo(self, tree): + meth = self.getmethod(tree, "CalculateModel") + if not meth: meth = self.getmethod(tree, "Estimate") + return meth + + def getInit(self, tree): + meth = self.getmethod(tree, "Init") + return meth + + def instancePastCurrent(self, stra): + algo = self.getAlgo(stra) + params = algo.params + res = {} + y = None + lst = [] + r = [] + for p in params: + if isinstance(p.pseudo_type, Node) and "typename" in dir(p.pseudo_type): + pname = str(p.name) + type_ = p.pseudo_type.typename + lst.append((p.pseudo_type.pseudo_type, pname)) + if type_ in res.values(): y = type_ + res.update({pname:type_}) + elif isinstance(p.pseudo_type, str): + lst.append((p.pseudo_type, str(p.name))) + + orDict = defaultdict(list) + + # iterating over list of tuples + for key, val in lst: + orDict[key].append(val) + + self.dclassdict = dict(orDict) + if y: + r = [k for k,v in res.items() if v == y] + else: + for k,v in self.dclassdict.items(): + if len(v) > 1: + r = v + break + return r + + @staticmethod + def retrieve_var_member(var): + pass + + def prec_cur_states(self, tree, past_current=[]): + inp_st = [] + if past_current: + algo = self.getAlgo(tree) + p = self.getStrategyVar() + inputs = [st.name for st in p[1]] + outputs = [st.name for st in p[2]] + self.getTypeNode(algo.block,"member_access") + v = self.getAttNode(self.getTree, name =past_current[1]) + precedent_v = list(set([vi.member if "." not in vi.member else vi.member.split(".")[0] for vi in v])) + v1 = self.getAttNode(self.getTree, name =past_current[0]) + current_v = list(set([vi.member if "." not in vi.member else vi.member.split(".")[0] for vi in v1])) + cv=[v for v in current_v if v not in outputs ] + for v in current_v: + if v in inputs and v not in precedent_v: + cv.append(v) + inp_st = list(set(cv))+ [t+"_t1" for t in precedent_v] + return inp_st + + + def totalvar(self, tree): + past_cur = self.instancePastCurrent(tree) + pc = self.prec_cur_states(tree, past_cur) + val = self.getStrategyVar() + p = val[1] + p2 = val[2] + var = [] + for inp in p: + var.append(inp.name) + var = var + pc + for out in p2: + s = out.name + if not (s in var and s+"_t1" in var): # I suppose that we could not have a current and past state in input and current state in output + var.append(s) + var = var + [v.name for v in val[0] if v] + return var + + + def model_desc(self, desc): + name = desc["name"][:-9] if desc["name"].endswith("Component") else desc["name"] + description = Description() + description.Title = name+" model" + description.Authors = desc["authors"].decode("utf-8") + description.Institution=desc["institution"].decode("utf-8") + description.Reference = desc["reference"].decode("utf-8"), + description.ExtendedDescription = desc["description"].decode("utf-8") + description.Url = desc["url"].decode("utf-8") + return description + + def modelunit(self, mdata, var, all_var_pa, tvar, inps, outs): + description = mdata.description + self.model= ModelUnit({"name":mdata.name, "version":mdata.version, "timestep":mdata.timestep}) + self.model.add_description(mdata.description) + inp = var[1] + out = var[2] + inpname = [p.name for p in inp] + outname = [p.name for p in out] + param = var[0] + param_names = [p.name for p in param] + inp = inp+param+out + inputs = [] + outputs = [] + par_var = list(set(inps + outs)) + + for v in par_var : #pc+param_names+out_names: + vn = v[:-3] if (len(v)>3 and v not in param_names and v.endswith("_t1")) else v + if vn in inpname: # I suppose that we could not have a current and past state in input and current state in output + input = getInput(mdata, vn) + inputs.append(input) + if vn in outname: + output = getOutput(mdata, vn) + outputs.append(output) + self.model.inputs = inputs + self.model.outputs = outputs + """ + def modelcomposition(self, models, tree, mcdata): + inputlink = [] + outputlink = [] + inp = {} + algo = self.getmethod(tree, "CalculateModel") + self.mc = ModelComposition({"name":mcdata.name, "version":mcdata.version, "timestep":mcdata.timestep}) + self.mc.add_description(mcdata.description) + self.getTypeNode(algo.block,"custom_call") + call = self.getAttNode(self.getTree, **{"function":"CalculateModel"}) + self.mc.model = [c.namespace.name[1:] for c in call] + print("mccccccccccccccccccc") + print(self.mc.model[0]) + inps, outs = [], [] + md = [] + for m in self.mc.model: + for n in models: + if m.lower() == n.name.lower(): + md.append(n) + break + self.mc.model = [n.name for n in md] + inps = [n.name for m in md for n in m.inputs ] + outs = [n.name for m in md for n in m.outputs ] + m_in = set(inps) - set(outs) + z = {} + internallink= [] + inp_=[] + ins_ = [] + for m in md: + vi = list(set([n.name for n in m.inputs ]).intersection(m_in)) + vo = [n.name for n in m.outputs] + for v in vi: + inputlink.append({"target": m.name + "." + v, "source":v}) + inp_.append(v+"_"+m.name) + for v in vo: + z.update({v:m.name}) + #inp_.append(v+"_"+m.name) + + for k, v in z.items(): + outputlink.append({"source": v + "." + k, "target":k}) + for i in range(0, len(md)-1): + mi = md[i] + for j in range(i+1, len(md)): + mj = md[j] + vi = list(set([n.name for n in mi.outputs ]).intersection(set([n.name for n in mj.inputs ]))) + if vi: + for k in vi: + internallink.append({"source": mi.name + "." + k, "target":mj.name + "." + k}) + ins_.append(k+"_"+mj.name) + for m in md: + states_in = [n.name for n in m.inputs if "variablecategory" in dir(n) and n.variablecategory == "state"] + states_out = [n.name for n in m.outputs if n.variablecategory == "state"] + for s_in in states_in: + for s_out in states_out: + if s_in == s_out and s_in + '_' + m.name not in inp_ and s_in + '_' + m.name not in ins_: + inputlink.append({"target": m.name + "." + v, "source":v}) + inp_.append(s_in+"_"+m.name) + + + self.mc.inputlink = inputlink + self.mc.outputlink = outputlink + self.mc.internallink = internallink + """ + + + def modelcomposition(self, models, tree, mcdata): + inputlink = [] + outputlink = [] + inp = {} + algo = self.getmethod(tree, "CalculateModel") + self.mc = ModelComposition({"name":mcdata.name, "version":mcdata.version, "timestep":mcdata.timestep}) + self.mc.add_description(mcdata.description) + self.getTypeNode(algo.block,"custom_call") + call = self.getAttNode(self.getTree, **{"function":"CalculateModel"}) + self.mc.model = [c.namespace.name[1:] for c in call] + inps, outs = [], [] + md = [] + for m in self.mc.model: + for n in models: + if m.lower() == n.name.lower(): + md.append(n) + break + self.mc.model = [n.name for n in md] + inps = [n.name for m in md for n in m.inputs ] + outs = [n.name for m in md for n in m.outputs ] + m_in = set(inps) - set(outs) + z = {} + internallink= [] + inp_=[] + + inputlink = [] + internallink = [] + outputlink = [] + + producer = {} # var -> "ModelUnit.var" (dernier producteur) + inferred_inputs = set() + + consumed = set() + produced = set() + state_outputs = set() + + composite_inputs = None + + # PASS 1: InputLink + InternalLink + producer + for m in md: + # inputs + for inp in m.inputs: + v = inp.name + consumed.add(v) + + if v in producer: + internallink.append({ + "source": producer[v], # ModelA.x + "target": f"{m.name}.{v}" # ModelB.x + }) + else: + inferred_inputs.add(v) + inputlink.append({ + "source": v, # composite input + "target": f"{m.name}.{v}" + }) + + # outputs + for out in m.outputs: + v = out.name + produced.add(v) + + # dernier producteur (pipeline semantics) + producer[v] = f"{m.name}.{v}" + + if getattr(out, "variablecategory", None) == "state": + state_outputs.add(v) + + # PASS 2: composite outputs = sinks U state_outputs (TA règle) + sinks = produced - consumed + composite_outputs = sinks | state_outputs + + # IMPORTANT: on garde uniquement celles qui ont un producteur (donc un ModelUnit source) + composite_outputs = {v for v in composite_outputs if v in producer} + + # PASS 3: OutputLink (toujours depuis un ModelUnit) + for v in composite_outputs: + outputlink.append({ + "source": producer[v], # "ModelUnit.var" + "target": v + }) + self.mc.inputlink = inputlink + self.mc.outputlink = outputlink + self.mc.internallink = internallink + """ + for m in md: + vi = list(set([n.name for n in m.inputs ]).intersection(m_in)) + vo = [n.name for n in m.outputs] + for v in vi: + inputlink.append({"target": m.name + "." + v, "source":v}) + inp_.append(v+"_"+m.name) + for v in vo: + z.update({v:m.name}) + #inp_.append(v+"_"+m.name) + for m in md: + states_in = [n.name for n in m.inputs if "variablecategory" in dir(n) and n.variablecategory == "state"] + states_out = [n.name for n in m.outputs if n.variablecategory == "state"] + for s_in in states_in: + for s_out in states_out: + if s_in == s_out and s_in + '_' + m.name not in inp_: + print("uiiiiiiiiii", m.name, states_in, states_out) + inputlink.append({"target": m.name + "." + v, "source":v}) + inp_.append(s_in+"_"+m.name) + + for k, v in z.items(): + outputlink.append({"source": v + "." + k, "target":k}) + for i in range(0, len(md)-1): + mi = md[i] + for j in range(i+1, len(md)): + mj = md[j] + vi = list(set([n.name for n in mi.outputs ]).intersection(set([n.name for n in mj.inputs ]))) + if vi: + for k in vi: + internallink.append({"source": mi.name + "." + k, "target":mj.name + "." + k}) + + self.mc.inputlink = inputlink + self.mc.outputlink = outputlink + self.mc.internallink = internallink + """ + #n = self.getAttNode(self.getTree,**{'type':'declaration', 'target': Node(type = 'member_access', name= v, member = att, pseudo_type = 'VarInfo')}) + + +def ensure_text(v): + if isinstance(v, bytes): + return v.decode("utf-8") + return v + +def modVal(val): + if val=="-1D": + return "" + return val + +def categorize(cat): + if "state" in cat.lower(): return "state" + if "rate" in cat.lower(): return "rate" + if "auxiliary" in cat.lower(): return "auxiliary" + if "exogenous" in cat.lower(): return "exogenous" + else: return "constant" # TODOOOOOOOOOO + + +def getInput(mdata, name): + for inp in mdata.inputs: + if inp.name == name: + return inp + return None + +def getOutput(mdata, name): + for out in mdata.outputs: + if out.name == name: + return out + return None + + +mapType = {"Integer":"INT", + "Double":"DOUBLE", + "String":"STRING", + "Date":"DATE", + "ListDouble":"DOUBLELIST", + "ListInteger":"INTLIST", + "ListString":"STRINGLIST", + "ListDate":"DATELIST", + "Boolean": "BOOLEAN", + "ArrayDouble":"DOUBLEARRAY", + "ArrayInt":"INTARRAY"} + + + + + + + + + + + + + +''' + +def listdictvalues(dictlist:list) -> list: + """Extract the values of a list of dictionnaries + + Args: + dictlist (list): list of dictionnaries + + Returns: + list: list of values + """ + return [v for d in dictlist for v in d.values()] + +class CsharpExtraction(MetaExtraction): + def __init__(self): + MetaExtraction.__init__(self) + self.model = None + self.mc = None + + + def getAlgo(self, tree): + meth = self.getmethod(tree, "CalculateModel") + if not meth: meth = self.getmethod(tree, "Estimate") + return meth + + def getInit(self, tree): + meth = self.getmethod(tree, "Init") + return meth + + + def orderedvar(self, mdata, tree): + mu_inputs = [m.name for m in tree.params] + mu_outputs = [m.name for m in tree.block[-1].value.elements] + inps = [] + outs = [] + for n in mu_inputs: + for inp in mdata.inputs: + if inp.name == n: + inps.append(inp) + for n in mu_outputs: + for out in mdata.outputs: + if out.name == n: + outs.append(out) + mdata.inputs = inps + mdata.outputs = outs + return mdata + + + def modelcomposition(self, file, models, tree): + self.mc = extract_compo(file) + self.getTypeNode(tree, "function_definition") + mc_def_tree = self.getTree + mc_inputs = [m.name for m in mc_def_tree[0].params] + mc_outputs = [m.name for m in mc_def_tree[0].block[-1].value.elements] + self.getTypeNode(mc_def_tree[0].block, "assignment") + list_assign = self.getTree + inputlink = [] + outputlink = [] + internallink = [] + inp = {} + funcs = self.getMethod(tree) + algo = [f for f in funcs if f.name.startswith("model")] + self.getTypeNode(algo[0].block,"custom_call") + call = self.getTree + self.mc.model = [c.function.split("model_")[-1] for c in call] + inps, outs = [], [] + md = [n for m in self.mc.model for n in models if m.lower() == n.name.split("model_")[-1].lower()] + self.mc.model = [n.name for n in md] + inps = {m.name:[n.name for n in m.inputs] for m in md} + outs = {m.name:[n.name for n in m.outputs] for m in md} + var_int = [] + var_out = [] # variables that are outputs of model units + len_r = len(md) - 1 if len(md) > 1 else len(md) + res_in = {} + res_out = {} + for i in range(0, len_r): + mi = md[i] + mi_inp = inps[mi.name] + mi_out = outs[mi.name] + mi_inp_p = set(mi_inp).intersection(set(mc_inputs)) # inputs of mi that are also inputs of the model composition + mi_out_p = set(mi_out).intersection(set(mc_outputs)) # outputs of mi that are also outputs ... + mi_inp_f = mi_inp_p - set(var_out) # inputs of mi that are not outputs of the previous model units + if len(md) > 1: + for j in range(i+1, len_r+1): + mj = md[j] + mj_inp = inps[mj.name] + zi = list(mi_out.intersection(set(mj_inp))) + var_int.extend(list(zi)) + for k in zi: + internallink.append({"source": mi.name + "." + k, "target":mj.name + "." + k}) + var_out.extend(mi_out) + mi_out_f = mi_out_p - set(var_int) # outputs of mi that are not used as intermediate variables are considered as outputs of the model composition + res_in.update({mi.name:mi_inp_f}) + res_out.update({mi.name:mi_out_f}) + + for k in mc_inputs: + for m in md: + if k in res_in[m.name]: + inputlink.append({"target": m.name + "." + k, "source":k}) + for k in mc_outputs: + for m in md: + if k in res_out[m.name]: + outputlink.append({"source": m.name + "." + k, "target":k}) + + ilink = {} + for a in list_assign: + if "name" in dir(a.value) and a.value.name in mc_inputs: + for m in md: + if a.target.name in inps[m.name]: + if a.value.name not in ilink: ilink[a.value.name] = [] + ilink[a.value.name].append({m.name: a.target.name}) + + self.mc.inputlink = inputlink + self.mc.outputlink = outputlink + self.mc.internallink = internallink + return self.mc +''' \ No newline at end of file diff --git a/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py b/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py index 5ad1d50..43297d7 100644 --- a/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py +++ b/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py @@ -885,7 +885,7 @@ def visit_common_member_declaration(self, node,constant_declaration, "block":block, "pseudo_type":["function"]+ps + ["Void"], "non_identifier":self.non_identifier, - "namespace":self.namespace[-1], + "namespace":self.namespace[-1] if self.namespace else None, "class_":self.clas[-1]} return v @@ -1028,7 +1028,7 @@ def visit_typed_member_declaration(self, "block":block, "pseudo_type":["function"] + ps + [typ["pseudo_type"]], "non_identifier":self.non_identifier, - "namespace":self.namespace[-1], + "namespace":self.namespace[-1] if self.namespace else None, "class_":self.clas[-1]} #domain = [a["pseudo_type"] for a in res["params"] if res["params"] ] self.type_env.top["functions"][res["name"]] = [res["return_type"]] @@ -1402,7 +1402,7 @@ def visit_assignment(self, node, unary_expression,assignment_operator,expression z = { 'type': 'assignment', 'target':self.visit(unary_expression), - 'op':assignment_operator, + 'op':str(assignment_operator), 'value': self.visit(expression), 'pseudo_type': 'Void' } @@ -1583,7 +1583,6 @@ def visit_multiplicative_expression(self, node,switch_expression, STAR,DIV,PERCE x['pseudo_type'], y['pseudo_type'])[-1]}, list(args)) def visit_unary_expression(self, node, primary_expression,PLUS,type_, BANG, MINUS,OP_INC,OP_DEC, unary_expression,STAR,TILDE, location): - if primary_expression: z = self.visit(primary_expression) return z @@ -1661,19 +1660,21 @@ def visit_primary_expression(self, node,primary_expression_start,OP_INC,BANG,OP_ m = self.translate(member_access) if isinstance(res, str): res = {"type":"member_access", "name":res, "member":m, "pseudo_type":"unknown"} elif isinstance(res, dict) and "name" in res: res = {"type":"member_access", "name":res["name"], "member":m, "pseudo_type":res["pseudo_type"]} + elif isinstance(res, dict) and "init" in res and "name" not in res: + res = {"type":"member_access", "init":res["init"], "member":m, "pseudo_type":res["pseudo_type"]} elif "class_type" in res: res = {"type":"member_access", "name":res["class_type"], "member":m, "pseudo_type":"unknown"} else: return None - - if res["name"] in CONSTANT_API and res["member"] in CONSTANT_API[res["name"]]: + if "name" in dir(res) and res["name"] in CONSTANT_API and res["member"] in CONSTANT_API[res["name"]]: return CONSTANT_API.get(res["name"]).get(res["member"]) receiver = res["pseudo_type"][0] if isinstance(res["pseudo_type"], list) else res["pseudo_type"] + if "name" in res and res["name"] =="Array" and res["pseudo_type"] is None: + receiver = "array" if isinstance(receiver, dict): receiver = receiver["pseudo_type"] if isinstance(receiver, list): receiver = receiver[0] - m = res["member"] - - if receiver in PROPERTY_API and not method_invocation: + m = res["member"] + if "name" in res and receiver in PROPERTY_API and not method_invocation: rec = {"type":"local", "name": res["name"], "pseudo_type":res["pseudo_type"]} api = PROPERTY_API[receiver].get(m) if not api: @@ -1688,25 +1689,35 @@ def visit_primary_expression(self, node,primary_expression_start,OP_INC,BANG,OP_ return z if method_invocation: - args = self.visit(method_invocation) - + args = self.visit(method_invocation) if member_access: - #m = self.visit(member_access) - #print("inv",location, res, args, m) if isinstance(m, dict) and m["type"] == "method_invocation": return res elif m.find(".") == -1: method = m - receiver = res["name"] + if "name" in res: + receiver = res["name"] + elif "init" in res: + receiver = res["init"] else: method = m.split(".")[-1] receiver = res["name"]+"."+".".join(m.split(".")[:-1]) - receiver_type = self.type_env[receiver] - receiver_type = receiver_type[0] if isinstance(receiver_type, list) else receiver_type - rec = {"type":"local" , "name":receiver, "pseudo_type":self.type_env[receiver]} - - if isinstance(receiver_type, dict): receiver_type=receiver_type["typename"] - + + if isinstance(receiver, str): + receiver_type = self.type_env[receiver] + receiver_type = receiver_type[0] if isinstance(receiver_type, list) else receiver_type + if isinstance(receiver_type, dict) and "typename" in receiver_type: + receiver_type=receiver_type["typename"] + rec = {"type":"local" , "name":receiver, "pseudo_type":self.type_env[receiver]} + + elif "type" in receiver and receiver["type"] == "initCollection": + receiver_type=res["pseudo_type"][0] if isinstance(res["pseudo_type"], list) else res["pseudo_type"] + rec = {"type":receiver_type , "init":receiver, "pseudo_type":res["pseudo_type"]} + receiver = receiver_type + else: + raise PseudoCythonTypeCheckError("Not implemented receiver type , %s"%location[0]) + #else: rec = {"type":"local" , "name":receiver, "pseudo_type":self.type_env[receiver]} + if receiver in FUNCTION_API: api = FUNCTION_API[receiver].get(method) if not api: @@ -1728,9 +1739,9 @@ def visit_primary_expression(self, node,primary_expression_start,OP_INC,BANG,OP_ 'pseudo-cython doesn\'t support %s%s with %d args' % ( receiver, method, len(args)), location, self.lines[location[0]]) - + elif receiver_type in METHOD_API: - api = METHOD_API.get(receiver_type,{}).get(method) + api = METHOD_API.get(receiver_type,{}).get(method) if api: res = api.expand([rec]+ args) if self.assign == False and "message" in res and res["message"] not in ("contains?", "index", "len"): @@ -1889,7 +1900,7 @@ def visit_literal(self, node,boolean_literal,string_literal,INTEGER_LITERAL,REAL if '"' in val: val = val.replace('"', '') val = val.encode('utf-8') - return {'type': 'string', 'value': val, 'pseudo_type': 'string'} + return {'type': 'string', 'value': ensure_text(val), 'pseudo_type': 'string'} if NULL: return {'type':"none", "value":"none", "pseudo_type":"none"} @@ -2048,3 +2059,9 @@ def visit_attribute(self, node, namespace_or_type_name,attribute_argument, locat else: res = {"type":"attribute", "name":type_} return res + + +def ensure_text(v): + if isinstance(v, bytes): + return v.decode("utf-8") + return v \ No newline at end of file diff --git a/src/pycropml/transpiler/antlr_py/csharp/run.py b/src/pycropml/transpiler/antlr_py/csharp/run.py new file mode 100644 index 0000000..e59f6d1 --- /dev/null +++ b/src/pycropml/transpiler/antlr_py/csharp/run.py @@ -0,0 +1,995 @@ +# coding: utf-8 + +from __future__ import absolute_import +from __future__ import print_function +import os +from os.path import isdir +from copy import deepcopy +from typing import * +from path import Path + +import networkx as nx +import itertools + +from pycropml.transpiler.antlr_py.to_CASG import to_dictASG, to_CASG +from pycropml.transpiler.antlr_py.csharp.csharpExtraction import CsharpExtraction +from pycropml.transpiler.pseudo_tree import Node +from pycropml.transpiler.antlr_py.csharp import cs_cyml +from pycropml.transpiler.generators.cymlGenerator import CymlGenerator +from pycropml.transpiler.ast_transform import transform_to_syntax_tree +from pycropml.transpiler.antlr_py.generateCyml import writeCyml +from pycropml.transpiler.antlr_py.createXml import Pl2Crop2ml +from pycropml.transpiler.antlr_py import repowalk + +from pycropml.transpiler.antlr_py.csharp.csharp_preprocessing import * +from pycropml.transpiler.antlr_py.codeExtraction import extraction +from pycropml.transpiler.antlr_py.extract_metadata_from_comment import extract +from pycropml.transpiler.antlr_py.api_declarations import Middleware +from pycropml.transpiler.antlr_py.to_specification import extractMetaInfo, createObjectModel, extractcomments, createObjectCompo + +from copy import deepcopy, copy + +description_tags = ["//%%CyML Description Begin%%", "//%%CyML Description End%%"] + + +""" Read BioMA component and extract metadata + +""" + +type_={ + "DOUBLE":"double", + "INT":"int", + "STRING":"string", + "DATE":"date", + "DOUBLELIST":"List", + "INTLIST":"List", + "STRINGLIST":"List", + "DATELIST":"List", + "BOOLEAN":"bool", + "DOUBLEARRAY":"array", + "INTARRAY":"array", + "STRINGARRAY":"array"} + +pseudo_type_={ + "DOUBLE":"double", + "INT":"int", + "STRING":"string", + "DATE":"date", + "DOUBLELIST":["List", "double"], + "INTLIST":["List", "int"], + "STRINGLIST":["List", "string"], + "DATELIST":["List", "date"], + "BOOLEAN":"bool", + "DOUBLEARRAY":["array", "double"], + "INTARRAY":["array", "int"], + "STRINGARRAY":["array", "string"]} + + +class Custom_call2(Middleware): + + def __init__(self, vars, extfunc = [], not_declared={}, ext_func_inout={}, member_category={}): + self.vars = vars + self.extfunc = extfunc + self.not_declared = not_declared + self.ext_func_inout = ext_func_inout + self.member_category = member_category + Middleware.__init__(self) + + def process(self, tree): + return self.transform(tree,in_block=False) + + def action_custom_call(self, tree): + method = tree.function + if "namespace" in dir(tree): + namespace = tree.namespace + name = namespace.name + args = tree.args + receiver_type = namespace.pseudo_type + rec = {"type":"local", "name":name, "pseudo_type":receiver_type} + receiver_type = receiver_type[0] if isinstance(receiver_type, list) else receiver_type + if receiver_type in METHOD_API: + api = METHOD_API.get(receiver_type,{}).get(method) + if api: + tree = api.expand([rec]+ args) + if "message" in tree and tree["message"] not in ("contains?", "index", "copyto"): + tree = transform_to_syntax_tree({"type": 'ExprStatNode', 'expr': tree}) + else: + return tree + if not api: + raise translation_error('CyMLT doesn\' t support %s %s ' % (receiver_type, method), + suggestions='CyMLT supports those %s functions\n %s' % ( + name, prepare_table(TYPED_API[receiver_type], ORIGINAL_METHODS.get(receiver_type)).strip())) + if self.extfunc: + for f in self.extfunc: + if f.name == method: + trees = copy(tree) + args = [] + z = CsharpExtraction() + inps = self.ext_func_inout[f.name]["inputs"] + if not isinstance(inps, list): inps = [inps] + meth_member_category = self.member_category[f.name] + if meth_member_category: + for num, arg in enumerate(tree.args): + if isinstance(arg.pseudo_type, Node) : + restricted_inputs = [ins for ins in inps if ("position_args" in dir(ins) and ins.position_args == num+1)] + for k in restricted_inputs: + k.type = "local" + args.append(k) + else: + args.append(arg) + if args: tree.args = args + + if len(trees.args) != len(inps): + trees.args.extend(inps[len(trees.args):]) + for num1, ar1 in enumerate(trees.args): + for num2, ar2 in enumerate(inps): + if num1 == num2: + if ((ar1.type == "int" ) or (ar1.type=="local" and ar1.pseudo_type=="int")) and ar2.pseudo_type in ["float", "double"] : + trees.args[num1] = Node(type="standard_method_call", receiver=trees.args[num1], args=[], message="float", pseudo_type="float") + + outs = deepcopy(self.ext_func_inout[f.name]["outputs"]) + if outs: + if outs.type=="local" and "pos" in dir(outs): + reso = copy(outs) + reso.name = trees.args[outs.pos].name + res = transform_to_syntax_tree({"type": 'assignment', "target":reso,'op':"=", 'value': trees}) + return res + else: + if outs.type == "Tuple": + reso = deepcopy(outs) + for j, o in enumerate(reso.elements): + if "pos" in dir(o): + reso.elements[j].name = copy(trees.args)[o.pos].name + return transform_to_syntax_tree({"type": 'assignment', "target":reso,'op':"=", 'value': trees}) + else: + return transform_to_syntax_tree({"type": 'assignment', "target":outs,'op':"=", 'value': trees}) + z.getTypeNode(f, "implicit_return") + if not z.getTree: + print("TODODODODODODO") + return transform_to_syntax_tree({"type": 'ExprStatNode', 'expr': trees}) + return self.transform_default(tree) + + +class CheckingInOut2(Middleware): + + """_summary_ + This code defines a middleware class called "CheckingInOut" + that checks the inputs and outputs of a given code block. + It does this by keeping track of the current scope and environment, + and adding any new variables to the environment. + It also keeps track of the inputs and outputs of the code block + by checking if a variable is already in the current scope or not. + The middleware class has methods for different types of statements + and expressions, such as assignment, if statements, for loops, and function calls. + The purpose of this middleware is to ensure that the inputs and outputs + of a code block are well-defined and can be used by other parts of a program. + """ + + def __init__(self, env_init=None, isAlgo=False): + if env_init is None: + self.env_init = {} + self.env_init = env_init + self.env = [self.env_init] + self.current_scope = {} + self.if_scope = None + self.isAlgo = isAlgo + self.inputs = [] + self.outputs = [] + self.newdecl = [] + Middleware.__init__(self) + + def process(self, tree): + self.current_scope = self.current() + #self.name = tree.name + return self.transform(tree,in_block=False) + + def current(self): + return {k: v for d in self.env for k, v in d.items()} + + def workflow(self, tree): + self.env.append({}) + r = self.transform_default(tree) + self.env.pop() + self.current_scope = self.current() + return r + + def action_assignment(self, tree): + self.transform(tree.value) + if tree.target.type == "local": + t_name = tree.target.name + type_ = tree.target.pseudo_type + if t_name not in self.current_scope and not self.isAlgo: # self.env[-1] + #self.inputs.append(t_name) + + self.newdecl.append({t_name:type_}) + + self.env[-1][t_name] = type_ + self.outputs.append(t_name) + + elif "sequence" in dir(tree.target): + t_name = tree.target.sequence.name + type_ = tree.target.sequence.pseudo_type + if t_name not in self.current_scope and not(isinstance(type_, list) and type_[0]=="array"): + self.inputs.append(t_name) + self.env[-1][t_name] = type_ + self.outputs.append(t_name) + elif tree.target.type == "sliceindex": + t_name = tree.target.receiver.name + type_ = tree.target.receiver.pseudo_type + if t_name not in self.current_scope: + self.inputs.append(t_name) + self.env[-1][t_name] = type_ + self.outputs.append(t_name) + else: + for elem in tree.target.elements: + t_name = elem.name if "name" in dir(elem) else elem.sequence.name + type_ = elem.pseudo_type + self.outputs.append(t_name) + self.env[-1][t_name] = type_ + + + if "op" in dir(tree) and tree.op != "=": + if t_name not in self.current_scope: + self.inputs.append(t_name) + + self.current_scope = self.current() + return tree + + '''def action_member_access(self, tree): + newvar = tree.name + "_" + tree.member + tree = Node(type="local", name=newvar, pseudo_type=tree.pseudo_type) + if tree.name not in self.current_scope:# and tree.name not in self.outputs: + self.inputs.append(tree.name) + self.env[-1][tree.name] = tree.type + self.current_scope = self.current() + return tree''' + + def action_custom_call(self, tree): + if "namespace" in dir(tree): + self.transform(tree.namespace) + for arg in tree.args: + self.transform(arg) + return tree + + def action_standard_method_call(self, tree): + if isinstance(tree.receiver.pseudo_type, list) and tree.message in ["append", "sum", "remove", "extend", "insert"]: + t_name = tree.receiver.name + if t_name not in self.current_scope: + self.inputs.append(t_name) + self.env[-1][t_name] = tree.receiver.pseudo_type + self.outputs.append(t_name) + self.current_scope = self.current() + self.transform_default(tree) + return tree + + + def action_declaration(self, tree): + for d in tree.decl: + if "value" in dir(d): + self.transform_default(d.value) + self.env[-1][d.name] = d.type + self.current_scope = self.current() + return tree + + + def action_local(self, tree): + if tree.name not in self.current_scope:# and tree.name not in self.outputs: + self.inputs.append(tree.name) + self.env[-1][tree.name] = tree.type + self.current_scope = self.current() + return tree + + def action_if_statement(self, tree): + self.env.append({}) + self.transform(tree.test) + self.transform(tree.block) + m1 = self.env[-1] + self.env.pop() + self.current_scope = self.current() + + if tree.otherwise: + self.env.append({}) + self.transform(tree.otherwise) + m2 = self.env[-1] + self.env.pop() + common_keys = m1.keys( ) & m2.keys() + common_dict = {k:m1[k] for k in common_keys} + self.env[-1].update(common_dict) + self.current_scope = self.current() + return tree + + def action_implicit_return(self, tree): + self.transform(tree.value) + return tree + + def action_binary_op(self, tree): + self.transform(tree.left) + self.transform(tree.right) + return tree + + def action_for_iterator(self, tree): + iterator = tree.iterator.name + if iterator not in self.current_scope: + self.env[-1][iterator] = tree.iterator.pseudo_type + self.current_scope = self.current() + return tree + + def action_for_statement(self, tree): + return self.workflow(tree) + + def action_for_range_statement(self, tree): + return self.workflow(tree) + + def action_while_statement(self, tree): + return self.workflow(tree) + + def action_standard_call(self, tree): + for arg in tree.args: + self.transform(arg) + return tree + + +class Local2(Middleware): + + def __init__(self, declnames=[], params={}): + self.declnames = declnames + self.not_declared=[] + self.params = params + Middleware.__init__(self) + + def process(self, tree): + return self.transform(tree,in_block=False) + + def action_local(self, tree): + if tree.name not in self.declnames: + self.not_declared.append(str(tree.name)) + if tree.name in self.params: + pseudo_type = self.params[tree.name] + tree.pseudo_type = pseudo_type + return tree + +class Member_access2(Middleware): + + def __init__(self, totaltree, prec_cur=[]): + self.totaltree = totaltree + self.members = [] + self.prec_cur = prec_cur + self.m_cat = {} + Middleware.__init__(self) + + def process(self, tree): + return self.transform(tree,in_block=False) + + def test_action_member_access(self, tree): + if "." in tree.member and tree.name + "_" + tree.member.split(".")[0] in self.all_var : + propert = tree.member.split(".")[-1] + name = tree.name + "_" + tree.member.split(".")[0] + type_ = pseudo_type[self.all_var[name]] + if isinstance(type_, list): + type_ = type_[0] + pseudo_type = self.all_var[name] + if type_ in PROPERTY_API: + rec = {"type":"local", "name": name, "pseudo_type":pseudo_type} + api = PROPERTY_API[type_].get(propert) + if not api: + raise PseudoCythonTypeCheckError("Not implemented property , %s"%propert) + + elif not isinstance(api, dict): + z = api.expand([rec]) + return transform_to_syntax_tree(z) + member = tree.member.replace(".", "_") + name = tree.name + "_" + member + pseudo = tree.pseudo_type + tree.name = name + self.members.append(tree) + # retrieve the class name + # retrieve the corresponding node in the totaltree + # dtype: retrieve the datatype wwith the variable name + # return {"type":"local", "name":name, "pseudo_type":dtype} + if pseudo is None: + return Node(type="local", name= name) + else: + return Node(type = "local", name =name, pseudo_type = pseudo_type_[self.all_var[name]]) + + def action_member_access(self, tree): + name = tree.member + if "." in name: + name = name.split('.')[0] + print("member accessssssssssssssssssssssss", tree.y) + pseudo = tree.pseudo_type + self.members.append(tree) + # retrieve the class name + # retrieve the corresponding node in the totaltree + # dtype: retrieve the datatype wwith the variable name + # return {"type":"local", "name":name, "pseudo_type":dtype} + if pseudo is None: + return Node(type="local", name= tree.member.split(".")[-1]) + classname = pseudo.pseudo_type if isinstance(pseudo, Node) else pseudo + z = BiomaExtraction() + z.getTypeNode(self.totaltree, "classDef") + classNode = [m for m in z.getTree if m.name == classname] + z.getTypeNode(classNode[0], "propertyDef") + propNode = [m for m in z.getTree if m.name == name] + + if not propNode: return Node(type = "local", name =name, pseudo_type = pseudo) + + pseudo_prop = propNode[0].pseudo_type + if isinstance(pseudo_prop, Node): + pseudo_type = pseudo_prop.pseudo_type + else: + pseudo_type = pseudo_prop + if isinstance(pseudo_type, list): + type_ = pseudo_type[0] + else: type_ = pseudo_type + + if "." in tree.member: + v = tree.member.split('.') + propert = v[1] + name = from_attr_to_var(tree.name, v[0], self.prec_cur) + self.m_cat[name] = tree.name + if type_ in PROPERTY_API: + rec = {"type":"local", "name": name, "pseudo_type":pseudo_type} + api = PROPERTY_API[type_].get(propert) + if not api: + raise PseudoCythonTypeCheckError("Not implemented property , %s"%propert) + + elif not isinstance(api, dict): + z = api.expand([rec]) + return transform_to_syntax_tree(z) + else: + if self.prec_cur: + name = from_attr_to_var(tree.name, tree.member, self.prec_cur) + self.m_cat[name] = tree.name + else: name = tree.member + return Node(type = "local", name =name, pseudo_type = pseudo_type) + + return tree + +class For_statement2(Middleware): + + def __init__(self): + Middleware.__init__(self) + self.declared = [] + + def process(self, tree): + return self.transform(tree,in_block=False) + + def action_for_statement(self, tree): + """_summary_ + + {'type': 'for_sequence', + 'sequence': {'type': 'local', 'name': 'soilConstituentNames', 'pseudo_type': ['array', 'string']}}, + 'iterators': {'type': 'for_iterator', + 'iterator': {'type': 'local', 'name': 'constituentName', 'pseudo_type': 'var'}} + """ + if tree.sequences.sequence.type == "ExprStatNode": + if tree.sequences.sequence.expr.type == "standard_method_call" and tree.sequences.sequence.expr.message == "except": + tree = Node(type="for_statement", + sequences=Node(type='for_sequence', + sequence = tree.sequences.sequence.expr.receiver), + iterators=tree.iterators, + block=Node(type ='if_statement', + test = Node(type ='standard_method_call', + receiver = Node(type = "List", + pseudo_type = ["List",tree.sequences.sequence.expr.args[0].pseudo_type[-1]], + elements = [r.init.value[0] for r in tree.sequences.sequence.expr.args]), + message ='not contains?', + args =[tree.iterators.iterator], + pseudo_type = 'Boolean'), + block = tree.block, + otherwise = [])) + + + iterator_pseudo_type = tree.iterators.iterator.pseudo_type + if iterator_pseudo_type == "var": + tree.iterators.iterator.pseudo_type = tree.sequences.sequence.pseudo_type[-1] + self.declared.append(tree.iterators.iterator.name) + return tree + +def create_package(output): + crop2ml_rep = Path(os.path.join(output, 'crop2ml')) + if not isdir(crop2ml_rep): + crop2ml_rep.mkdir() + algo_rep = Path(os.path.join(crop2ml_rep, 'algo')) + if not isdir(algo_rep): + algo_rep.mkdir() + cyml_rep = Path(os.path.join(algo_rep, 'pyx')) + if not isdir(cyml_rep): + cyml_rep.mkdir() + return crop2ml_rep, cyml_rep + + + + +def function_dependency(st, f): + r = [f] + z = CsharpExtraction() + while True: + f = f if isinstance(f, list) else [f] + f_exts = [z.externFunction(st, n, False, n.name) for n in f] + exts = list(itertools.chain(*f_exts)) + exs = [i for i in exts if i ] + if exs: + for ex in exs: + r.append(ex) + f = exs + else: + break + return r + + + + + +def redefine_params(m:Node, var_:Dict, member_category, inputs, outputs, extfunc, instance_dclass)->List[Node]: + """It allows to change all parameters which are instance of domain class with the explicit attributes required + + Args: + m (Node): Auxiliary function ASG + var_ (dict): Metadata from strategy classes and varinfo files: (inputs, parameters, outputs) + member_category (_type_): _description_ + inputs (List[str]): Parameter names of the auxiliary function. It can be an instance of domain class + + Returns: + List[Node]: New parameters nodes + """ + res = [] + name = m.name + inputs_p_node = [] + outputs_p_node = [] + inps = list(set(inputs)) + pseudo_name = [] + pos = 0 + reso = [] + inpnames = {p.name:p.pseudo_type for p in m.params} + for p in m.params: + pos = pos + 1 + if p.pseudo_type not in list(pseudo_type_.values()) : + pseudo = p.pseudo_type.pseudo_type if isinstance(p.pseudo_type, Node) else p.pseudo_type + pseudo_name.append(pseudo) + # find the inputs whose instance is p.name + inputs_p = [key for key, val in member_category[name].items() if val==p.name] + #inputs_p = inps + # find its datatype + for p_ in inps: + if p_ in inputs_p: + vn = p_[:-3] if (len(p_)>3 and p_.endswith("_t1")) else p_ + for k, m_inp in var_.items(): + if k == vn or (k == p_): + inputs_p_node.append(Node(type=type_[m_inp['ValueType']], name=p_, pseudo_type=pseudo_type_[m_inp['ValueType']], position_args = pos)) + res.append(name) + break + else: + indice = 1 if pseudo_name.count(pseudo)>1 else 0 + for f in extfunc: + test = False + dclass = deepcopy(instance_dclass[f.name]) + meth_member_category = member_category[f.name] + if meth_member_category: + var = dclass[pseudo][indice] + inputs_names = [key for key, val in meth_member_category.items() if val==var] + if p_ in inputs_names: + vn = p_[:-3] if (len(p_)>3 and p_.endswith("_t1")) else p_ + for k, m_inp in var_.items(): + if k == vn or (k == p_): + test = True + res.append(name) + inputs_p_node.append(Node(type=type_[m_inp.datatype], name=p_, pseudo_type=pseudo_type_[m_inp.datatype], position_args = pos)) + break + if test: break + else: + if p.name not in res and p.name in inputs: + inputs_p_node.append(p) + res.append(p.name) + if isinstance(p.pseudo_type, list) and p.pseudo_type[0] in ("array", "List", "list") and p.name in outputs and p.name not in reso: + outputs_p_node.append(Node(type= "local", name=p.name, pseudo_type=p.pseudo_type)) + reso.append(p.name) # This case because in C# an input with datatype list or array is passed by reference + + + outs = list(set(outputs)) + for p_ in outs: + vn = p_[:-3] if (len(p_)>3 and p_.endswith("_t1")) else p_ + for k, m_inp in var_.items(): + if (k == vn or (k == p_)) and p_ not in reso: + outputs_p_node.append(Node(type= "local", name=p_, pseudo_type=pseudo_type_[m_inp.datatype])) + reso.append(p_) + break + if p_ not in reso and p_ in inpnames: + outputs_p_node.append(Node(type= "local", name=p_, pseudo_type=inpnames[p_])) + reso.append(p_) + return inputs_p_node, outputs_p_node + + + + + +from collections import defaultdict + +def inst_dclass(meth): + params = meth.params + lst = [] + for p in params: + if isinstance(p.pseudo_type, Node) and "typename" in dir(p.pseudo_type): + pname = str(p.name) + lst.append((p.pseudo_type.pseudo_type, pname)) + elif isinstance(p.pseudo_type, str): + lst.append((p.pseudo_type, str(p.name))) + else: + lst.append((p.pseudo_type[1].upper() + p.pseudo_type[0].upper(), str(p.name))) + + orDict = defaultdict(list) + # iterating over list of tuples + for key, val in lst: + orDict[key].append(val) + dclassdict = dict(orDict) + return dclassdict + + + + +def translate(total_tree, varinfo, algo, not_declared, res_inout={}, member_category={}, pa={}): + """Transform specific nodes based on class of subnodes of node. It also allows to extract some usefull information. At finish + the modified node contains only the constructs of CyML and converted in CyML after applying translate_simple function. + + Args: + total_tree (Node): ASG of all the component + varinfo (Node): ASG of the Var info files + + Returns: + ASG: transform algo + """ + z = CsharpExtraction() + funcs = z.externFunction(total_tree, algo) + funcs = [f for f in funcs if f] + + rr1 = Member_access2(total_tree, varinfo) + vv1 = rr1.process(algo) + + rr1_ = Local2(params=pa) + vv1_ = rr1_.process(vv1) + + ri2 = Index() + vi2= ri2.process(vv1_) + + rr2 = Binary_op() + vv2= rr2.process(vi2) + + rr3 = Assignment() + vv3 = rr3.process(vv2) + + rr = Declarations() + vv = rr.process(vv3) + + rr4 = Custom_call2(total_tree, funcs, not_declared, res_inout, member_category) + vv4 = rr4.process(vv) + + expr = ExprStatNode(funcs, res_inout) + expr_ = expr.process(vv4) + + return rr, expr_ + + +def translate_(f, pa): + res = [] + res_ = [] + dr = Declarations() + dv = dr.process(f) + lr = Local(dr.declnames) + lv = lr.process(dv) + params = [str(p.name) for p in f.params] + args = params + dr.declnames + not_declared = list(set(lr.not_declared) - set(args)) + for n in not_declared: + for m in pa: + if m["Name"].decode("utf-8") == n: + r = Node(type=type_[m['ValueType']], name=n, pseudo_type=pseudo_type_[m['ValueType']]) + res.append(r) + r.type = "local" + res_.append(r) + break + return lv, dr.declarations, res_ + +def run_csharp(component, output): + """Transform a CSharp component in Crop2ML + + Args: + component (_type_): csharp component path + output (_type_): Crop2ML package path + """ + crop2ml_rep, cyml_rep = create_package(output) + + pkg = os.path.split(component)[-1].replace('-', '_') + + files = repowalk.walk(component, "cs" ) + res = {} + stra = {} + straNames = [] + varinfo = {} + dclass = [] + compo = {} + source_codes=[] + compo_codes = [] + for k, v in files.items(): + with open(v, 'r') as f: + code = f.read() + if code : + if code.startswith(""): code = code[3:] + splitcode = code.split('\n') + zz = map(lambda x: x.lstrip(), splitcode) + codelist = [n for n in zz if not n.startswith("#") ] + code = "\n".join(codelist) + dictasgt = to_dictASG(code,"cs") + strAsg = to_CASG(dictasgt) + res[k] = strAsg + print("Processing file:", v) + print("===================================" ) + m = CsharpExtraction() + m.getTypeNode(strAsg, "classDef") + g= m.getTree + n = m.getmethod( g, "CalculateModel") + if n: + if "Component" in v.split(os.sep)[-1]: + compo[k] = strAsg + compo_codes.append(code) + else: + stra[k]=strAsg + straNames.append(g[0].name) + source_codes.append(code) + total_tree = list(res.values()) + #vinfo = list(varinfo.values()) + strats = list(stra.values()) + compos = list(compo.values()) + models = [] + func_names = [] + kk = CsharpExtraction() + all_var = kk.getAllVar(source_codes) + for k, st in enumerate(strats): + print(k, st) + mod = source_codes[k] + z = CsharpExtraction(code=mod) + var = z.totalvar(st) + algo = z.getAlgo(st) + init_ = z.getInit(st) + funcs = z.externFunction(st, algo.block + init_.block, False) + funcs = [f for f in funcs if f] + commentsPart = extraction(mod, description_tags[0], description_tags[1]) + mdata = extract(commentsPart[0]+"\n\n") + strat_var = z.getStrategyVar() + pa = strat_var[0] + dict_pa = {f.name:f for f in pa} + all_var_pa = {**dict_pa, **all_var} # all the variable from all varinfo files and parameters of the specific strategy. + #pa = mdata.inputs + params_not_declared = {} + params_not_declared_ = {} + decl = {} + member_category = {} # member_category[func1] = {member1:instance1, member2: instance1, ...} + + res_inout = {} + instance_dclass = {} + + if funcs: + for f in funcs: + r = [] + # order of function dependency + f_dep = function_dependency(st, f) + dep_ = list(reversed(f_dep)) + dep = [] + dep_names = [] + for d in dep_: + if d.name not in dep_names: + dep.append(d) + dep_names.append(d.name) + for ex in dep: # dep is the list of external function in the order of dependency + if ex.name not in func_names: # to avoid duplicating dependent functions in different auxiliary functions + func = z.externFunction(total_tree, ex, False, ex.name) + extfunc = [p for p in func if p] + if extfunc and isinstance(extfunc[0], list): + extfunc = list(itertools.chain(*extfunc)) + for rr in extfunc: + if ex.class_!= rr.class_: + rr.name = "_" + rr.class_ + "__" + rr.name +"_" + params_not_declared[rr.name] = [] + res = [] + res_ = [] + res_inout[ex.name] = {"inputs":None, "outputs":None} + dclassdict = inst_dclass(ex) + f_rr1 = Member_access2(total_tree, dclassdict) + f_vv1 = f_rr1.process(ex) + member_category[ex.name] = f_rr1.m_cat + ri2 = Index() + vi2= ri2.process(f_vv1) + dr = Declarations() + dv = dr.process(vi2) + lr = Local2(dr.declnames) + lv = lr.process(dv) + params = [str(p.name) for p in lv.params] + args = params + dr.declnames + not_declared = list(set(lr.not_declared) - set(args)) + for n in not_declared: + for m in pa: + if m.name.encode("utf-8") == n: + tt = Node(type=type_[m.datatype], name=n, pseudo_type=pseudo_type_[m.datatype]) + res.append(tt) + tt.type = "local" + res_.append(tt) + break + + params_names_not_declared = [p.name for p in res] + for fc in extfunc: + params_t = params_not_declared[fc.name] + for p in params_t: + if p.name not in params_names_not_declared: + res.append(p) + res_.append(p) + + params_not_declared[lv.name] = res + params_not_declared_[lv.name] = res_ + decl[lv.name] = dr.declarations + name = lv.name + instance_dclass[name] = inst_dclass(lv) # before changing the signature + lv.params = lv.params + params_not_declared[name] + lv.block.insert(0,decl[name]) + trans_local = TransformLocal(params_not_declared[name]) + r_trans_local = trans_local.process(lv) + rr2 = Binary_op() + vv2= rr2.process(r_trans_local) + rr4 = Custom_call2(total_tree, extfunc, params_not_declared_, res_inout, member_category) + p_cust = rr4.process(vv2) + env = {xx.name:xx.pseudo_type for j in decl[name] for xx in j.decl} + zz = CheckingInOut2(env) + r_ch = zz.process(p_cust) + inputs_p_node, outputs_p_node = redefine_params(p_cust,all_var_pa, member_category,zz.inputs, zz.outputs,extfunc, instance_dclass) + p_cust.params = inputs_p_node + res_inout[name]["inputs"] = inputs_p_node + params = {p.name:p.pseudo_type for p in p_cust.params} + lr = Local2(declnames=[], params=params) + lv = lr.process(p_cust) + outputs_node = outputs_p_node # transform_io(zz.outputs, all_var, True) + newinps = {p.name:i for i,p in enumerate(inputs_p_node)} + if lv.return_type == "Void": + if len(outputs_node) == 1: + lv.return_type = outputs_node[0].pseudo_type + return_ = Node(type = "implicit_return", value = Node(type = "local", pseudo_type = p_cust.return_type, name = outputs_node[0].name)) + if outputs_node[0].name in newinps.keys(): + return_ = Node(type = "implicit_return", value = Node(type = "local", pseudo_type = p_cust.return_type, name = outputs_node[0].name, pos = newinps[outputs_node[0].name])) + else: + lv.return_type = ["Tuple"] + [n.pseudo_type for n in outputs_node] + return_ = Node(type = "implicit_return", value = Node(type = "Tuple", pseudo_type = p_cust.return_type, elements = outputs_node)) + lv.block.append(return_) + res_inout[name]["outputs"] = return_.value + else: + if "modifiers" in dir(lv.block[-1]): + return_ = lv.block[-1].value + if return_.type == "local" and return_.name in newinps.keys(): + elts = [] + elts.append(Node(type = "local", pseudo_type = lv.return_type, name = return_.name, pos = newinps[return_.name])) + for o in outputs_node: + if o.name in newinps.keys() and o.name != return_.name and o.name in all_var and o.name not in dr.declnames: + elts.append(Node(type = "local", pseudo_type = o.pseudo_type, name = o.name, pos = newinps[o.name])) + elif o.name != return_.name and o.name in all_var and o.name not in dr.declnames: + elts.append(o) + if len(elts) == 1: + return_ = elts[0] + else: + return_ = Node(type = "Tuple", pseudo_type = ["Tuple"]+[e.pseudo_type for e in elts], elements = elts) + lv.block[-1] = Node(type = "implicit_return", value = return_) + else: + elts = [] + r_outs = [o.name for o in return_.elements] + for o in outputs_node: + if o.name in r_outs and o.name in newinps.keys(): + elts.append(Node(type = "local", pseudo_type = o.pseudo_type, name = o.name, pos = newinps[o.name])) + elif o.name in r_outs: + elts.append(Node(type = "local", pseudo_type = o.pseudo_type, name = o.name)) + elif o.name not in r_outs: + elts.append(o) + return_ = Node(type = "Tuple", pseudo_type = lv.return_type, elements = elts) + lv.block[-1] = Node(type = "implicit_return", value = return_) + lv.return_type = ["Tuple"] + [n.pseudo_type for n in outputs_node] + res_inout[name]["outputs"] = return_ + r.append(lv) + func_names.append(lv.name) + cd = cs_cyml.Cs_Cyml_ast(r) + h = cd.transform() + nd = transform_to_syntax_tree(h) + code = writeCyml(nd) + filename = Path(os.path.join(cyml_rep, "%s.pyx"%(name))) + with open(filename, "wb") as tg_file: + tg_file.write(code.encode('utf-8')) + + rr, vv = translate(total_tree, z.dclassdict, algo.block, params_not_declared_, res_inout, member_category, dict_pa) + zz = CheckingInOut2( {},isAlgo = True) + r_ch = zz.process(vv) + cd = cs_cyml.Cs_Cyml_ast(rr.declarations + vv, var =var) + h = cd.transform() + nd = transform_to_syntax_tree(h) + code = writeCyml(nd) + + filename = Path(os.path.join(cyml_rep, "%s.pyx"%(straNames[k]))) + with open(filename, "wb") as tg_file: + tg_file.write(code.encode('utf-8')) + + dict_init = {} + inps_init = [] + outs_init = [] + + if init_: + rr_, init_pseudo = translate(total_tree, z.dclassdict, init_.block, params_not_declared_, res_inout, member_category, dict_pa) + dict_init = {} + name_i = "init."+straNames[k] + dict_init["name"] = "init" + dict_init["filename"] = "algo/pyx/" + name_i + ".pyx" + #z.model.initialization = [dict_init] + cd = cs_cyml.Cs_Cyml_ast(rr_.declarations + init_pseudo, var =var) + h = cd.transform() + nd = transform_to_syntax_tree(h) + initcode = writeCyml(nd) + filename = Path(os.path.join(cyml_rep, "init.%s.pyx"%(straNames[k]))) + with open(filename, "wb") as tg_file: + tg_file.write(initcode.encode('utf-8')) + zz2 = CheckingInOut2( {},isAlgo = True) + r_ch = zz2.process(init_pseudo) + inps_init = zz2.inputs + outs_init = zz2.outputs + + inps_str = zz.inputs + inps_init + outs_str = zz.outputs + outs_init + + z.modelunit(mdata, strat_var, all_var_pa,var, list(set(inps_str)), list(set(outs_str))) + z.model.function = [n.name for n in funcs if f] + if dict_init: z.model.initialization = [dict_init] + + models.append(z.model) + + xml_ = Pl2Crop2ml(z.model, "Crop2ML."+pkg).run_unit() + filename = Path(os.path.join(crop2ml_rep, "unit.%s.xml"%(straNames[k]))) + with open(filename, "wb") as xml_file: + #xml_file.write(xml_.unicode(indent=4).encode('utf-8')) + r = '\n' + r += '\n' + r += xml_.unicode(indent=4)#.encode('utf-8') + xml_file.write(r.encode()) + for k, compo in enumerate(compos): + mod = compo_codes[k] + commentsPart = extraction(mod, description_tags[0], description_tags[1]) + mdatac = extract(commentsPart[0]+"\n\n") + z.modelcomposition(models,compo, mdatac) + xml_ = Pl2Crop2ml(z.mc, "Crop2ML."+pkg).run_compo() + name = z.mc.name[:-9] if z.mc.name.endswith("Component") else z.mc.name + filename = Path(os.path.join(crop2ml_rep, "composition.%s.xml"%(name))) + with open(filename, "wb") as xml_file: + #xml_file.write(xml_.unicode(indent=4).encode('utf-8')) + r = '\n' + r += '\n' + r += xml_.unicode(indent=4)#.encode('utf-8') + xml_file.write(r.encode()) + + + +import io + +def is_filehandle(x): + return isinstance(x, io.IOBase) # catches TextIOWrapper, BufferedReader, etc. + +def find_filehandles(obj, path="root", seen=None): + if seen is None: + seen = set() + oid = id(obj) + if oid in seen: + return + seen.add(oid) + + if is_filehandle(obj): + print("FILEHANDLE at", path, "->", repr(obj), "name=", getattr(obj, "name", None)) + return + + # Recurse + if hasattr(obj, "__dict__"): + for k, v in vars(obj).items(): + find_filehandles(v, f"{path}.{k}", seen) + elif isinstance(obj, dict): + for k, v in obj.items(): + find_filehandles(v, f"{path}[{k!r}]", seen) + elif isinstance(obj, (list, tuple, set)): + for i, v in enumerate(obj): + find_filehandles(v, f"{path}[{i}]", seen) diff --git a/src/pycropml/transpiler/antlr_py/csharp/test.ipynb b/src/pycropml/transpiler/antlr_py/csharp/test.ipynb new file mode 100644 index 0000000..8f70a2f --- /dev/null +++ b/src/pycropml/transpiler/antlr_py/csharp/test.ipynb @@ -0,0 +1,316 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "9555e9dd", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35691dd2", + "metadata": {}, + "outputs": [], + "source": [ + "components = \"/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell\"\n", + "from pycropml.transpiler.antlr_py import repowalk\n", + "files = repowalk.walk(components, 'cs')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "7abac7a2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'SoiltempAuxiliary.cs': '/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempAuxiliary.cs',\n", + " 'SoiltempComponent.cs': '/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempComponent.cs',\n", + " 'SoilTemperature.cs': '/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoilTemperature.cs',\n", + " 'SoiltempExogenous.cs': '/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempExogenous.cs',\n", + " 'SoiltempRate.cs': '/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempRate.cs',\n", + " 'SoiltempState.cs': '/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempState.cs',\n", + " 'SoiltempWrapper.cs': '/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempWrapper.cs'}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "files" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e7027473", + "metadata": {}, + "outputs": [], + "source": [ + "from pycropml.transpiler.antlr_py.to_CASG import to_dictASG, to_CASG\n", + "from pycropml.transpiler.antlr_py.csharp.csharpExtraction import CsharpExtraction" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8b23b861", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempAuxiliary.cs\n", + "/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoiltempComponent.cs\n", + "{'type': 'member_access', 'name': '_SoilTemperature', 'member': 'CalculateModel', 'pseudo_type': 'SoilTemperature'} SoilTemperature (346, 8) uuuuuuuuuuuu\n", + "{'type': 'member_access', 'name': '_SoilTemperature', 'member': 'Init', 'pseudo_type': 'SoilTemperature'} SoilTemperature (420, 8) uuuuuuuuuuuu\n", + "/mnt/d/Docs/AMEI_Workshop/AMEI_10_14_2022/Models/ApsimCampbell/src/cs/ApsimCampbell/SoilTemperature.cs\n", + "{'type': 'member_access', 'name': 'Array', 'member': 'ConstrainedCopy', 'pseudo_type': None} None (1317, 17) uuuuuuuuuuuu\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'split'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 8\u001b[39m\n\u001b[32m 6\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(v, \u001b[33m'\u001b[39m\u001b[33mr\u001b[39m\u001b[33m'\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m f:\n\u001b[32m 7\u001b[39m code = f.read()\n\u001b[32m----> \u001b[39m\u001b[32m8\u001b[39m dictasgt = \u001b[43mto_dictASG\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcode\u001b[49m\u001b[43m,\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mcs\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 9\u001b[39m strAsg = to_CASG(dictasgt)\n\u001b[32m 10\u001b[39m res[k] = strAsg \n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/to_CASG.py:34\u001b[39m, in \u001b[36mto_dictASG\u001b[39m\u001b[34m(code, language, comments, env)\u001b[39m\n\u001b[32m 32\u001b[39m tree = parse.parsef(code,language, start=\u001b[33m\"\u001b[39m\u001b[33mcompilation_unit\u001b[39m\u001b[33m\"\u001b[39m, strict=\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[32m 33\u001b[39m ast_proc = simplifyAntlrTree.process_tree(tree,transformer_cls =GENERATORS[language].Transformer )\n\u001b[32m---> \u001b[39m\u001b[32m34\u001b[39m trans = \u001b[43mGENERATORS\u001b[49m\u001b[43m[\u001b[49m\u001b[43mlanguage\u001b[49m\u001b[43m]\u001b[49m\u001b[43m.\u001b[49m\u001b[43mAstTransformer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mast_proc\u001b[49m\u001b[43m,\u001b[49m\u001b[43mcode\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcomments\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43menv\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mtransformer\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 35\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m trans\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:546\u001b[39m, in \u001b[36mAstTransformer.transformer\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 544\u001b[39m \u001b[38;5;28mself\u001b[39m.namespace = []\n\u001b[32m 545\u001b[39m \u001b[38;5;28mself\u001b[39m.top_level(\u001b[38;5;28mself\u001b[39m.tree)\n\u001b[32m--> \u001b[39m\u001b[32m546\u001b[39m body = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mtree\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 547\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m {\u001b[33m'\u001b[39m\u001b[33mbody\u001b[39m\u001b[33m'\u001b[39m: body \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(body, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m [body]}\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:606\u001b[39m, in \u001b[36mAstTransformer.visit_compilation_unit\u001b[39m\u001b[34m(self, node, using_directives, namespace_member_declarations, location)\u001b[39m\n\u001b[32m 604\u001b[39m res2.append(us)\n\u001b[32m 605\u001b[39m u = res2\n\u001b[32m--> \u001b[39m\u001b[32m606\u001b[39m z = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnamespace_member_declarations\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 607\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33mmodule\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 608\u001b[39m \u001b[33m\"\u001b[39m\u001b[33musing\u001b[39m\u001b[33m\"\u001b[39m: u,\n\u001b[32m 609\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mbody\u001b[39m\u001b[33m\"\u001b[39m: z,\n\u001b[32m 610\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33mVoid\u001b[39m\u001b[33m\"\u001b[39m}\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:625\u001b[39m, in \u001b[36mAstTransformer.visit_namespace_member_declarations\u001b[39m\u001b[34m(self, node, namespace_member_declaration, location)\u001b[39m\n\u001b[32m 623\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_namespace_member_declarations\u001b[39m(\u001b[38;5;28mself\u001b[39m,node, namespace_member_declaration, location):\n\u001b[32m--> \u001b[39m\u001b[32m625\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m.\u001b[49m\u001b[43mchildren\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:686\u001b[39m, in \u001b[36mAstTransformer.visit_namespace_member_declaration\u001b[39m\u001b[34m(self, node, namespace_declaration, type_declaration, location)\u001b[39m\n\u001b[32m 684\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_namespace_member_declaration\u001b[39m(\u001b[38;5;28mself\u001b[39m,node, namespace_declaration, type_declaration, location):\n\u001b[32m 685\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m type_declaration:\n\u001b[32m--> \u001b[39m\u001b[32m686\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtype_declaration\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 687\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m namespace_declaration:\n\u001b[32m 688\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.visit(namespace_declaration)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:746\u001b[39m, in \u001b[36mAstTransformer.visit_type_declaration\u001b[39m\u001b[34m(self, node, class_definition, struct_definition, interface_definition, enum_definition, delegate_definition, attributes, all_member_modifiers, location)\u001b[39m\n\u001b[32m 744\u001b[39m name = \u001b[38;5;28mself\u001b[39m.visit(class_definition.identifier)\n\u001b[32m 745\u001b[39m \u001b[38;5;28mself\u001b[39m.clas.append(name)\n\u001b[32m--> \u001b[39m\u001b[32m746\u001b[39m block = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mclass_definition\u001b[49m\u001b[43m.\u001b[49m\u001b[43mclass_body\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 747\u001b[39m res = {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mclassDef\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 748\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mname\u001b[39m\u001b[33m\"\u001b[39m: name,\n\u001b[32m 749\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mbase\u001b[39m\u001b[33m\"\u001b[39m: \u001b[38;5;28mself\u001b[39m.visit(class_definition.class_base) \u001b[38;5;28;01mif\u001b[39;00m class_definition.class_base \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m , \u001b[38;5;66;03m#TODO\u001b[39;00m\n\u001b[32m 750\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mblock\u001b[39m\u001b[33m\"\u001b[39m: block } \n\u001b[32m 751\u001b[39m \u001b[38;5;28mself\u001b[39m.clas.pop()\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:769\u001b[39m, in \u001b[36mAstTransformer.visit_class_body\u001b[39m\u001b[34m(self, node, class_member_declarations, location)\u001b[39m\n\u001b[32m 767\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_class_body\u001b[39m(\u001b[38;5;28mself\u001b[39m, node, class_member_declarations, location):\n\u001b[32m--> \u001b[39m\u001b[32m769\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mclass_member_declarations\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:773\u001b[39m, in \u001b[36mAstTransformer.visit_class_member_declarations\u001b[39m\u001b[34m(self, node, class_member_declaration, location)\u001b[39m\n\u001b[32m 771\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_class_member_declarations\u001b[39m(\u001b[38;5;28mself\u001b[39m, node, class_member_declaration, location):\n\u001b[32m--> \u001b[39m\u001b[32m773\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m.\u001b[49m\u001b[43mchildren\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 775\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 776\u001b[39m \u001b[33;03m z = self.getpath(node, \"typed_member_declaration\")\u001b[39;00m\n\u001b[32m 777\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 792\u001b[39m \u001b[33;03m \u001b[39;00m\n\u001b[32m 793\u001b[39m \u001b[33;03m return self.visit(class_member_declarations.children)\"\"\"\u001b[39;00m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:811\u001b[39m, in \u001b[36mAstTransformer.visit_class_member_declaration\u001b[39m\u001b[34m(self, node, common_member_declaration, destructor_definition, attributes, all_member_modifiers, location)\u001b[39m\n\u001b[32m 809\u001b[39m y = \u001b[38;5;28mself\u001b[39m.visit(attributes)\n\u001b[32m 810\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m common_member_declaration:\n\u001b[32m--> \u001b[39m\u001b[32m811\u001b[39m z = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcommon_member_declaration\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 812\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m z:\n\u001b[32m 813\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m x : z[\u001b[33m\"\u001b[39m\u001b[33mmodifiers\u001b[39m\u001b[33m\"\u001b[39m] = x\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:858\u001b[39m, in \u001b[36mAstTransformer.visit_common_member_declaration\u001b[39m\u001b[34m(self, node, constant_declaration, typed_member_declaration, event_declaration, conversion_operator_declarator, body, right_arrow, throwable_expression, constructor_declaration, VOID, method_declaration, class_definition, struct_definition, interface_definition, enum_definition, delegate_definition, location)\u001b[39m\n\u001b[32m 856\u001b[39m param = \u001b[38;5;28mself\u001b[39m.visit(method_declaration.formal_parameter_list)\n\u001b[32m 857\u001b[39m ps = [p[\u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m] \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m param] \u001b[38;5;28;01mif\u001b[39;00m param \u001b[38;5;28;01melse\u001b[39;00m [\u001b[38;5;28;01mNone\u001b[39;00m]\n\u001b[32m--> \u001b[39m\u001b[32m858\u001b[39m block = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod_declaration\u001b[49m\u001b[43m.\u001b[49m\u001b[43mmethod_body\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 859\u001b[39m modifiers = []\n\u001b[32m 861\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m param:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1924\u001b[39m, in \u001b[36mAstTransformer.visit_ifstatement\u001b[39m\u001b[34m(self, node, expression, if_body, location, ELSE, IF)\u001b[39m\n\u001b[32m 1922\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(if_body)==\u001b[32m1\u001b[39m:\n\u001b[32m 1923\u001b[39m test = \u001b[38;5;28mself\u001b[39m.visit(expression)\n\u001b[32m-> \u001b[39m\u001b[32m1924\u001b[39m block = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mif_body\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1925\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1926\u001b[39m test = \u001b[38;5;28mself\u001b[39m.visit(expression)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1927\u001b[39m, in \u001b[36mAstTransformer.visit_ifstatement\u001b[39m\u001b[34m(self, node, expression, if_body, location, ELSE, IF)\u001b[39m\n\u001b[32m 1925\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1926\u001b[39m test = \u001b[38;5;28mself\u001b[39m.visit(expression)\n\u001b[32m-> \u001b[39m\u001b[32m1927\u001b[39m block = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mif_body\u001b[49m\u001b[43m[\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1928\u001b[39m \u001b[38;5;28;01mwhile\u001b[39;00m(node.ELSE \u001b[38;5;129;01mand\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mIF\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mdir\u001b[39m(node.if_body[\u001b[32m1\u001b[39m])):\n\u001b[32m 1929\u001b[39m z = node.if_body[\u001b[32m1\u001b[39m]\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1468\u001b[39m, in \u001b[36mAstTransformer.visit_expressionstatement\u001b[39m\u001b[34m(self, node, expression, location)\u001b[39m\n\u001b[32m 1467\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_expressionstatement\u001b[39m(\u001b[38;5;28mself\u001b[39m, node, expression, location):\n\u001b[32m-> \u001b[39m\u001b[32m1468\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexpression\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1396\u001b[39m, in \u001b[36mAstTransformer.visit_expression\u001b[39m\u001b[34m(self, node, assignment, non_assignment_expression, location)\u001b[39m\n\u001b[32m 1394\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node, assignment, non_assignment_expression, location):\n\u001b[32m 1395\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m non_assignment_expression:\n\u001b[32m-> \u001b[39m\u001b[32m1396\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnon_assignment_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1397\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m x[\u001b[32m0\u001b[39m] \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m x\n\u001b[32m 1398\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m assignment:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1449\u001b[39m, in \u001b[36mAstTransformer.visit_non_assignment_expression\u001b[39m\u001b[34m(self, node, lambda_expression, query_expression, conditional_expression, location)\u001b[39m\n\u001b[32m 1447\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m lambda_expression: \u001b[38;5;28;01mraise\u001b[39;00m PseudoCythonTypeCheckError(\u001b[33m\"\u001b[39m\u001b[33mNot implemented lambda expression , \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m%location) \n\u001b[32m 1448\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m query_expression: \u001b[38;5;28;01mraise\u001b[39;00m PseudoCythonTypeCheckError(\u001b[33m\"\u001b[39m\u001b[33mNot implemented query_expression , \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[33m\"\u001b[39m%location) \n\u001b[32m-> \u001b[39m\u001b[32m1449\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconditional_expression\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1453\u001b[39m, in \u001b[36mAstTransformer.visit_conditional_expression\u001b[39m\u001b[34m(self, node, null_coalescing_expression, throwable_expression, location)\u001b[39m\n\u001b[32m 1451\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_conditional_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node,null_coalescing_expression,throwable_expression, location):\n\u001b[32m 1452\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m null_coalescing_expression:\n\u001b[32m-> \u001b[39m\u001b[32m1453\u001b[39m res = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnull_coalescing_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1454\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m throwable_expression:\n\u001b[32m 1455\u001b[39m bodyif = \u001b[38;5;28mself\u001b[39m.visit(throwable_expression[\u001b[32m0\u001b[39m])\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1486\u001b[39m, in \u001b[36mAstTransformer.visit_conditional_or_expression\u001b[39m\u001b[34m(self, node, conditional_and_expression, OP_OR, location)\u001b[39m\n\u001b[32m 1480\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_conditional_or_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m,\n\u001b[32m 1481\u001b[39m node, \n\u001b[32m 1482\u001b[39m conditional_and_expression,\n\u001b[32m 1483\u001b[39m OP_OR,\n\u001b[32m 1484\u001b[39m location):\n\u001b[32m 1485\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m: \n\u001b[32m-> \u001b[39m\u001b[32m1486\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconditional_and_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1487\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n\u001b[32m 1488\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m reduceT(\u001b[38;5;28;01mlambda\u001b[39;00m x,y, op: {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mcomparison\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mop\u001b[39m\u001b[33m\"\u001b[39m:op, \u001b[33m\"\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m\"\u001b[39m:x \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m x[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m:y \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(y, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m y[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mbool\u001b[39m\u001b[33m\"\u001b[39m}, \u001b[38;5;28mlist\u001b[39m(args))\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1476\u001b[39m, in \u001b[36mAstTransformer.visit_conditional_and_expression\u001b[39m\u001b[34m(self, node, inclusive_or_expression, OP_AND, location)\u001b[39m\n\u001b[32m 1470\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_conditional_and_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m,\n\u001b[32m 1471\u001b[39m node, \n\u001b[32m 1472\u001b[39m inclusive_or_expression,\n\u001b[32m 1473\u001b[39m OP_AND,\n\u001b[32m 1474\u001b[39m location):\n\u001b[32m 1475\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m: \n\u001b[32m-> \u001b[39m\u001b[32m1476\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43minclusive_or_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1477\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n\u001b[32m 1478\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m reduceT(\u001b[38;5;28;01mlambda\u001b[39;00m x,y, op: {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mcomparison\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mop\u001b[39m\u001b[33m\"\u001b[39m:op, \u001b[33m\"\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m\"\u001b[39m:x \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m x[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m:y \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(y, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m y[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mbool\u001b[39m\u001b[33m\"\u001b[39m}, \u001b[38;5;28mlist\u001b[39m(args))\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1504\u001b[39m, in \u001b[36mAstTransformer.visit_inclusive_or_expression\u001b[39m\u001b[34m(self, node, exclusive_or_expression, BITWISE_OR, location)\u001b[39m\n\u001b[32m 1499\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_inclusive_or_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node,\n\u001b[32m 1500\u001b[39m exclusive_or_expression,\n\u001b[32m 1501\u001b[39m BITWISE_OR,\n\u001b[32m 1502\u001b[39m location):\n\u001b[32m 1503\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m: \n\u001b[32m-> \u001b[39m\u001b[32m1504\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mexclusive_or_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1505\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n\u001b[32m 1506\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m reduceT(\u001b[38;5;28;01mlambda\u001b[39;00m x,y, op: {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mcomparison\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mop\u001b[39m\u001b[33m\"\u001b[39m:op, \u001b[33m\"\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m\"\u001b[39m:x \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m x[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m:y \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m y[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mbool\u001b[39m\u001b[33m\"\u001b[39m}, \u001b[38;5;28mlist\u001b[39m(args))\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1514\u001b[39m, in \u001b[36mAstTransformer.visit_exclusive_or_expression\u001b[39m\u001b[34m(self, node, and_expression, CARET, location)\u001b[39m\n\u001b[32m 1508\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_exclusive_or_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, \n\u001b[32m 1509\u001b[39m node,\n\u001b[32m 1510\u001b[39m and_expression,\n\u001b[32m 1511\u001b[39m CARET,\n\u001b[32m 1512\u001b[39m location):\n\u001b[32m 1513\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m: \n\u001b[32m-> \u001b[39m\u001b[32m1514\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mand_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1515\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n\u001b[32m 1516\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m reduceT(\u001b[38;5;28;01mlambda\u001b[39;00m x,y, op: {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mcomparison\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mop\u001b[39m\u001b[33m\"\u001b[39m:op, \u001b[33m\"\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m\"\u001b[39m:x \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m x[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m:y \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m y[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mbool\u001b[39m\u001b[33m\"\u001b[39m}, \u001b[38;5;28mlist\u001b[39m(args))\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1524\u001b[39m, in \u001b[36mAstTransformer.visit_and_expression\u001b[39m\u001b[34m(self, node, equality_expression, AMP, location)\u001b[39m\n\u001b[32m 1518\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_and_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, \n\u001b[32m 1519\u001b[39m node,\n\u001b[32m 1520\u001b[39m equality_expression,\n\u001b[32m 1521\u001b[39m AMP,\n\u001b[32m 1522\u001b[39m location ):\n\u001b[32m 1523\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m: \n\u001b[32m-> \u001b[39m\u001b[32m1524\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mequality_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1525\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n\u001b[32m 1526\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m reduceT(\u001b[38;5;28;01mlambda\u001b[39;00m x,y, op: {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mcomparison\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mop\u001b[39m\u001b[33m\"\u001b[39m:op, \u001b[33m\"\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m\"\u001b[39m:x \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m x[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m:y \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m) \u001b[38;5;28;01melse\u001b[39;00m y[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mbool\u001b[39m\u001b[33m\"\u001b[39m}, \u001b[38;5;28mlist\u001b[39m(args))\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1530\u001b[39m, in \u001b[36mAstTransformer.visit_equality_expression\u001b[39m\u001b[34m(self, node, relational_expression, OP_EQ, OP_NE, location)\u001b[39m\n\u001b[32m 1528\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_equality_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node, relational_expression, OP_EQ,OP_NE,location):\n\u001b[32m 1529\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m: \n\u001b[32m-> \u001b[39m\u001b[32m1530\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrelational_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1531\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n\u001b[32m 1532\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m reduceT(\u001b[38;5;28;01mlambda\u001b[39;00m x,y, op: {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mcomparison\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mop\u001b[39m\u001b[33m\"\u001b[39m:op, \u001b[33m\"\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m\"\u001b[39m:x[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m:y[\u001b[32m0\u001b[39m], \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mbool\u001b[39m\u001b[33m\"\u001b[39m}, \u001b[38;5;28mlist\u001b[39m(args))\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1544\u001b[39m, in \u001b[36mAstTransformer.visit_relational_expression\u001b[39m\u001b[34m(self, node, shift_expression, LT, GT, OP_LE, OP_GE, IS, isType, AS, type_, location)\u001b[39m\n\u001b[32m 1542\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m {\u001b[33m\"\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33misExpression\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mleft\u001b[39m\u001b[33m\"\u001b[39m: left, \u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m:right, \u001b[33m\"\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m\"\u001b[39m:\u001b[33m\"\u001b[39m\u001b[33mVoid\u001b[39m\u001b[33m\"\u001b[39m}\n\u001b[32m 1543\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1544\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mshift_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1545\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1546\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1564\u001b[39m, in \u001b[36mAstTransformer.visit_shift_expression\u001b[39m\u001b[34m(self, node, additive_expression, OP_LEFT_SHIFT, right_shift, location)\u001b[39m\n\u001b[32m 1557\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_shift_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, \n\u001b[32m 1558\u001b[39m node,\n\u001b[32m 1559\u001b[39m additive_expression,OP_LEFT_SHIFT,\n\u001b[32m 1560\u001b[39m right_shift,\n\u001b[32m 1561\u001b[39m location):\n\u001b[32m 1563\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1564\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43madditive_expression\u001b[49m\u001b[43m)\u001b[49m[\u001b[32m0\u001b[39m]\n\u001b[32m 1565\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1566\u001b[39m \u001b[38;5;66;03m#op = OP_LEFT_SHIFT if OP_LEFT_SHIFT else right_shift\u001b[39;00m\n\u001b[32m 1567\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1572\u001b[39m, in \u001b[36mAstTransformer.visit_additive_expression\u001b[39m\u001b[34m(self, node, multiplicative_expression, PLUS, MINUS, location)\u001b[39m\n\u001b[32m 1570\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_additive_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node,multiplicative_expression, PLUS,MINUS,location):\n\u001b[32m 1571\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1572\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmultiplicative_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1573\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1574\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1581\u001b[39m, in \u001b[36mAstTransformer.visit_multiplicative_expression\u001b[39m\u001b[34m(self, node, switch_expression, STAR, DIV, PERCENT, location)\u001b[39m\n\u001b[32m 1579\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_multiplicative_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node,switch_expression, STAR,DIV,PERCENT, location):\n\u001b[32m 1580\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1581\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mswitch_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1582\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1583\u001b[39m args = \u001b[38;5;28mmap\u001b[39m(\u001b[38;5;28;01mlambda\u001b[39;00m n:\u001b[38;5;28mself\u001b[39m.visit(n), node.children) \n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1635\u001b[39m, in \u001b[36mAstTransformer.visit_switch_expression\u001b[39m\u001b[34m(self, node, range_expression, SWITCH, switch_expression_arms, location)\u001b[39m\n\u001b[32m 1633\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_switch_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node,range_expression,SWITCH,switch_expression_arms, location):\n\u001b[32m 1634\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1635\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrange_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1636\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1637\u001b[39m lhs = \u001b[38;5;28mself\u001b[39m.visit(range_expression)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1643\u001b[39m, in \u001b[36mAstTransformer.visit_range_expression\u001b[39m\u001b[34m(self, node, unary_expression, OP_RANGE, location)\u001b[39m\n\u001b[32m 1641\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_range_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node,unary_expression,OP_RANGE, location):\n\u001b[32m 1642\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(node.children)==\u001b[32m1\u001b[39m:\n\u001b[32m-> \u001b[39m\u001b[32m1643\u001b[39m res = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43munary_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1644\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m res[\u001b[32m0\u001b[39m]\n\u001b[32m 1645\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:582\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 580\u001b[39m results = []\n\u001b[32m 581\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m node:\n\u001b[32m--> \u001b[39m\u001b[32m582\u001b[39m x = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 583\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(x, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 584\u001b[39m results.extend(x)\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1590\u001b[39m, in \u001b[36mAstTransformer.visit_unary_expression\u001b[39m\u001b[34m(self, node, primary_expression, PLUS, type_, BANG, MINUS, OP_INC, OP_DEC, unary_expression, STAR, TILDE, location)\u001b[39m\n\u001b[32m 1587\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mvisit_unary_expression\u001b[39m(\u001b[38;5;28mself\u001b[39m, node, primary_expression,PLUS,type_, BANG, MINUS,OP_INC,OP_DEC, unary_expression,STAR,TILDE, location):\n\u001b[32m 1588\u001b[39m \u001b[38;5;66;03m#print(location, \"unarrrrrrrrrrrrrrrrrrrrrrrrry\")\u001b[39;00m\n\u001b[32m 1589\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m primary_expression:\n\u001b[32m-> \u001b[39m\u001b[32m1590\u001b[39m z = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mvisit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprimary_expression\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1591\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m z\n\u001b[32m 1592\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m type_: \n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:578\u001b[39m, in \u001b[36mAstTransformer.visit\u001b[39m\u001b[34m(self, node)\u001b[39m\n\u001b[32m 576\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 577\u001b[39m fields[\u001b[33m'\u001b[39m\u001b[33mlocation\u001b[39m\u001b[33m'\u001b[39m] = \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m578\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mvisit_\u001b[39;49m\u001b[38;5;132;43;01m%s\u001b[39;49;00m\u001b[33;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m%\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mtype\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mnode\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[34;43m__name__\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mfields\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;66;03m# [:-7]\u001b[39;00m\n\u001b[32m 579\u001b[39m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(node, \u001b[38;5;28mlist\u001b[39m):\n\u001b[32m 580\u001b[39m results = []\n", + "\u001b[36mFile \u001b[39m\u001b[32m/mnt/d/Docs/PyCropML_Old/src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py:1768\u001b[39m, in \u001b[36mAstTransformer.visit_primary_expression\u001b[39m\u001b[34m(self, node, primary_expression_start, OP_INC, BANG, OP_PTR, identifier, OP_DEC, member_access, method_invocation, bracket_expression, location)\u001b[39m\n\u001b[32m 1766\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m: \n\u001b[32m 1767\u001b[39m \u001b[38;5;28mprint\u001b[39m(res, receiver, location, \u001b[33m\"\u001b[39m\u001b[33muuuuuuuuuuuu\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m-> \u001b[39m\u001b[32m1768\u001b[39m res[\u001b[33m\"\u001b[39m\u001b[33mmember\u001b[39m\u001b[33m\"\u001b[39m] = \u001b[43mreceiver\u001b[49m\u001b[43m.\u001b[49m\u001b[43msplit\u001b[49m(\u001b[33m\"\u001b[39m\u001b[33m.\u001b[39m\u001b[33m\"\u001b[39m)[-\u001b[32m1\u001b[39m]\n\u001b[32m 1769\u001b[39m res = {\u001b[33m'\u001b[39m\u001b[33mtype\u001b[39m\u001b[33m'\u001b[39m: \u001b[33m'\u001b[39m\u001b[33mcustom_call\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mnamespace\u001b[39m\u001b[33m'\u001b[39m: res, \u001b[33m\"\u001b[39m\u001b[33mfunction\u001b[39m\u001b[33m\"\u001b[39m:method, \u001b[33m'\u001b[39m\u001b[33margs\u001b[39m\u001b[33m'\u001b[39m: args, \u001b[33m'\u001b[39m\u001b[33mpseudo_type\u001b[39m\u001b[33m'\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33munknown\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mclass_\u001b[39m\u001b[33m\"\u001b[39m: \u001b[38;5;28mself\u001b[39m.clas[-\u001b[32m1\u001b[39m]} \u001b[38;5;66;03m#TODO \u001b[39;00m\n\u001b[32m 1770\u001b[39m \u001b[38;5;66;03m#if self.assign == False:\u001b[39;00m\n\u001b[32m 1771\u001b[39m \u001b[38;5;66;03m#res = {\"type\": 'ExprStatNode', 'expr': res} \u001b[39;00m\n\u001b[32m 1772\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n", + "\u001b[31mAttributeError\u001b[39m: 'NoneType' object has no attribute 'split'" + ] + } + ], + "source": [ + "stra = {}\n", + "straNames = []\n", + "res = {}\n", + "for k, v in files.items():\n", + " print(v)\n", + " with open(v, 'r') as f:\n", + " code = f.read()\n", + " dictasgt = to_dictASG(code,\"cs\")\n", + " strAsg = to_CASG(dictasgt)\n", + " res[k] = strAsg \n", + " m = CsharpExtraction()\n", + " m.getTypeNode(strAsg, \"classDef\")\n", + " g= m.getTree\n", + " if k==2: print(g) " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a6d5b39f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'type': 'module',\n", + " 'definition': [],\n", + " 'iterators': [],\n", + " 'body': [{'type': 'function_definition',\n", + " 'name': 'toto',\n", + " 'params': [{'name': 'x', 'type': 'int', 'pseudo_type': 'int'}],\n", + " 'pseudo_type': ['Function', 'int', ['list', 'int']],\n", + " 'return_type': ['list', 'int'],\n", + " 'block': [{'type': 'declaration',\n", + " 'decl': [{'name': 'b',\n", + " 'type': 'list',\n", + " 'lineno': (3, 9),\n", + " 'pseudo_type': ['list', 'int']}]},\n", + " {'type': 'declaration',\n", + " 'decl': [{'name': 'i',\n", + " 'type': 'int',\n", + " 'lineno': (4, 9),\n", + " 'pseudo_type': 'int'}]},\n", + " {'type': 'assignment',\n", + " 'target': {'type': 'local', 'name': 'b', 'pseudo_type': ['list', 'int']},\n", + " 'value': {'type': 'list',\n", + " 'pseudo_type': ['list', 'int'],\n", + " 'elements': [{'type': 'int', 'value': '15', 'pseudo_type': 'int'},\n", + " {'type': 'int', 'value': '20', 'pseudo_type': 'int'}]},\n", + " 'pseudo_type': 'Void'},\n", + " {'type': 'assignment',\n", + " 'target': {'type': 'index',\n", + " 'sequence': {'type': 'local',\n", + " 'name': 'b',\n", + " 'pseudo_type': ['list', 'int'],\n", + " 'lineno': (6, 4)},\n", + " 'index': {'type': 'int', 'value': '0', 'pseudo_type': 'int'},\n", + " 'pseudo_type': 'int'},\n", + " 'value': {'type': 'int', 'value': '15', 'pseudo_type': 'int'},\n", + " 'pseudo_type': 'Void'},\n", + " {'type': 'ExprStatNode',\n", + " 'expr': {'type': 'standard_method_call',\n", + " 'receiver': {'type': 'local',\n", + " 'name': 'b',\n", + " 'pseudo_type': ['list', 'int'],\n", + " 'lineno': (7, 4)},\n", + " 'message': 'append',\n", + " 'args': [{'type': 'int', 'value': '16', 'pseudo_type': 'int'}],\n", + " 'pseudo_type': ['list', 'int']}},\n", + " {'type': 'if_statement',\n", + " 'test': {'type': 'standard_method_call',\n", + " 'receiver': {'type': 'local',\n", + " 'name': 'b',\n", + " 'pseudo_type': ['list', 'int'],\n", + " 'lineno': (8, 12)},\n", + " 'message': 'contains?',\n", + " 'args': [{'type': 'local',\n", + " 'name': 'i',\n", + " 'pseudo_type': 'int',\n", + " 'lineno': (8, 7)}],\n", + " 'pseudo_type': 'Boolean'},\n", + " 'block': [{'type': 'assignment',\n", + " 'target': {'type': 'local', 'name': 'x', 'pseudo_type': 'int'},\n", + " 'value': {'type': 'int', 'value': '2', 'pseudo_type': 'int'},\n", + " 'pseudo_type': 'Void'}],\n", + " 'pseudo_type': 'Void',\n", + " 'otherwise': []},\n", + " {'type': 'implicit_return',\n", + " 'value': {'type': 'local',\n", + " 'name': 'b',\n", + " 'pseudo_type': ['list', 'int'],\n", + " 'lineno': (10, 11)},\n", + " 'pseudo_type': ['list', 'int']}],\n", + " 'recursive': False}]}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pycropml.transpiler.main import Main\n", + "\n", + "source = \"\"\"\n", + "def toto(int x):\n", + " cdef intlist b\n", + " cdef int i\n", + " b = [15,20]\n", + " b[0]=15\n", + " b.append(16)\n", + " if i in b:\n", + " x = 2\n", + " return b\n", + "\"\"\"\n", + "\n", + "\n", + "cst = Main(source, 'cs')\n", + "\n", + "p = cst.parse() # convert to cst\n", + "r = cst.to_ast(source) # convert to ast\n", + "\n", + "cst.dictAst # print ast as dict\n", + "\n", + "#print(cst.to_source()) # generate code " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "crop2ml", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/pycropml/transpiler/antlr_py/extract_metadata.py b/src/pycropml/transpiler/antlr_py/extract_metadata.py index e9f9b3b..daf7938 100644 --- a/src/pycropml/transpiler/antlr_py/extract_metadata.py +++ b/src/pycropml/transpiler/antlr_py/extract_metadata.py @@ -11,6 +11,7 @@ def __init__(self): def getFromComment(self, file, c_st_single, c_st_multi, c_end_multi): comments = ExtractComments(file, c_st_single, c_st_multi, c_end_multi) + print("bababab", comments) model_mdata = extract(comments) return model_mdata diff --git a/src/pycropml/transpiler/antlr_py/extract_metadata_from_comment.py b/src/pycropml/transpiler/antlr_py/extract_metadata_from_comment.py index 21031a0..5bd4245 100644 --- a/src/pycropml/transpiler/antlr_py/extract_metadata_from_comment.py +++ b/src/pycropml/transpiler/antlr_py/extract_metadata_from_comment.py @@ -42,84 +42,154 @@ def ExtractComments(filename, c_st_single, c_st_multi, c_end_multi): all_text = all_text[end_pos + 1:] return comments -pattern_attr_val = r"(\*\*?\s*(?P\w+)\s*:\s*(?P[\-\(\)\w+\s:,ï\[\]\\_\./\'\*]*))" +#pattern_attr_val = r"(\*\*?\s*(?P\w+)\s*:\s*(?P[\-\(\)\w+\s:,ï\[\]\\_\./\'\*]*))" +pattern_attr_val = r"(\*\*?\s*(?P\w+)\s*:\s*(?P.*))" + +def ensure_text(v): + if isinstance(v, bytes): + return v.decode("utf-8") + return v + +def _search_group(pattern, text, group=1, flags=0, default=None): + """Return match.group(group) or default if no match.""" + m = re.search(pattern, text, flags) + return m.group(group) if m else default + +import json +def parse_default(val): + if isinstance(val, str): + s = val.strip() + if s.startswith("[") and s.endswith("]"): + try: + return json.loads(s) + except json.JSONDecodeError: + return val + return val + +def _find_section(text, section_name): + """ + Return the raw body of a section like '- inputs:' up to next top-level '- :' + Works even if the section is last. + """ + # top-level section markers: start of line then '-' then name then ':' + # allow optional comment prefixes like //, #, !, * and spaces + pat = rf"(?im)^[ \t*/#!-]*-\s*{re.escape(section_name)}\s*:\s*(.*?)(?=^[ \t*/#!-]*-\s*\w+\s*:|\Z)" + m = re.search(pat, text, flags=re.DOTALL) + return m.group(1) if m else None + +def _split_named_items(section_body): + """ + Split a section body into chunks per '* name: ...' + Returns list of (name, body_after_name). + """ + if not section_body: + return [] + + # Normalize line endings + section_body = section_body.replace("\r\n", "\n").replace("\r", "\n") + + # Find all occurrences of '* name: X' with their spans + item_pat = re.compile(r"(?im)^[ \t*/#!-]*\*\s*name\s*:\s*(?P[^\n]+)\n?", re.MULTILINE) + matches = list(item_pat.finditer(section_body)) + if not matches: + return [] + + items = [] + for i, m in enumerate(matches): + start = m.end() + end = matches[i + 1].start() if i + 1 < len(matches) else len(section_body) + name = ensure_text(m.group("name").strip()) + body = section_body[start:end].strip("\n") + items.append((name, body)) + return items + +def attval(text): + """ + Parse lines like: + * Title: ... + ** description : ... + Supports multiline continuation: lines without attribute are appended to last attribute. + """ + if not text: + return {} + + text = text.replace("\r\n", "\n").replace("\r", "\n") + lines = [ln for ln in text.split("\n") if ln.strip()] + dic = {} + last_attr = None -def extract(comment): - keywords = ["name", "version", "timestep" ] - patterns = [r'(\s*-?\s*Name:\s*(?P\w+))', - r'(\s*-?\s*Version:\s*(?P\d+\.*\d+))', - r'(\s*-?\s*Time step:\s*(?P\d+\.*\d*))'] - - # header of modelUnit name, version, timestep - head = {} - i = 0 - for p in patterns: - if re.search(p, comment): - head[keywords[i]] = re.search(p, comment).group(keywords[i]) - i = i + 1 - m = ModelUnit(head) + for line in lines: + # Try strict match first + m = re.search(pattern_attr_val, line) + if m: + attr = m.group("attribute").strip() + val = m.group("value").strip() + val = ensure_text(val) + last_attr = attr + else: + # continuation line + if last_attr is None: + # If we don't know what to attach to, skip or store under a generic key + continue + attr = last_attr + val = ensure_text(line.strip()) + + # Clean common comment junk at line start + val = re.sub(r"^[ \t*/#!-]+", "", val).strip() + + if attr in dic: + dic[attr] += "\n" + val + else: + dic[attr] = val - # description element of modelUnit (Title, Authors, Reference, Institution, Abstract) - pat_description = r'-\s*Description:\s*(.*?)(?=\n\s*[#!/]*\s*-\s*inputs|\n\s*[#!/]*\s*-\s*outputs|$)' - text_description = re.search(pat_description, comment, re.DOTALL).group(1) - description = attval(text_description) - d = Description() - for k, v in description.items(): setattr(d, k, v) - m.add_description(d) + return dic + +def extract(comment): + # -------- header (safe) -------- + header_patterns = { + "name": r"(?im)\bName\s*:\s*(?P[^\s,]+)", + "version": r"(?im)\bVersion\s*:\s*(?P[^\s,]+)", + "timestep": r"(?im)\bTime\s*step\s*:\s*(?P[^\s,]+)", + } - # inputs - pat_inputs = r'-\s*inputs:\s*(.*?)(?=\n\s*[#!/]*\s*-\s*outputs|\n\s*[#!/]*\n)' - inputs_part = re.search(pat_inputs, comment, re.DOTALL).group(1) - pat_input = r'\*\s*name:\s*(.*?)(?=\n\s*[#!/]*\s*\*\s*name:|\n\n)' - input_parts = re.findall(pat_input, inputs_part+"\n\n", re.DOTALL) + head = {} + for k, pat in header_patterns.items(): + m = re.search(pat, comment) + if m: + head[k] = ensure_text(m.group(k)) + + munit = ModelUnit(head) + + # -------- description (optional) -------- + desc_body = _find_section(comment, "Description") + if desc_body: + desc_dict = attval(desc_body) + d = Description() + for k, v in desc_dict.items(): + setattr(d, k, v) + munit.add_description(d) + + # -------- inputs (optional) -------- + inputs_body = _find_section(comment, "inputs") inpList = [] - if input_parts: - for inp in input_parts: - input={} - name = inp.split("\n")[0].strip() - inp = "\n".join(inp.split("\n")[1:]) - input["name"] = name - input.update(attval(inp)) - inpList.append(Input(input)) - m.inputs = inpList - - # outputs - pat_outputs = r'-\s*outputs:\s*(.*?)(?=\n\s*[#!/]*\s*-\s*inputs|\n\s*[#!/]*\s*\n)' - outputs_part = re.search(pat_outputs, comment, re.DOTALL).group(1) - pat_output = r'\*\s*name:\s*(.*?)(?=\n\s*[#!/]*\s*\*\s*name:|\n\n)' - output_parts = re.findall(pat_output, outputs_part+'\n\n', re.DOTALL) + for name, body in _split_named_items(inputs_body): + data = {"name": name} + data.update(attval(body)) + inpList.append(Input(data)) + munit.inputs = inpList # empty if missing + + # -------- outputs (optional) -------- + outputs_body = _find_section(comment, "outputs") outList = [] - if output_parts: - for out in output_parts: - output={} - name = out.split("\n")[0].strip() - out = "\n".join(out.split("\n")[1:]) - output["name"] = name - output.update(attval(out)) - outList.append(Output(output)) - m.outputs = outList - - return m + for name, body in _split_named_items(outputs_body): + data = {"name": name} + data.update(attval(body)) + outList.append(Output(data)) + munit.outputs = outList # empty if missing + + return munit -def attval(text): - space = " " - lines = text.split('\n') - dic = {} - last_attr = None - for line in lines: - if not line: continue - obj = re.search(pattern_attr_val, line) - if not obj: attribute = last_attr - else: attribute = obj.group("attribute") - obj = re.search(pattern_attr_val, line, re.ASCII) - if not obj: - value = '\n' + space*3 + line.strip() - else: value = obj.group("value").replace('\r', "").strip() - if attribute in dic : dic[attribute] += str(value) - else: dic[attribute] = value - last_attr = attribute - return dic diff --git a/src/pycropml/transpiler/antlr_py/extract_metadata_from_comment_ori.py b/src/pycropml/transpiler/antlr_py/extract_metadata_from_comment_ori.py new file mode 100644 index 0000000..3301b48 --- /dev/null +++ b/src/pycropml/transpiler/antlr_py/extract_metadata_from_comment_ori.py @@ -0,0 +1,306 @@ +# inspired from http://csharphelper.com/blog/2015/10/extract-comments-from-a-c-file-in-c/ + +""" + information extraction over structured documentation or comments + +""" +from pycropml.composition import ModelComposition +from pycropml.modelunit import ModelUnit +from pycropml.description import Description +from pycropml.inout import Input, Output +import os +import re +# Return a file's comments. +def ExtractComments(filename, c_st_single, c_st_multi, c_end_multi): + # If a language has no block comment style, be sure that the default c_st_multi and c_end_multi will never be met. + if os.path.isfile(filename): + with open(filename, 'r', encoding='utf-8') as file: + all_text = file.read() + else: all_text = filename + comments = ""; + while (len(all_text) > 0): + single_line_pos = all_text.find(c_st_single) + multi_line_pos = all_text.find(c_st_multi) + if (single_line_pos < 0) and multi_line_pos <0 : break + if (single_line_pos < 0) : single_line_pos = len(all_text) + if (multi_line_pos < 0): multi_line_pos = len(all_text) + if (single_line_pos < multi_line_pos): + end_pos = all_text.find("\n", single_line_pos +1); + if end_pos<0 : + comments += all_text[single_line_pos:] + "\r\n" + all_text = "" + else: + comments += all_text[single_line_pos: end_pos] +"\r\n" + all_text = all_text[end_pos + 1:] + else: + end_pos = all_text.find(c_end_multi, multi_line_pos + 1) + if (end_pos < 0): + comments += all_text[multi_line_pos:] + "\r\n" + all_text = "" + else: + comments += all_text[multi_line_pos : end_pos+2] + "\r\n"; + all_text = all_text[end_pos + 1:] + return comments + +pattern_attr_val = r"(\*\*?\s*(?P\w+)\s*:\s*(?P[\-\(\)\w+\s:,ï\[\]\\_\./\'\*]*))" +#pattern_attr_val = r"(\*\*?\s*(?P\w+)\s*:\s*(?P.*))" + +def ensure_text(v): + if isinstance(v, bytes): + return v.decode("utf-8") + return v +''' +def _search_group(pattern, text, group=1, flags=0, default=None): + """Return match.group(group) or default if no match.""" + m = re.search(pattern, text, flags) + return m.group(group) if m else default + +import json +def parse_default(val): + if isinstance(val, str): + s = val.strip() + if s.startswith("[") and s.endswith("]"): + try: + return json.loads(s) + except json.JSONDecodeError: + return val + return val + +def _find_section(text, section_name): + """ + Return the raw body of a section like '- inputs:' up to next top-level '- :' + Works even if the section is last. + """ + # top-level section markers: start of line then '-' then name then ':' + # allow optional comment prefixes like //, #, !, * and spaces + pat = rf"(?im)^[ \t*/#!-]*-\s*{re.escape(section_name)}\s*:\s*(.*?)(?=^[ \t*/#!-]*-\s*\w+\s*:|\Z)" + m = re.search(pat, text, flags=re.DOTALL) + return m.group(1) if m else None + +def _split_named_items(section_body): + """ + Split a section body into chunks per '* name: ...' + Returns list of (name, body_after_name). + """ + if not section_body: + return [] + + # Normalize line endings + section_body = section_body.replace("\r\n", "\n").replace("\r", "\n") + + # Find all occurrences of '* name: X' with their spans + item_pat = re.compile(r"(?im)^[ \t*/#!-]*\*\s*name\s*:\s*(?P[^\n]+)\n?", re.MULTILINE) + matches = list(item_pat.finditer(section_body)) + if not matches: + return [] + + items = [] + for i, m in enumerate(matches): + start = m.end() + end = matches[i + 1].start() if i + 1 < len(matches) else len(section_body) + name = ensure_text(m.group("name").strip()) + body = section_body[start:end].strip("\n") + items.append((name, body)) + return items + +def attval(text): + """ + Parse lines like: + * Title: ... + ** description : ... + Supports multiline continuation: lines without attribute are appended to last attribute. + """ + if not text: + return {} + + text = text.replace("\r\n", "\n").replace("\r", "\n") + lines = [ln for ln in text.split("\n") if ln.strip()] + + dic = {} + last_attr = None + + for line in lines: + # Try strict match first + m = re.search(pattern_attr_val, line) + if m: + attr = m.group("attribute").strip() + val = m.group("value").strip() + val = ensure_text(val) + last_attr = attr + else: + # continuation line + if last_attr is None: + # If we don't know what to attach to, skip or store under a generic key + continue + attr = last_attr + val = ensure_text(line.strip()) + + # Clean common comment junk at line start + val = re.sub(r"^[ \t*/#!-]+", "", val).strip() + + if attr in dic: + dic[attr] += "\n" + val + else: + dic[attr] = val + + return dic + +def extract(comment): + # -------- header (safe) -------- + header_patterns = { + "name": r"(?im)\bName\s*:\s*(?P[^\s,]+)", + "version": r"(?im)\bVersion\s*:\s*(?P[^\s,]+)", + "timestep": r"(?im)\bTime\s*step\s*:\s*(?P[^\s,]+)", + } + + head = {} + for k, pat in header_patterns.items(): + m = re.search(pat, comment) + if m: + head[k] = ensure_text(m.group(k)) + + munit = ModelUnit(head) + + # -------- description (optional) -------- + desc_body = _find_section(comment, "Description") + if desc_body: + desc_dict = attval(desc_body) + d = Description() + for k, v in desc_dict.items(): + setattr(d, k, v) + munit.add_description(d) + + # -------- inputs (optional) -------- + inputs_body = _find_section(comment, "inputs") + inpList = [] + for name, body in _split_named_items(inputs_body): + data = {"name": name} + data.update(attval(body)) + inpList.append(Input(data)) + munit.inputs = inpList # empty if missing + + # -------- outputs (optional) -------- + outputs_body = _find_section(comment, "outputs") + outList = [] + for name, body in _split_named_items(outputs_body): + data = {"name": name} + data.update(attval(body)) + outList.append(Output(data)) + munit.outputs = outList # empty if missing + + return munit + +''' +def extract(comment): + keywords = ["name", "version", "timestep" ] + patterns = [r'(\s*-?\s*Name:\s*(?P\w+))', + r'(\s*-?\s*Version:\s*(?P\d+\.*\d+))', + r'(\s*-?\s*Time step:\s*(?P\d+\.*\d*))'] + + # header of modelUnit name, version, timestep + head = {} + i = 0 + for p in patterns: + if re.search(p, comment): + head[keywords[i]] = re.search(p, comment).group(keywords[i]) + i = i + 1 + m = ModelUnit(head) + + # description element of modelUnit (Title, Authors, Reference, Institution, Abstract) + pat_description = r'-\s*Description:\s*(.*?)(?=\n\s*[#!/]*\s*-\s*inputs|\n\s*[#!/]*\s*-\s*outputs|$)' + text_description = re.search(pat_description, comment, re.DOTALL).group(1) + description = attval(text_description) + d = Description() + for k, v in description.items(): setattr(d, k, v) + m.add_description(d) + + # inputs + pat_inputs = r'-\s*inputs:\s*(.*?)(?=\n\s*[#!/]*\s*-\s*outputs|\n\s*[#!/]*\n)' + inputs_part = re.search(pat_inputs, comment, re.DOTALL).group(1) + pat_input = r'\*\s*name:\s*(.*?)(?=\n\s*[#!/]*\s*\*\s*name:|\n\n)' + input_parts = re.findall(pat_input, inputs_part+"\n\n", re.DOTALL) + inpList = [] + if input_parts: + for inp in input_parts: + input={} + name = inp.split("\n")[0].strip() + inp = "\n".join(inp.split("\n")[1:]) + input["name"] = ensure_text(name) + input.update(attval(inp)) + inpList.append(Input(input)) + m.inputs = inpList + + # outputs + pat_outputs = r'-\s*outputs:\s*(.*?)(?=\n\s*[#!/]*\s*-\s*inputs|\n\s*[#!/]*\s*\n)' + outputs_part = re.search(pat_outputs, comment, re.DOTALL).group(1) + pat_output = r'\*\s*name:\s*(.*?)(?=\n\s*[#!/]*\s*\*\s*name:|\n\n)' + output_parts = re.findall(pat_output, outputs_part+'\n\n', re.DOTALL) + outList = [] + if output_parts: + for out in output_parts: + output={} + name = out.split("\n")[0].strip() + out = "\n".join(out.split("\n")[1:]) + output["name"] = ensure_text(name) + output.update(attval(out)) + outList.append(Output(output)) + m.outputs = outList + + return m + +def attval(text): + space = " " + lines = text.split('\n') + dic = {} + last_attr = None + for line in lines: + if not line: continue + obj = re.search(pattern_attr_val, line) + if not obj: attribute = last_attr + else: attribute = obj.group("attribute") + obj = re.search(pattern_attr_val, line, re.ASCII) + if not obj: + value = '\n' + space*3 + line.strip() + else: value = obj.group("value").replace('\r', "").strip() + if attribute in dic : dic[attribute] += str(value) + else: dic[attribute] = value + last_attr = attribute + return dic + + + + +def extract_compo(comment): + keywords = ["name", "version", "timestep" ] + patterns = [r'(\s*-?\s*Name:\s*(?P\w+))', + r'(\s*-?\s*Version:\s*(?P\d+\.*\d+))', + r'(\s*-?\s*Time step:\s*(?P\d+\.*\d*))'] + + # header of modelUnit name, version, timestep + head = {} + i = 0 + for p in patterns: + if re.search(p, comment): + head[keywords[i]] = re.search(p, comment).group(keywords[i]) + i = i + 1 + m = ModelComposition(head) + # description element of modelUnit (Title, Authors, Reference, Institution, Abstract) + pat_description = r'-\s*Description:\s*(.*?)(?=\n\s*[#!/]*\s*-\s*inputs|\n\s*[#!/]*\s*-\s*outputs|$)' + text_description = re.search(pat_description, comment, re.DOTALL).group(1) + description = attval(text_description) + d = Description() + for k, v in description.items(): + setattr(d, k, v) + m.add_description(d) + return m + + +""" +from pycropml.transpiler.antlr_py.extract_metadata_from_comment import ExtractComments, extract +from path import Path +file = Path("C:/Users/midingoy/Documents/SQ_Wheat_Phenology/src/f90/vernalizationprogress.f90") +r = ExtractComments(file, "!", '"""', '"""') +v = extract(r) + + +""" \ No newline at end of file diff --git a/src/pycropml/transpiler/antlr_py/java/api_transform.py b/src/pycropml/transpiler/antlr_py/java/api_transform.py index 0528662..8d701f7 100644 --- a/src/pycropml/transpiler/antlr_py/java/api_transform.py +++ b/src/pycropml/transpiler/antlr_py/java/api_transform.py @@ -252,7 +252,7 @@ def integr_expander(type, message, args): 'ceil': StandardCall('math', 'ceil', expander=ceil_expander), 'abs': StandardCall('global', 'abs', expander = abs_expander), 'exp': StandardCall('math', 'exp'), - 'round': StandardCall('System', 'round'), + 'round': StandardCall('math', 'round'), 'pow': StandardCall('math', 'pow'), 'floor': StandardCall('math', 'floor', expander=floor_expander), 'min': StandardCall('system', 'min', expander=min_expander) diff --git a/src/pycropml/transpiler/antlr_py/java/builtin_typed_api.py b/src/pycropml/transpiler/antlr_py/java/builtin_typed_api.py index fdf441b..5e0135d 100644 --- a/src/pycropml/transpiler/antlr_py/java/builtin_typed_api.py +++ b/src/pycropml/transpiler/antlr_py/java/builtin_typed_api.py @@ -214,7 +214,7 @@ def binary_or(l, r): 'PI': 'PI', 'Max': ['Number','Number'], 'Min': ['Number','Number'], - 'Round': ['double','double'], + 'round': ['double','double'], 'floor': ["double", "int"], 'pow': ["Number", "Number", "int"] }, diff --git a/src/pycropml/transpiler/antlr_py/java/javaTransformer.py b/src/pycropml/transpiler/antlr_py/java/javaTransformer.py index d01bb17..946a9ba 100644 --- a/src/pycropml/transpiler/antlr_py/java/javaTransformer.py +++ b/src/pycropml/transpiler/antlr_py/java/javaTransformer.py @@ -1107,6 +1107,7 @@ def util_methodinvocation(self, api, receiver, method, args, location,comments): prepare_table(TYPED_API[receiver], ORIGINAL_METHODS.get(receiver)).strip())) elif not isinstance(api, dict): + print("locationnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn", location) z = api.expand(args ) return z else: diff --git a/src/pycropml/transpiler/antlr_py/simplace/run.py b/src/pycropml/transpiler/antlr_py/simplace/run.py index 7799e18..7eeca5f 100644 --- a/src/pycropml/transpiler/antlr_py/simplace/run.py +++ b/src/pycropml/transpiler/antlr_py/simplace/run.py @@ -13,9 +13,29 @@ from pycropml.transpiler.antlr_py.java.java_preprocessing import Declarations, MemberAcess, Custom_call, Local, Assignment from pycropml.transpiler.antlr_py.java import java_cyml from pycropml.transpiler.ast_transform import transform_to_syntax_tree -from pycropml.transpiler.antlr_py.to_specification import extractcomments +from pycropml.transpiler.antlr_py.to_specification import extractcomments, createObjectCompo from pycropml.transpiler.antlr_py.createXml import Pl2Crop2ml, generate_compositefile, generate_unitfile, create_repo from pycropml.transpiler.antlr_py.codeExtraction import remove +import itertools + + +def function_dependency(st, f): + r = [f] + z = SimplaceExtraction() + while True: + f = f if isinstance(f, list) else [f] + print("fffffffff", f) + f_exts = [z.externFunction(st, n, False, n.name) for n in f] + exts = list(itertools.chain(*f_exts)) + exs = [i for i in exts if i ] + if exs: + for ex in exs: + r.append(ex) + f = exs + else: + break + return r + def translate(algo, names): @@ -71,8 +91,11 @@ def translate_f(algo, names): return zcode def run_simplace(components, output): + compositeStrat = [] simpleStrat= Path(components).glob('*.java') - compositeStrat = Path(components).glob('*.xml')[0] + compositeStrats = Path(components).glob('*.xml') + if compositeStrats: + compositeStrat = compositeStrats[0] crop2ml_rep = Path(os.path.join(output, 'crop2ml')) if not isdir(crop2ml_rep): crop2ml_rep.mkdir() @@ -84,7 +107,10 @@ def run_simplace(components, output): cyml_rep.mkdir() models = [] p = SimplaceExtraction() - auxiliary = p.getAuxiliary(compositeStrat) + auxiliary = {} + func_names = [] + if compositeStrat: + auxiliary = p.getAuxiliary(compositeStrat) for strat in simpleStrat: print(strat) with open(strat, "r") as f: @@ -104,6 +130,7 @@ def run_simplace(components, output): names = [ j.name for j in mm.model.inputs + mm.model.outputs] algo = mm.getProcess(strAsg) init = mm.getInit(strAsg) + funcs = mm.externFunction(strAsg, [algo] + [init], False) algocode = translate(algo.block, names) initcode = translate(init.block, names) @@ -121,28 +148,42 @@ def run_simplace(components, output): filename = Path(os.path.join(cyml_rep, "%s.pyx"%(mm.model.name))) with open(filename, "wb") as tg_file: tg_file.write(algocode.encode('utf-8')) - - - - funcs = mm.externFunction(strAsg, algo) + funcs = [f for f in funcs if f] if funcs: - for m in funcs: - if m: - mm.model.function.append(m.name) - code = translate_f(m, []) - filename = Path(os.path.join(cyml_rep, "%s.pyx"%(m.name))) + for f in funcs: + if f: + r = [] + # order of function dependency + f_dep = function_dependency(strAsg, f) + dep_ = list(reversed(f_dep)) + dep = [] + dep_names = [] + print("dep_", dep_) + for d in dep_: + if d.name not in dep_names: + dep.append(d) + dep_names.append(d.name) + for ex in dep: # dep is the list of external function in the order of dependency + if ex.name not in func_names: # to avoid duplicating dependent functions in different auxiliary functions + func = mm.externFunction(strAsg, ex, False, ex.name) + extfunc = [p for p in func if p] + if extfunc and isinstance(extfunc[0], list): + extfunc = list(itertools.chain(*extfunc)) + r.append(ex) + func_names.append(ex.name) + cd = java_cyml.Java_Cyml_ast(r) + h = cd.transform() + nd = transform_to_syntax_tree(h) + code = writeCyml(nd) + filename = Path(os.path.join(cyml_rep, "%s.pyx"%(f.name))) with open(filename, "wb") as tg_file: tg_file.write(code.encode('utf-8')) + mm.model.function.append(f.name) + + models.append(mm.model) - """coms = com_meta_info_part.split("\n") - shortdescription = [] - for k, com in enumerate(coms[2:]): - while coms[k].strip()!="*" and len(shortdescription)==0: - shortdescription.append(coms[k][1:].strip()) - k = k+1 - print(shortdescription)""" xml_ = Pl2Crop2ml(mm.model, "Simplace.SoilTemp").run_unit() @@ -153,9 +194,29 @@ def run_simplace(components, output): r += xml_.unicode(indent=4)#.encode('utf-8') xml_file.write(r.encode()) - op_extr = SimplaceExtraction() - mc = op_extr.modelcomposition(compositeStrat, models) - generate_compositefile(output, mc, mc.name) + op_extr = SimplaceExtraction() + if compositeStrat: + mc = op_extr.modelcomposition(compositeStrat, models) + generate_compositefile(output, mc, mc.name) + else: + description = {} + description["name"]=mm.model.name+"_" + description["version"]=mm.model.version + description["timestep"]=mm.model.timestep + description["url"] = "" + description["Authors"]=mm.model.description.Authors + description["Reference"]=mm.model.description.Reference + description["ShortDescription"]=mm.model.description.ShortDescription + description["ExtendedDescription"]=mm.model.description.ExtendedDescription + description["Institution"]=mm.model.description.Institution + mc = createObjectCompo(description,models) + xml_ = Pl2Crop2ml(mc, "Simplace_").run_compo() + filename = os.path.join(output, "crop2ml", "composition.%s.xml"%(mm.model.name)) + with open(filename, "wb") as xml_file: + r = '\n' + r += '\n' + r += xml_.unicode(indent=4)#.encode('utf-8') + xml_file.write(r.encode()) diff --git a/src/pycropml/transpiler/antlr_py/simplace/simplaceExtraction.py b/src/pycropml/transpiler/antlr_py/simplace/simplaceExtraction.py index 4b9b598..2a65bff 100644 --- a/src/pycropml/transpiler/antlr_py/simplace/simplaceExtraction.py +++ b/src/pycropml/transpiler/antlr_py/simplace/simplaceExtraction.py @@ -119,7 +119,7 @@ def getOutputs(self, tree): outs = list(map(lambda out: out.instance.name, setouts)) return outs - def modelunit(self, tree, auxiliary): + def modelunit(self, tree, auxiliary={}): desc = self.description(tree) self.model= ModelUnit({"name":desc["name"], "version":"001", "timestep":"1"}) description = self.model_desc(desc) @@ -150,7 +150,7 @@ def modelunit(self, tree, auxiliary): elif att == "state": category = "state" else: category = att.lower() - if auxiliary[self.model.name] and name in auxiliary[self.model.name]: + if auxiliary and auxiliary[self.model.name] and name in auxiliary[self.model.name]: category = "auxiliary" if name in ins and name in outnames: category = "state" diff --git a/src/pycropml/transpiler/generators/rGenerator.py b/src/pycropml/transpiler/generators/rGenerator.py index 3d98ada..19a7a8f 100644 --- a/src/pycropml/transpiler/generators/rGenerator.py +++ b/src/pycropml/transpiler/generators/rGenerator.py @@ -283,11 +283,11 @@ def visit_function_definition(self, node): self.newline(1) self.write(f"#' @return") self.newline(1) - self.write(f"#' \describe{{") + self.write(f"#' \\describe{{") self.newline(1) for out in self.model.outputs: if out.variablecategory=="state": - self.write(f"#' \item{{{out.name} ({out.unit})}}{{{out.description} {out.variablecategory} ({out.min}-{inp.max})}}") + self.write(f"#' \\item{{{out.name} ({out.unit})}}{{{out.description} {out.variablecategory} ({out.min}-{inp.max})}}") self.newline(1) self.newline(1) self.write(f"#' }}") @@ -320,10 +320,10 @@ def visit_function_definition(self, node): self.newline(1) self.write(f"#' @return") self.newline(1) - self.write(f"#' \describe{{") + self.write(f"#' \\describe{{") self.newline(1) for out in self.model.outputs: - self.write(f"#' \item{{{out.name} ({out.unit})}}{{{out.description} {out.variablecategory} ({out.min}-{inp.max})}} ") + self.write(f"#' \\item{{{out.name} ({out.unit})}}{{{out.description} {out.variablecategory} ({out.min}-{inp.max})}} ") self.newline(1) self.newline(1) self.write(f"#' }}")