From 4b91ae80505893ad65e890f3eed84786b298cf69 Mon Sep 17 00:00:00 2001 From: cyrillemidingoyi Date: Fri, 23 Feb 2024 14:38:50 +0100 Subject: [PATCH] update --- .../transpiler/antlr_py/java/java_cyml.py | 4 +++ src/pycropml/transpiler/ast_transform.py | 8 ++--- src/pycropml/transpiler/builtin_typed_api.py | 2 +- .../transpiler/generators/cppGenerator.py | 29 +++++++++++++++++-- .../transpiler/generators/cymlGenerator.py | 8 ++++- .../transpiler/generators/fortranGenerator.py | 24 +++++++++++---- .../transpiler/generators/javaGenerator.py | 15 +++++++--- .../transpiler/generators/pythonGenerator.py | 9 ++++-- src/pycropml/transpiler/rules/cppRules.py | 14 +++++---- src/pycropml/transpiler/rules/javaRules.py | 2 +- 10 files changed, 86 insertions(+), 29 deletions(-) diff --git a/src/pycropml/transpiler/antlr_py/java/java_cyml.py b/src/pycropml/transpiler/antlr_py/java/java_cyml.py index bfaabad6..5bdc737c 100644 --- a/src/pycropml/transpiler/antlr_py/java/java_cyml.py +++ b/src/pycropml/transpiler/antlr_py/java/java_cyml.py @@ -297,6 +297,10 @@ def visit_if_statement(self, node): 'pseudo_type': 'Void', 'otherwise': self.visit(node.otherwise), "comments": node.comments} + + def visit_Void(self, node): + return {"type":"none", "value":"None", "pseudo_type":"none"} + def visit_else_statement(self, node): return {'type': 'else_statement', diff --git a/src/pycropml/transpiler/ast_transform.py b/src/pycropml/transpiler/ast_transform.py index 245a4669..3830ac2c 100644 --- a/src/pycropml/transpiler/ast_transform.py +++ b/src/pycropml/transpiler/ast_transform.py @@ -389,7 +389,7 @@ def visit_singleassignmentnode(self, node, lhs, rhs, location): }""" def visit_nonenode(self, node, location): - return {"type":"none", "value":"None"} + return {"type":"none", "value":"None", "pseudo_type":"none"} def visit_inplaceassignmentnode(self, node, lhs, rhs, location): z = node.end_pos() @@ -770,7 +770,6 @@ def visit_simplecallnode(self, node, function, coerced_self, args, arg_tuple, lo self._definition_index["functions"][message] = self.visit_node(x[0]) q = c[message][-1] if argx != param_types: - print(message, "iooooooooooooo", argx, param_types) raise PseudoCythonTypeCheckError("Types incompatibility at line %s"%location[0]) #q = self._type_check(argx+returnx,message, param_types)[-1] self.function_name = v @@ -785,7 +784,7 @@ def visit_simplecallnode(self, node, function, coerced_self, args, arg_tuple, lo arg, ExprNodes.Node) else self.visit_node(arg) for arg in args] meth = [d for m in list(self._fromimport.values()) for d in m] if function.name not in meth and function.name not in FUNCTION_API["math"] : - print("err", function.name, FUNCTION_API["math"].keys()) + print("err", function.name, FUNCTION_API["math"].keys(),[n.name for n in args]) else: if self.retrieve_library(function.name) not in self._imports: self._imports.append( @@ -1758,7 +1757,7 @@ def visit_primarycmpnode(self, node, operand1, operand2, coerced_operand2, casca right_node = self.visit_node(operand2) left_node = self.visit_node(operand1) if node.operator not in ["in", "not_in"]: - self._confirm_comparable( + if node.operator != "is": self._confirm_comparable( op, left_node['pseudo_type'], right_node['pseudo_type'], location) result = { 'type': 'comparison', @@ -1852,7 +1851,6 @@ def _compatible_types(self, from_, to, err, silent=False): if silent: return False else: - print(to, from_) raise PseudoCythonTypeCheckError( err + ' from %s to %s' % (serialize_type(from_), serialize_type(to))) for f, t in zip(from_[1:-1], to[1:-1]): diff --git a/src/pycropml/transpiler/builtin_typed_api.py b/src/pycropml/transpiler/builtin_typed_api.py index adc7a5a6..172388f2 100644 --- a/src/pycropml/transpiler/builtin_typed_api.py +++ b/src/pycropml/transpiler/builtin_typed_api.py @@ -408,7 +408,7 @@ def binary_or(l, r): ExprNodes.MulNode: '*', ExprNodes.DivNode: '/', ExprNodes.PowNode: '**', - ExprNodes.PrimaryCmpNode: ['==','<','>','<=','>=','!=', 'in', 'not_in'], + ExprNodes.PrimaryCmpNode: ['==','<','>','<=','>=','!=', 'in', 'not_in',"is"], ExprNodes.ModNode: '%', ExprNodes.BoolBinopNode: ['and','or'] } diff --git a/src/pycropml/transpiler/generators/cppGenerator.py b/src/pycropml/transpiler/generators/cppGenerator.py index fb4f8846..184339ba 100644 --- a/src/pycropml/transpiler/generators/cppGenerator.py +++ b/src/pycropml/transpiler/generators/cppGenerator.py @@ -142,6 +142,9 @@ def visit_else_statement(self, node): def visit_print(self, node): pass + def visit_ExprStatNode(self, node): + self.visit(node.expr) + def visit_float(self, node): self.write(node.value) @@ -178,7 +181,17 @@ def visit_standard_method_call(self, node): l = l[0] z = self.methods[l][node.message] if callable(z): - self.visit(z(node)) + if node.message == "sum" and node.receiver.type == "sliceindex": + self.write("std::accumulate(") + self.visit(node.receiver.receiver) + self.write(".begin() + ") + self.visit(node.receiver.args[0]) + self.write(",") + self.visit(node.receiver.receiver) + self.write(".begin() + ") + self.visit(node.receiver.args[1]) + self.write(", 0.0)") + else: self.visit(z(node)) else: if not node.args: self.write(z) @@ -219,7 +232,16 @@ def visit_sliceindex(self, node): self.write(u"]") def visit_assignment(self, node): - if "function" in dir(node.value) and node.value.function.split('_')[0] == "model": + if node.value.type == "binary_op" and node.value.left.type == "list": + self.visit(node.target) + self.write(".assign(") + self.visit(node.value.right) + self.write(", ") + self.visit(node.value.left.elements[0]) + self.write(");") + + + elif "function" in dir(node.value) and node.value.function.split('_')[0] == "model": name = node.value.function.split('model_')[1] for m in self.model.model: if name == signature2(m): @@ -603,7 +625,7 @@ def visit_declaration(self, node): if n.type == "list": self.write(f"std::vector<{self.types[n.pseudo_type[1]]}> {n.name};") elif n.type == "array": - if not n.elts: + if "elts" not in dir(n) or not n.elts: self.write(f"std::vector<{self.types[n.pseudo_type[1]]}> {n.name};") else: self.write(f"std::vector<{self.types[n.pseudo_type[1]]}> {n.name}") @@ -1244,6 +1266,7 @@ def header_mu_cpp(models, rep, name): path_func = Path(os.path.join(m.path, "crop2ml", file_func)) func_tree=parser(Path(path_func)) newtree = AstTransformer(func_tree,path_func) + #print(newtree) dictAst = newtree.transformer() nodeAst= transform_to_syntax_tree(dictAst) z ={nodeAst.body[0].name: [nodeAst.body[0].return_type,nodeAst.body[0].params]} diff --git a/src/pycropml/transpiler/generators/cymlGenerator.py b/src/pycropml/transpiler/generators/cymlGenerator.py index 386885c1..df3a0f6a 100644 --- a/src/pycropml/transpiler/generators/cymlGenerator.py +++ b/src/pycropml/transpiler/generators/cymlGenerator.py @@ -99,6 +99,9 @@ def visit_cond_expr_node(self, node): def visit_constant(self, node): self.write(self.constant[node.library][node.name]) + + def visit_none(self, node): + self.write("None") def visit_if_statement(self, node): self.newline(node) @@ -106,7 +109,10 @@ def visit_if_statement(self, node): self.translate_com(node.comments) self.newline(node) self.write('if ') - self.visit(node.test) + if node.test.right.type=="none" and node.test.op=="==": + self.visit(node.test.left) + self.write(" is None") + else: self.visit(node.test) self.write(':') self.body(node.block) while True: diff --git a/src/pycropml/transpiler/generators/fortranGenerator.py b/src/pycropml/transpiler/generators/fortranGenerator.py index 087d86e0..2b30ca3d 100644 --- a/src/pycropml/transpiler/generators/fortranGenerator.py +++ b/src/pycropml/transpiler/generators/fortranGenerator.py @@ -26,6 +26,14 @@ #shutil.copyfileobj(f_src, f_dest) +def transf_var_name(name): + #if var_name starts with "_" we replace it by "cy_" + if name.startswith("_"): + name = "cy_" + name[1:] + return name + + + class FortranGenerator(CodeGenerator, FortranRules): """ This class contains the specific properties of @@ -67,12 +75,16 @@ def visit_notAnumber(self, node): pass def visit_comparison(self, node): - #self.write('(') - self.visit_binary_op(node) - #self.write(')') + if node.op == "is": + if node.right.type == "none": + self.write("NULL(") + self.visit(node.left) + self.write(")") + else: + self.visit_binary_op(node) def visit_local(self, node): - self.write(node.name) + self.write(transf_var_name(node.name)) # self.write("(%s - 1)"%node.name) if node.name in self.index else self.write(node.name) def visit_binary_op(self, node): @@ -153,7 +165,7 @@ def visit_assignment(self, node): self.write('call ') self.visit(node) elif node.value.type =="list" and not node.value.elements: - self.write("\n deallocate(%s)\n"%node.target.name) + self.write("\n deallocate(%s)\n"%transf_var_name(node.target.name)) elif node.value.type == "notAnumber": self.visit_notAnumber(node) else: @@ -716,6 +728,8 @@ def visit_array_decl(self, node): self.write(" )") if ("feat" not in dir(node)) and (("elts" not in dir(node) or not node.elts or len(node.elts)==0)): # and node.name not in self.parameters : self.write(", ALLOCATABLE ") + if("feat" in dir(node) and node.feat=="OUT") and ("elts" in dir(node) or not node.elts or len(node.elts)==0): + self.write(", ALLOCATABLE ") def visit_float_decl(self, node): self.write(self.types[node]) diff --git a/src/pycropml/transpiler/generators/javaGenerator.py b/src/pycropml/transpiler/generators/javaGenerator.py index 277ec769..7b6dbca3 100644 --- a/src/pycropml/transpiler/generators/javaGenerator.py +++ b/src/pycropml/transpiler/generators/javaGenerator.py @@ -253,7 +253,14 @@ def visit_sliceindex(self, node): self.write(u"]") def visit_assignment(self, node): - if "function" in dir(node.value) and node.value.function.split('_')[0]=="model": + if node.value.type == "binary_op" and node.value.left.type == "list": + self.visit(node.target) + self.write(".fill(") + self.visit(node.value.right) + self.write(", ") + self.visit(node.value.left.elements[0]) + self.write(");") + elif "function" in dir(node.value) and node.value.function.split('_')[0]=="model": name = node.value.function.split('model_')[1] for m in self.model.model: if name == signature2(m): @@ -993,7 +1000,6 @@ def model2Node(self): variables.append(ex) varnames.append(category + ex.name) #print(len(variables)) - st = [] for var in variables: if "variablecategory" in dir(var): @@ -1038,8 +1044,9 @@ def create(typevar): self.node_rates= create(self.rates) self.node_auxiliary= create(self.auxiliary) self.node_exogenous= create(self.exogenous) - self.node_param=create(self.modparam) - + self.node_param=create(self.modparam) + + def private(self,node): vars = [] for arg in node: diff --git a/src/pycropml/transpiler/generators/pythonGenerator.py b/src/pycropml/transpiler/generators/pythonGenerator.py index c120a969..f9c2d46e 100644 --- a/src/pycropml/transpiler/generators/pythonGenerator.py +++ b/src/pycropml/transpiler/generators/pythonGenerator.py @@ -209,9 +209,12 @@ def visit_module(self, node): def visit_comparison(self, node): - #self.write('(') - self.visit_binary_op(node) - #self.write(')') + if node.op == "is": + if node.right.type == "none": + self.visit(node.left) + self.write(" is None") + else: + self.visit_binary_op(node) def visit_method_call(self, node): "%s.%s"%(self.visit(node.receiver),self.write(node.message)) diff --git a/src/pycropml/transpiler/rules/cppRules.py b/src/pycropml/transpiler/rules/cppRules.py index 18224b35..f353101e 100644 --- a/src/pycropml/transpiler/rules/cppRules.py +++ b/src/pycropml/transpiler/rules/cppRules.py @@ -15,12 +15,14 @@ def translateLog(node): def translateSum(node): - return Node("call", function="accumulate", - args=[Node("local", name=f"{node.receiver.name}.begin()"), - Node("local", name=f"{node.receiver.name}.end()"), - Node("local", name=f"decltype({node.receiver.name})::value_type(0)")], - pseudo_type=node.pseudo_type) - + if "name" in dir(node.receiver): + print(node.receiver.y) + return Node("call", function="accumulate", + args=[Node("local", name=f"{node.receiver.name}.begin()"), + Node("local", name=f"{node.receiver.name}.end()"), + Node("int", value="0" if node.receiver.pseudo_type[1] == "int" else "0.0")], + pseudo_type=node.pseudo_type) + def translateNotContains(node): return Node("call", function="!", args=[Node("standard_method_call", receiver=node.receiver, diff --git a/src/pycropml/transpiler/rules/javaRules.py b/src/pycropml/transpiler/rules/javaRules.py index ceb06f92..cae1920a 100644 --- a/src/pycropml/transpiler/rules/javaRules.py +++ b/src/pycropml/transpiler/rules/javaRules.py @@ -77,7 +77,7 @@ def __init__(self): types = { "int": "Integer", - "float": "Double", + "float": "double", "bool": "Boolean", "array": "%s[] %s", "list": "List",