from pycropml.transpiler.pseudo_tree import Node
from pycropml.transpiler.env import Env
from pycropml.transpiler.antlr_py.fortran.fortran_preprocessing import Assignment, TransformLocal
from pycropml.transpiler.antlr_py.fortran.fortranExtraction import FortranExtraction
from pycropml.transpiler.ast_transform import transform_to_syntax_tree
[docs]
class F90_Cyml_ast():
"""G
"""
def __init__(self, tree, model=None, name=None, var= [], treeG=None):
self.tree = tree
self.model = model
self.name = name
self.recursive = False
self.type_env = Env()
self.var = var if var else []
self.treeG = treeG if treeG else None
[docs]
def visit(self, node):
'''
Parameters
----------
node : Node
DESCRIPTION.
Returns
-------
dict
Common Code Model Representation based on CyML constructs.
'''
if isinstance(node, list):
results = []
for n in node:
x = self.visit(n)
if isinstance(x, list):
results.extend(x)
else:
results.append(x)
return results
elif isinstance(node, Node):
return getattr(self, 'visit_%s'%(node.type))(node)
else:
return node
[docs]
def visit_top_level(self, nodes):
for n in nodes:
if n.type == "function_definition": #isinstance(n, SubroutineSubprogram)
self.definitions.append(('function', n.name))
self._definition_index['functions'][n.name] = n
self.type_env.top['functions'][n.name] = [
'Function'] + ([None] * len(n.params)) + [None]
self.type_env.top[n.params] = self.type_env.top['functions'][str(n.params)]
[docs]
def visit_import(self, node):
return
[docs]
def visit_tuple(self, node):
return {'type':'tuple',
'elements':self.visit(node.elements),
"pseudo_type": node.pseudo_type}
[docs]
def visit_function_definition(self, node):
varnotdeclared = node.notdeclared
imports = node.imports
extr2 = FortranExtraction()
if varnotdeclared:
res = extr2.getDecl(self.treeG, imports, varnotdeclared)
otherparams = list(res.values())
else: otherparams=[]
pa = otherparams + self.visit(node.params)
block = self.visit(node.block)
z = {
'type': "function_definition",
'name': node.name,
'params': pa,
'return_type': node.return_type,
'pseudo_type': node.pseudo_type,
'block': block,
'recursive':self.recursive,
"comments": node.comments
}
return z
[docs]
def visit_module(self, node):
return self.visit(node.block)
[docs]
def visit_test(self, node):
return {"type":"main", "body":self.visit(node.body)}
[docs]
def visit_declaration(self, node):
res = []
for de in node.decl:
if de.name not in self.var:
z = self.visit(de)
self.type_env[z["name"]] = z["pseudo_type"]
res.append(z)
self.var.append(z["name"])
if res:
return {"type" : "declaration", "decl" : res, "comments":node.comments}
else:
pass
[docs]
def visit_float(self, node):
if "value" in dir(node) and "name" in dir(node):
val = self.visit(node.value)
return {'type': 'float', 'name': str(node.name), 'value': val, 'pseudo_type': 'float'}
elif "value" in dir(node):
val = self.visit(node.value)
return {'type': 'float', 'value': val, 'pseudo_type': 'float'}
elif "name" in dir(node): return {'type': 'float', 'name':str(node.name), 'pseudo_type': 'float'}
else: print ("todo doble")
[docs]
def visit_int(self, node):
if "value" in dir(node) and "name" in dir(node):
val = self.visit(node.value)
return {'type': 'int', 'name': str(node.name), 'value': val["value"], 'pseudo_type': 'int'}
elif "value" in dir(node):
val = self.visit(node.value)
return {'type': 'int', 'value': val, 'pseudo_type': 'int'}
elif "name" in dir(node):
return {'type': 'int', 'name':str(node.name), 'pseudo_type': 'int'}
[docs]
def visit_bool(self, node):
if "value" in dir(node) and "name" in dir(node):
val = self.visit(node.value)
return {'type': 'bool', 'name': str(node.name), 'value': val["value"].capitalize() if "value" in val else val.capitalize(), 'pseudo_type': 'bool'}
elif "value" in dir(node):
val = self.visit(node.value)
return {'type': 'bool', 'value': val.capitalize(), 'pseudo_type': 'bool'}
elif "name" in dir(node):
return {'type': 'bool', 'name':str(node.name), 'pseudo_type': 'bool'}
[docs]
def visit_str(self, node):
if "value" in dir(node) and "name" in dir(node):
val = self.visit(node.value)
return {'type': 'str', 'name': node.name, 'value': val["value"], 'pseudo_type': 'str'}
elif "value" in dir(node):
val = self.visit(node.value)
return {'type': 'str', 'value': val, 'pseudo_type': 'str'}
elif "name" in dir(node): return {'type': 'str', 'name':node.name, 'pseudo_type': 'str'}
[docs]
def visit_list(self, node):
if "value" not in dir(node):
z = []
if "elements" in dir(node):
z = self.visit(node.elements)
elif "name" not in dir(node):
z = self.visit(node.init.value)
else:
z = self.visit(node.value.init.value)
res = {'type': 'list',
'elements': z,
'pseudo_type': node.pseudo_type}
if "name" in dir(node):
res["name"] = str(node.name)
return res
if "args" in dir(node):
return {"type": "standard_call",
"function":"copy",
"namespace":"system",
"pseudo_type": node.pseudo_type,
"args": self.visit(node.args[0])
}
if "elements" in dir(node):
return res
[docs]
def visit_array(self, node):
if "name" not in dir(node):
return {'type': 'array',
'elements': self.visit(node.elements),
'pseudo_type': node.pseudo_type}
return {"type":"array",
"name":str(node.name),
"dim": node.dim,
"elts":self.visit(node.elts),
"pseudo_type":node.pseudo_type
}
[docs]
def visit_assignment(self, node):
target = self.visit(node.target)
value = self.visit(node.value)
if "name" in value and (isinstance(value["pseudo_type"], list) and value["pseudo_type"][0]=="list"):
return {'type': 'assignment',
'target': target,
'op': '=',
'value': {"type": "standard_call",
"function":"copy",
"namespace":"system",
"pseudo_type": value["pseudo_type"],
"args": value
},
'pseudo_type': 'Void',
"comments":node.comments}
return {'type': 'assignment',
'target': target,
'op': '=',
'value': value,
'pseudo_type': 'Void',
"comments":node.comments}
[docs]
def visit_if_statement(self, node):
return {'type': 'if_statement',
'test': self.visit(node.test),
'block': self.visit(node.block),
'pseudo_type': 'Void',
'otherwise': self.visit(node.otherwise),
"comments": node.comments}
[docs]
def visit_implicit_return(self, node):
z = self.visit(node.value)
return {'type': 'implicit_return',
'value': z, 'pseudo_type': z['pseudo_type'],
"comments": node.comments}
[docs]
def visit_else_statement(self, node):
return {'type': 'else_statement',
'block': self.visit(node.block),
'pseudo_type': 'Void',
"comments": node.comments}
[docs]
def visit_elseif_statement(self, node):
return {'type': 'elseif_statement',
'test': self.visit(node.test),
'block': self.visit(node.block),
'pseudo_type': 'Void',
"comments": node.comments}
[docs]
def visit_for_range_statement(self, node):
step = self.visit(node.step)
if step["type"] == "unary_op" and step["operator"]=="-":
end = {"type":"binary_op", "op":"-","left":self.visit(node.end), "right":{"type":"int", "value":"1"}}
else:
end ={"type":"binary_op", "op":"+","left":self.visit(node.end), "right":{"type":"int", "value":"1"}}
z = {'type': 'for_range_statement',
'start': self.visit(node.start),
'end': end,
'step': step,
'index': self.visit(node.index),
'block': self.visit(node.block),
"comments": node.comments}
self.decl.append({'type': 'declaration',
'decl': [{'type': z["index"]["pseudo_type"],
'name': z["index"]["name"],
'pseudo_type': z["index"]["pseudo_type"]}]})
return z
[docs]
def visit_binary_op(self, node):
if node.op == "**":
return {
'type': 'standard_call',
'namespace': 'system',
'args': [self.visit(node.left), self.visit(node.right)],
'pseudo_type': node.pseudo_type,
'function': 'pow'
}
return {'type': 'binary_op',
'op': str(node.op),
'left': self.visit(node.left),
'right': self.visit(node.right),
'pseudo_type': node.pseudo_type}
[docs]
def visit_standard_method_call(self, node):
return {'type': 'standard_method_call',
'receiver': self.visit(node.receiver),
'args': self.visit(node.args) if "args" in dir(node) else [],
'message': node.message,
'pseudo_type': node.pseudo_type}
[docs]
def visit_local(self, node):
return {"type":"local", "name":str(node.name), "pseudo_type": node.pseudo_type}
[docs]
def visit_ExprStatNode(self, node):
return {
"type": "ExprStatNode",
"expr": self.visit(node.expr)
}
[docs]
def visit_sliceindex(self, node):
rec = self.visit(node.receiver)
args = self.visit(node.args)
if len(args) == 2:
arg0 = {"type":"binary_op", "op":"-", "left":args[0], "right":{"type":"int", "value":"1", "paseudo_type":"int"}, "pseudo_type":"int"}
return {'type': 'sliceindex',
'receiver': self.visit(node.receiver),
'message': 'sliceindex',
'args': [arg0, args[1]],
'pseudo_type': rec["pseudo_type"]}
else:
return {'type': 'sliceindex',
'receiver': self.visit(node.receiver),
'message': 'sliceindex',
'args': args,
'pseudo_type': rec["pseudo_type"]}
[docs]
def visit_index(self, node):
z = self.visit(node.sequence)
index = self.visit(node.index)
if not isinstance(index, list): index = index
elif isinstance(index, list) and len(index)==1: index = index[0]
else: print("#########TODO") #TODO
#print("bababa", index)
return {'type': 'index',
'sequence': z,
'index': {"type":"binary_op", "op":"-", "left":index, "right":{"type":"int", "value":"1","pseudo_type":"int"}},
'pseudo_type': z["pseudo_type"][-1]}
[docs]
def visit_while_statement(self, node):
return {'type': 'while_statement',
'test': self.visit(node.test),
'block': self.visit(node.block),
'pseudo_type': 'Void'
}
[docs]
def visit_comparison(self, node):
return {'type': 'comparison',
'op': node.op,
'left':self.visit(node.left),
'right': self.visit(node.right),
'pseudo_type': 'Void'}
[docs]
def visit_standard_call(self, node):
return {'type': 'standard_call',
'namespace': node.namespace,
'function': node.function,
'args': self.visit(node.args),
'pseudo_type': node.pseudo_type}
[docs]
def visit_custom_call(self, node):
return {"type": "custom_call",
"args": self.visit(node.args),
"function": node.function,
"pseudo_type": node.pseudo_type}
[docs]
def visit_unary_op(self, node):
return {
'type': 'unary_op',
'operator': str(node.operator),
'value': self.visit(node.value),
'pseudo_type': node.pseudo_type
}
[docs]
def visit_whereconstruct(self, node):
test = self.visit(node.test)
body = self.visit(node.body)
m = transform_to_syntax_tree(body)
r = TransformLocal()
arr = r.process(m)
res = {'type': 'for_statement',
'sequences': {'type': 'for_sequence_with_index',
'sequence': test["left"]},
'iterators': {'type': 'for_iterator_with_index',
'index': {'type': 'local', 'pseudo_type': 'int', 'name': 'i_cyml'},
'iterator': {'type': 'local', 'pseudo_type': test["left"]["pseudo_type"][-1], 'name': 'j_cyml'}},
'block': {'type': 'if_statement',
'test': {'type': 'comparison',
'op': test["op"],
'left': {'type': 'local',
'name': 'j_cyml',
'pseudo_type': test["left"]["pseudo_type"][-1]},
'right': test["right"],
'pseudo_type': 'bool'},
'block': arr,
'pseudo_type': 'Void',
'otherwise': []},
'pseudo_type': 'Void'}
return res