Source code for pycropml.transpiler.antlr_py.csharp.csharpTransformer

from pycropml.transpiler.antlr_py.parse import *
from pycropml.transpiler.errors import *
from pycropml.transpiler.antlr_py.csharp.builtin_typed_api import *
from pycropml.transpiler.antlr_py.csharp.api_transform import *
from pycropml.transpiler.env import Env
from pycropml.transpiler.helpers import *
from pycropml.transpiler.antlr_py import parse
import ast
from ast import AST, arg
[docs] def reduceT(function, iterable, initializer=None): iterable_new = [j for i, j in enumerate(iterable) if i%2!=1] op = [j for i, j in enumerate(iterable) if i%2==1] it = iter(iterable_new) if initializer is None: value = next(it) else: value = initializer for k,element in enumerate(it): value = function(value, element, op[k]) return value
[docs] def treeWalker(node, child): tab =[] for j in node.children: if j==child: tab.append(j) if len(tab)!=0: return tab else: ext_node = treeWalker(node.children, child) if len(ext_node)!=0: return ext_node return None
[docs] class Compilation_unit(AliasNode): _fields_spec = ["using_directives", "namespace_member_declarations"]
[docs] class Namespace_member_declarations(AliasNode): _fields_spec = ["namespace_member_declaration"]
[docs] class Constructor_declaration(AliasNode): _fields_spec = ["identifier", "formal_parameter_list","constructor_initializer", "body"]
[docs] class Constructor_initializer(AliasNode): _fields_spec = ["BASE", "THIS","argument_list" ]
[docs] class Property_declaration(AliasNode): _fields_spec = ["member_name","accessor_declarations","variable_initializer","right_arrow" ,"throwable_expression"]
[docs] class Field_declaration(AliasNode): _fields_spec = [ "variable_declarators"]
[docs] class Enum_definition(AliasNode): _fields_spec = [ "identifier", "enum_base", "enum_body"]
[docs] class Namespace_member_declaration(AliasNode): _fields_spec = ["namespace_declaration", "type_declaration"]
[docs] class Namespace_declaration(AliasNode): _fields_spec = ["qualified_identifier", "namespace_body", "NAMESPACE"]
[docs] class Type_declaration(AliasNode): _fields_spec = ["attributes" ,"all_member_modifiers","class_definition"]
[docs] class Class_body(AliasNode): _fields_spec = ["class_member_declarations"]
[docs] class Attributes(AliasNode): _fields_spec = ["attribute_section"]
[docs] class Namespace_body(AliasNode): _fields_spec = ["extern_alias_directives", "using_directives", "namespace_member_declarations"]
[docs] class Namespace_or_type_name(AliasNode): _fields_spec = ["identifier", "type_argument_list", "qualified_alias_member", "DOT"]
[docs] class Class_member_declarations(AliasNode): _fields_spec = ["class_member_declaration"]
[docs] class Common_member_declaration(AliasNode): _fields_spec = ["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"]
[docs] class Type_(AliasNode): _fields_spec = ["base_type", "INTERR", "rank_specifier", "STAR"]
[docs] class TypeofExpression(AliasNode): _fields_spec = ["unbound_type_name" , "type_" , "VOID"]
[docs] class Base_type(AliasNode): _fields_spec = ['simple_type','class_type', "VOID", "tuple_type"]
[docs] class ParenthesisExpressions(AliasNode): _fields_spec = ['expression']
[docs] class Simple_type(AliasNode): _fields_spec = ['numeric_type', "BOOL"]
[docs] class Class_type(AliasNode): _fields_spec = ['namespace_or_type_name', "OBJECT", "DYNAMIC", "STRING"]
[docs] class Numeric_type(AliasNode): _fields_spec = ['integral_type',"floating_point_type"]
[docs] class Typed_member_declaration(AliasNode): _fields_spec = ["type_","namespace_or_type_name","indexer_declaration","method_declaration","property_declaration", "operator_declaration","field_declaration","REF","READONLY"]
[docs] class Arg_declaration(AliasNode): _fields_spec = ["type_ ", "identifier", "expression"]
[docs] class DeclarationStatement(AliasNode): _fields_spec = ["local_variable_declaration","local_constant_declaration","local_function_declaration"]
[docs] class Local_variable_declaration(AliasNode): _fields_spec = ["local_variable_type", "local_variable_declarator"]
[docs] class Local_variable_type(AliasNode): _fields_spec = ["type_", "VAR"]
[docs] class Local_variable_declarator(AliasNode): _fields_spec = ["identifier","local_variable_initializer"]
[docs] class Local_variable_initializer(AliasNode): _fields_spec = ["expression","array_initializer","stackalloc_initializer"]
[docs] class Expression(AliasNode): _fields_spec = ["assignment","non_assignment_expression"]
[docs] class Relational_expression(AliasNode): _fields_spec = ["shift_expression", 'LT', 'GT', 'OP_LE','OP_GE','IS','isType',"AS","type_"]
[docs] class Shift_expression(AliasNode): _fields_spec = ["additive_expression","right_shift",'OP_LEFT_SHIFT']
[docs] class Additive_expression(AliasNode): _fields_spec = ["multiplicative_expression", "PLUS", "MINUS", ]
[docs] class Multiplicative_expression(AliasNode): _fields_spec = ["switch_expression", 'STAR', 'DIV','PERCENT']
[docs] class ExpressionStatement(AliasNode): _fields_spec = ["expression"]
[docs] class Assignment(AliasNode): _fields_spec = ["unary_expression", "assignment_operator","expression"]
[docs] class Unary_expression(AliasNode): _fields_spec = ["primary_expression", "unary_expression", "TILDE","type_","PLUS","BANG", "MINUS","OP_INC","OP_DEC", "STAR"]
[docs] class Non_assignment_expression(AliasNode): _fields_spec = ["lambda_expression", "query_expression","conditional_expression"]
[docs] class Conditional_expression(AliasNode): _fields_spec = ["null_coalescing_expression", "throwable_expression"]
[docs] class Conditional_and_expression(AliasNode): _fields_spec = ["inclusive_or_expression", "OP_AND"]
[docs] class Conditional_or_expression(AliasNode): _fields_spec = ["conditional_and_expression", "OP_OR"]
[docs] class Inclusive_or_expression(AliasNode): _fields_spec = ["exclusive_or_expression", "BITWISE_OR"]
[docs] class Exclusive_or_expression(AliasNode): _fields_spec = ["and_expression", "CARET"]
[docs] class And_expression(AliasNode): _fields_spec = ["equality_expression","AMP"]
[docs] class Equality_expression(AliasNode): _fields_spec = ["relational_expression", "OP_EQ","OP_NE"]
[docs] class Switch_expression(AliasNode): _fields_spec = ["range_expression", "switch_expression_arms", "SWITCH"]
[docs] class Range_expression(AliasNode): _fields_spec = ["unary_expression","OP_RANGE"]
[docs] class ReturnStatement(AliasNode): _fields_spec = ["expression"]
[docs] class SimpleNameExpression(AliasNode): _fields_spec = ["identifier", "type_argument_list"]
[docs] class LiteralExpression(AliasNode): _fields_spec = ["literal"]
[docs] class Literal(AliasNode): _fields_spec = ["boolean_literal","string_literal","INTEGER_LITERAL","REAL_LITERAL","CHARACTER_LITERAL","NULL"]
[docs] class Type_argument_list(AliasNode): _fields_spec = ["type_"]
[docs] class ObjectCreationExpression(AliasNode): _fields_spec = [ "type_","expression_list","anonymous_object_initializer","rank_specifier","array_initializer","object_creation_expression","object_or_collection_initializer"]
[docs] class DefaultValueExpression(AliasNode): _fields_spec = ["type_" ]
[docs] class Object_creation_expression(AliasNode) : _fields_spec = ["argument_list","object_or_collection_initializer"]
[docs] class Collection_initializer(AliasNode): _fields_spec = ["element_initializer"]
[docs] class Element_initializer(AliasNode): _fields_spec = ["non_assignment_expression","expression_list" ]
[docs] class Array_type(AliasNode): _fields_spec = ["base_type","rank_specifier"]
[docs] class TupleExpression(AliasNode): _fields_spec = ["argument"]
[docs] class IfStatement(AliasNode): _fields_spec = ["expression","if_body","ELSE","IF"]
[docs] class ForStatement(AliasNode): _fields_spec = ["for_initializer","expression","for_iterator","embedded_statement"]
[docs] class WhileStatement(AliasNode): _fields_spec = ["expression","embedded_statement"]
[docs] class ForeachStatement(AliasNode): _fields_spec = ["local_variable_type", "identifier", "expression", "embedded_statement"]
[docs] class Method_invocation(AliasNode): _fields_spec = ["argument_list"]
[docs] class Argument_list(AliasNode): _fields_spec = ["argument"]
[docs] class Argument(AliasNode): _fields_spec = ["identifier", "type_", "REF" , "OUT" , "IN", "expression"]
[docs] class Attribute(AliasNode): _fields_spec = ["namespace_or_type_name", "attribute_argument"]
[docs] class Bracket_expression(AliasNode): _fields_spec = ["indexer_argument"]
[docs] class Interface_definition(AliasNode): _fields_spec = ["INTERFACE", "identifier", "variant_type_parameter_list", "interface_base", "type_parameter_constraints_clauses", "class_body"]
[docs] class SwitchStatement(AliasNode): _fields_spec = ["switch_section", "expression"]
[docs] class Switch_section(AliasNode): _fields_spec = ["switch_label", "statement_list"]
[docs] class Attribute_section(AliasNode): _fields_spec = ["attribute_target", "attribute_list"]
[docs] class Switch_label(AliasNode): _fields_spec = ["expression", "case_guard"]
[docs] class BreakStatement(AliasNode): _fields_spec = ["BREAK"]
[docs] class Class_base(AliasNode): _fields_spec = ["class_type","namespace_or_type_name"]
[docs] class ThrowStatement(AliasNode): _fields_spec = ["THROW", "expression"]
[docs] class Fixed_parameter(AliasNode): _fields_spec = [ "attributes", "parameter_modifier", "arg_declaration", "ARGLIST"]
[docs] class Istype(AliasNode): _fields_spec = ["base_type", "rank_specifier", "isTypePatternArms", "identifier"]
[docs] class Array_initializer(AliasNode): _fields_spec = ["variable_initializer"]
[docs] class Enum_member_declaration(AliasNode): _fields_spec = ["attributes", "identifier", "expression"]
[docs] class BaseAccessExpression(AliasNode): _fields_spec = ["identifier", "type_argument_list", "expression_list"]
[docs] class Transformer(BaseNodeTransformer):
[docs] def visit_Compilation_unit(self, node): return Compilation_unit.from_spec(node)
[docs] def visit_Class_base(self, node): return Class_base.from_spec(node)
[docs] def visit_ThrowStatement(self, node): return ThrowStatement.from_spec(node)
[docs] def visit_SwitchStatement(self, node): return SwitchStatement.from_spec(node)
[docs] def visit_BreakStatement(self, node): return BreakStatement.from_spec(node)
[docs] def visit_Switch_section(self, node): return Switch_section.from_spec(node)
[docs] def visit_Switch_label(self, node): return Switch_label.from_spec(node)
[docs] def visit_Attributes(self, node) : return Attributes.from_spec(node)
[docs] def visit_Attribute(self, node) : return Attribute.from_spec(node)
[docs] def visit_Interface_definition(self, node): return Interface_definition.from_spec(node)
[docs] def visit_Namespace_member_declarations(self, node): return Namespace_member_declarations.from_spec(node)
[docs] def visit_Constructor_declaration(self, node): return Constructor_declaration.from_spec(node)
[docs] def visit_Constructor_initializer(self, node): return Constructor_initializer.from_spec(node)
[docs] def visit_Property_declaration(self, node): return Property_declaration.from_spec(node)
[docs] def visit_Field_declaration(self, node): return Field_declaration.from_spec(node)
[docs] def visit_TypeofExpression(self, node): return TypeofExpression.from_spec(node)
[docs] def visit_Common_member_declaration(self, node): return Common_member_declaration.from_spec(node)
[docs] def visit_Namespace_member_declaration(self, node): return Namespace_member_declaration.from_spec(node)
[docs] def visit_Class_member_declarations(self, node): return Class_member_declarations.from_spec(node)
[docs] def visit_Class_body(self, node): return Class_body.from_spec(node)
[docs] def visit_Local_variable_type(self, node): return Local_variable_type.from_spec(node)
[docs] def visit_DefaultValueExpression(self, node): return DefaultValueExpression.from_spec(node)
[docs] def visit_Namespace_body(self, node): return Namespace_body.from_spec(node)
[docs] def visit_Method_invocation(self, node): return Method_invocation.from_spec(node)
[docs] def visit_Argument_list(self, node): return Argument_list.from_spec(node)
[docs] def visit_Argument(self, node): return Argument.from_spec(node)
[docs] def visit_Namespace_or_type_name(self, node): return Namespace_or_type_name.from_spec(node)
[docs] def visit_Namespace_declaration(self, node): return Namespace_declaration.from_spec(node)
[docs] def visit_Type_(self, node): return Type_.from_spec(node)
[docs] def visit_Base_type(self, node): return Base_type.from_spec(node)
[docs] def visit_Class_type(self, node): return Class_type.from_spec(node)
[docs] def visit_Simple_type(self, node): return Simple_type.from_spec(node)
[docs] def visit_Numeric_type(self, node): return Numeric_type.from_spec(node)
[docs] def visit_Array_type(self, node): return Array_type.from_spec(node)
[docs] def visit_Typed_member_declaration(self, node): return Typed_member_declaration.from_spec(node)
[docs] def visit_Arg_declaration(self, node): return Arg_declaration.from_spec(node)
[docs] def visit_DeclarationStatement(self, node): return DeclarationStatement.from_spec(node)
[docs] def visit_Local_variable_declaration(self, node): return Local_variable_declaration.from_spec(node)
[docs] def visit_Local_variable_declarator(self, node): return Local_variable_declarator.from_spec(node)
[docs] def visit_Local_variable_initializer(self,node): return Local_variable_initializer.from_spec(node)
[docs] def visit_Expression(self,node): return Expression.from_spec(node)
[docs] def visit_Relational_expression(self, node): return Relational_expression.from_spec(node)
[docs] def visit_Shift_expression(self, node): return Shift_expression.from_spec(node)
[docs] def visit_Additive_expression(self, node): return Additive_expression.from_spec(node)
[docs] def visit_Multiplicative_expression(self, node): return Multiplicative_expression.from_spec(node)
[docs] def visit_ParenthesisExpressions(self, node): return ParenthesisExpressions.from_spec(node)
[docs] def visit_ExpressionStatement(self, node): return ExpressionStatement.from_spec(node)
[docs] def visit_Assignment(self, node): return Assignment.from_spec(node)
[docs] def visit_Non_assignment_expression(self, node): return Non_assignment_expression.from_spec(node)
[docs] def visit_Conditional_expression(self, node): return Conditional_expression.from_spec(node)
[docs] def visit_Conditional_and_expression(self,node): return Conditional_and_expression.from_spec(node)
[docs] def visit_Conditional_or_expression(self,node): return Conditional_or_expression.from_spec(node)
[docs] def visit_Inclusive_or_expression(self, node): return Inclusive_or_expression.from_spec(node)
[docs] def visit_Exclusive_or_expression(self, node): return Exclusive_or_expression.from_spec(node)
[docs] def visit_And_expression(self, node): return And_expression.from_spec(node)
[docs] def visit_Equality_expression(self, node): return Equality_expression.from_spec(node)
[docs] def visit_Unary_expression(self, node): return Unary_expression.from_spec(node)
[docs] def visit_TupleExpression(self, node): return TupleExpression.from_spec(node)
[docs] def visit_Switch_expression(self, node): return Switch_expression.from_spec(node)
[docs] def visit_Range_expression(self, node): return Range_expression.from_spec(node)
[docs] def visit_ReturnStatement(self, node): return ReturnStatement.from_spec(node)
[docs] def visit_SimpleNameExpression(self, node): return SimpleNameExpression.from_spec(node)
[docs] def visit_Literal(self, node): return Literal.from_spec(node)
[docs] def visit_Type_argument_list(self, node): return Type_argument_list.from_spec(node)
[docs] def visit_Object_creation_expression(self, node): return Object_creation_expression.from_spec(node)
[docs] def visit_Collection_initializer(self, node): return Collection_initializer.from_spec(node)
[docs] def visit_IfStatement(self, node): return IfStatement.from_spec(node)
[docs] def visit_ForStatement(self, node): return ForStatement.from_spec(node)
[docs] def visit_Enum_definition(self, node): return Enum_definition.from_spec(node)
[docs] def visit_WhileStatement(self, node): return WhileStatement.from_spec(node)
[docs] def visit_ForeachStatement(self, node): return ForeachStatement.from_spec(node)
[docs] def visit_Bracket_expression(self, node): return Bracket_expression.from_spec(node)
[docs] def visit_Fixed_parameter(self, node): return Fixed_parameter.from_spec(node)
[docs] def visit_Istype(self, node): return Istype.from_spec(node)
[docs] def visit_Array_initializer(self, node): return Array_initializer.from_spec(node)
[docs] def visit_Enum_member_declaration(self, node): return Enum_member_declaration.from_spec(node)
[docs] def visit_BaseAccessExpression(self, node): return BaseAccessExpression.from_spec(node)
[docs] def visit_Attribute_section(self, node): return Attribute_section.from_spec(node)
"""def visit_Element_initializer(self, node): return Element_initializer.from_spec(node)"""
[docs] class AstTransformer(): def __init__(self, tree, code: str=None, comments:str=None, env:str=None): self.tree = tree self.base = 0 self.type_env = Env(dict(list(TYPED_API.items())), None)
[docs] def transformer(self): self.type_env['functions'] = {} self.assign = False self.function_name = 'top level' self.definitions = [] self._definition_index = {'functions': {}} self.non_identifier=[] self.decl = [] self.clas = [] self.label = False self.namespace = [] self.top_level(self.tree) body = self.visit(self.tree) return {'body': body if isinstance(body, list) else [body]}
[docs] def top_level(self, tree): pass
[docs] def getpath(self, node, child, tab=[]): if isinstance(node, list): for i in node: self.getpath(i,child) for i in node.children: result = getattr(i, child, None) if result: tab.append(result) elif result is None and "children" in dir(i): self.getpath(i, child, tab) return tab
[docs] def visit(self, node): #if isinstance(node, ParserRuleContext): if isinstance(node, AST): x = node.get_position() fields = {field: getattr(node, field) for field in node._fields }# get_field_names(node) if "self" in fields: fields.pop("self") #l = getattr(node, 'position', None) fields["node"] = node if x: fields['location'] = x["line_start"],x["column_start"] else: fields['location'] = None return getattr(self, 'visit_%s' % type(node).__name__.lower())(**fields)# [:-7] elif 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, dict): return {k: self.visit(v) for k, v in node.items()} else: return node
[docs] def visit_compilation_unit(self,node, using_directives, namespace_member_declarations, location): res, res2 = [], [] if using_directives is None: u = [] else: for n in using_directives: z = n.namespace_or_type_name.identifier res.append(z) for n in res: usin = [str(rs) for rs in n ] us = usin[0] if len(usin)==1 else ".".join(usin) res2.append(us) u = res2 z = self.visit(namespace_member_declarations) return {"type": "module", "using": u, "body": z, "pseudo_type": "Void"}
[docs] def visit_interface_definition(self, node, INTERFACE, identifier, variant_type_parameter_list, interface_base, type_parameter_constraints_clauses, class_body, location): name = self.visit(identifier) self.clas.append(name) body = self.visit(class_body) res = {"type":"interface", "name": name, "block": body } self.clas.pop() return res
[docs] def visit_namespace_member_declarations(self,node, namespace_member_declaration, location): return self.visit(node.children)
[docs] def visit_breakstatement(self, node, BREAK, location): if self.label: return { "type": "breakstatnode" } else: pass
[docs] def visit_switchstatement(self, node, switch_section, expression, location): self._if = 0 selector = self.visit(expression) self.sel.append(selector) body = self.visit(switch_section) ifst = body[0] elsest = body[1:] ifst["otherwise"] = elsest return ifst
[docs] def translate_list(self, inputs): res = [] for arg in inputs: b = self.visit(arg) res.append(b) return res
[docs] def visit_switch_section(self, node, switch_label, statement_list, location): casebody = self.visit(statement_list) res = self.translate_list(switch_label) r = [] if len(res)>=1 and res[0]["type"]!="else_statement": for f in res: f["block"] = casebody r.append(f) return r elif res[0]["type"]=="else_statement": res[0]["block"] = casebody return res[0]
[docs] def visit_switch_label(self, node, expression, case_guard, location): if expression: res = self.visit(expression) test={"type":"comparison", "op": "==", "left":self.sel[-1], "right":res} if self._if ==0: r = {"type":"if_statement", "test":test, "block":[],"otherwise":[]} else: r = {"type":"elseif_statement", "test":test, "block":[]} else: r = {"type":"else_statement", "block":[]} self._if = self._if + 1 return r
[docs] def visit_throwstatement(self, node, THROW, expression, location ): return {"type":"throwexception", "expression":self.visit(expression)}
[docs] def visit_namespace_member_declaration(self,node, namespace_declaration, type_declaration, location): if type_declaration: return self.visit(type_declaration) if namespace_declaration: return self.visit(namespace_declaration)
[docs] def visit_namespace_declaration(self, node,NAMESPACE, qualified_identifier, namespace_body,SEMICOLON, location): namespace_id = self.visit(qualified_identifier) self.namespace.append(namespace_id) z = self.visit(namespace_body) res = {"type":"namespace", "name":namespace_id, "body":z} self.namespace.pop() return res
[docs] def visit_qualified_identifier(self, node, identifier, DOT, location): if len(identifier)==1: return self.visit(identifier[0].IDENTIFIER) res = self.translate_list(identifier) if len(res)==1: return res[0] else: return ".".join(res)
[docs] def visit_namespace_body(self, node,extern_alias_directives, using_directives, namespace_member_declarations, location): r = [] res, res2 = [], [] if using_directives: us = using_directives.children for n in us: z = n.namespace_or_type_name.identifier res.append(z) for n in res: usin = [str(rs) for rs in n ] us = usin[0] if len(usin)==1 else ".".join(usin) res2.append(us) u = res2 r.append(u) if namespace_member_declarations: z = self.visit(namespace_member_declarations.children) r.append(z) return r
[docs] def visit_type_declaration(self,node,class_definition, struct_definition, interface_definition, enum_definition, delegate_definition, attributes, all_member_modifiers, location): if interface_definition: return self.visit(interface_definition) if enum_definition: return self.visit(enum_definition) if struct_definition: return self.visit(struct_definition) if delegate_definition: return self.visit(delegate_definition) if class_definition: name = self.visit(class_definition.identifier) self.clas.append(name) block = self.visit(class_definition.class_body) res = {"type":"classDef", "name": name, "base": self.visit(class_definition.class_base) if class_definition.class_base else None , #TODO "block": block } self.clas.pop() return res if attributes: raise PseudoCythonTypeCheckError("Not implemented attributes , %s"%location)
[docs] def visit_class_base(self, node,class_type,namespace_or_type_name, location): res = [] res.append(self.visit(class_type)) if namespace_or_type_name: v = self.translate_list(namespace_or_type_name) res = res + v return res
[docs] def visit_class_body(self, node, class_member_declarations, location): return self.visit(class_member_declarations)
[docs] def visit_class_member_declarations(self, node, class_member_declaration, location): return self.visit(node.children) """ z = self.getpath(node, "typed_member_declaration") for child in z: if child.method_declaration: name = self.visit(child.method_declaration.method_member_name) name = name[0] rt = self.visit(child.type_) params = self.visit(child.method_declaration.formal_parameter_list) self.definitions.append(('function', name)) if params: self.type_env.top['functions'][name] = ['Function'] +[p["pseudo_type"] for p in params] + [rt["pseudo_type"]] self.type_env.top[name] = self.type_env.top['functions'][name] else: self.type_env.top['functions'][name] = ['Function'] +[None] + [rt["pseudo_type"]] self.type_env.top[name] = self.type_env.top['functions'][name] return self.visit(class_member_declarations.children)"""
[docs] def visit_class_member_declaration(self, node, common_member_declaration, destructor_definition, attributes, all_member_modifiers, location): z = {} x = None y=None if all_member_modifiers is not None: x = self.visit(all_member_modifiers) if attributes is not None: y = self.visit(attributes) if common_member_declaration: z = self.visit(common_member_declaration) if z: if x : z["modifiers"] = x if y : z["attributes"] = y return z
[docs] def visit_attributes(self, node,attribute_section, location): res = [] for attribute in attribute_section: r = self.visit(attribute) res.append(r) return res
[docs] def visit_attribute_section(self, node,attribute_target, attribute_list, location): linkname = None attributelist = self.visit(attribute_list) if attribute_target: linkname = self.visit(attribute_target) res = {"type":"link", "linkname":linkname, "attributes":attributelist} return res
[docs] def visit_attribute_list(self, node,attribute_name, location): return self.visit(attribute_name)
[docs] def visit_common_member_declaration(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): self.sel=[] if throwable_expression: raise PseudoCythonTypeCheckError("Not implemented throwable_expression , %s"%location[0]) if VOID: return_type = "Void" self.non_identifier = [] self.function_name = self.visit(method_declaration.method_member_name)[0] param = self.visit(method_declaration.formal_parameter_list) ps = [p["pseudo_type"] for p in param] if param else [None] block = self.visit(method_declaration.method_body) modifiers = [] if param: for p in param: if "modifier" in p: modifiers.append(p) if modifiers: if block[-1] is None: del block[-1] if block[-1] is not None and block[-1]["type"] == "implicit_return": if isinstance(block[-1]["value"], dict): block[-1]["value"] = {"type":"tuple", "elements":[block[-1]["value"]] + modifiers} else: block[-1]["value"] = {"type":"tuple", "elements":block[-1]["value"] + modifiers} return_type = ["tuple"] + [p["pseudo_type"] for p in block[-1]["value"]["elements"] ] else: if len(modifiers) == 1: block.append({"type":"implicit_return", "value":modifiers[0], "modifiers":True}) return_type = modifiers[0]["pseudo_type"] else: block.append({"type":"implicit_return", "value":{"type":"tuple", "elements":modifiers}, "modifiers":True}) return_type = ["tuple"] + [p["pseudo_type"] for p in modifiers] v = {"type":"methodDef", "name":self.function_name, "params":param, "return_type":return_type, "block":block, "pseudo_type":["function"]+ps + ["Void"], "non_identifier":self.non_identifier, "namespace":self.namespace[-1] if self.namespace else None, "class_":self.clas[-1]} return v if constructor_declaration: return self.visit(constructor_declaration) elif typed_member_declaration: return self.visit(typed_member_declaration) elif enum_definition: return self.visit(enum_definition) elif constant_declaration: return self.visit(constant_declaration) elif event_declaration: pass elif class_definition: pass else: raise PseudoCythonTypeCheckError("Not implemented common member declaration , %s"%location[0])
[docs] def visit_constructor_declaration(self, node, identifier, formal_parameter_list,constructor_initializer, body, location): z={} z["type"] = "constructorDef" z["name"]= self.visit(identifier) z["parameters"] = self.visit(formal_parameter_list) if formal_parameter_list else None if constructor_initializer : z["init"] = self.visit(constructor_initializer) z["block"] = self.visit(body) if body else [] return z
[docs] def visit_block(self, node, location, statement_list): if statement_list : return [] return self.visit(statement_list)
[docs] def visit_constructor_initializer(self, node, location, BASE, THIS, argument_list): p = "THIS" if THIS else BASE arg = self.visit(argument_list) if argument_list else [] return {"type":"constructor_init", "keyw":p, "args": arg, "pseudo_type":"Void"}
[docs] def visit_property_declaration(self, node,member_name, accessor_declarations,variable_initializer,right_arrow ,throwable_expression, location): res = {} res["name"] = self.visit(member_name) accessors = self.visit(accessor_declarations) if accessors is None: if throwable_expression: res["throw"] = self.visit(throwable_expression) return res res["get"] = accessors["get"] res["set"] = accessors["set"] return res
[docs] def visit_accessor_declarations(self, node, attributes, accessor_modifier, GET, accessor_body, set_accessor_declaration, SET, get_accessor_declaration, location): setbody, getbody = None, None if GET: getbody = self.visit(accessor_body) if set_accessor_declaration: setbody = self.visit(accessor_body) if SET: setbody = self.visit(accessor_body) if get_accessor_declaration: getbody = self.visit(accessor_body) return {"get":getbody, "set":setbody}
[docs] def visit_member_name(self, node,namespace_or_type_name, location): return self.visit(namespace_or_type_name)
[docs] def visit_field_declaration(self, node, variable_declarators, location): res = {} s = self.visit(variable_declarators) if isinstance(s, list): s = s[0] if "init" in s: res["name"] =s["name"] res["init"] = s["init"] else: res["name"] = s return res
[docs] def visit_variable_declarators(self, node,variable_declarator, location): r=[] if isinstance(variable_declarator, list): r.append(self.visit(variable_declarator)) else: return self.visit(variable_declarator) return r
[docs] def visit_defaultvalueexpression(self, node,type_, location): return {"type":"custom_call", "name":"default", "args": self.visit("type")}
[docs] def visit_variable_declarator(self, node, identifier,ASSIGNMENT, variable_initializer, location): if variable_initializer is None: return self.visit(identifier) else: return {"name":self.visit(identifier), "init":self.visit(variable_initializer)}
[docs] def visit_typed_member_declaration(self, node, type_, namespace_or_type_name, indexer_declaration, method_declaration, property_declaration, operator_declaration, field_declaration, REF, READONLY, location): z = {} self.sel= [] typ = self.visit(type_) if namespace_or_type_name: res = {"type":"namespace", "block":self.visit(namespace_or_type_name)} if indexer_declaration: res = {"type":"indexer", "block":self.visit(indexer_declaration)} if method_declaration: self.non_identifier = [] self.function_name = self.visit(method_declaration.method_member_name)[0] param = self.visit(method_declaration.formal_parameter_list) ps = [p["pseudo_type"] for p in param] if param else [None] if method_declaration.right_arrow: block = {"type":"implicit_return", "value":self.visit(method_declaration.throwable_expression)} else: block = self.visit(method_declaration.method_body) modifiers = [] if param: for p in param: if "modifier" in p: modifiers.append(p) if modifiers: if isinstance(block[-1]["value"], dict): block[-1]["value"] = {"type":"tuple", "elements":[block[-1]["value"]] + modifiers} else: block[-1]["value"] = {"type":"tuple", "elements":block[-1]["value"] + modifiers} res = {"type":"methodDef", "name":self.function_name, "return_type" :typ["pseudo_type"], "params":param, "block":block, "pseudo_type":["function"] + ps + [typ["pseudo_type"]], "non_identifier":self.non_identifier, "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"]] if property_declaration: r = self.visit(property_declaration) pseudo = typ if isinstance(typ, str) else typ["pseudo_type"] self.type_env.top[r["name"]] = pseudo if "throw" in r: return {"type":"propertyDef", "name":r["name"], "throw":r["throw"], "pseudo_type":pseudo} return {"type":"propertyDef", "name":r["name"], "get":r["get"], "set":r["set"], "pseudo_type":pseudo} if operator_declaration: res = {"type":"operator", "block":self.visit(operator_declaration)} if field_declaration: r = self.visit(field_declaration) z = r["name"][0] if isinstance(r["name"], list) else r["name"] self.type_env.top[str(z)] = typ["pseudo_type"] res = {"type":"fielddecl", "name":str(z), "pseudo_type":typ["pseudo_type"]} if "init" in r: res["init"] = r["init"] return res
[docs] def visit_type_(self, node,INTERR,rank_specifier,STAR, base_type, location): if rank_specifier: return self.visit_array_type(node,base_type,location) if base_type.simple_type: res = base_type.simple_type if base_type.class_type: res = base_type.class_type re = self.visit(res) if STAR : re["operator"] = "*" return re
[docs] def visit_base_type(self, node,simple_type,class_type,VOID, tuple_type, location): if simple_type: res = simple_type if class_type: res = class_type if VOID: return "VOID" if tuple_type: res = self.visit(tuple_type) return self.visit(res)
[docs] def visit_array_type(self,node,base_type,location): z = self.visit(base_type) res = {} res["type"] = "array" res["pseudo_type"] = ["array",z["type"]] return res
[docs] def visit_namespace_or_type_name(self, node, identifier,type_argument_list,qualified_alias_member,DOT, location) : #names=[] if qualified_alias_member is not None: raise PseudoCythonTypeCheckError("Not implemented quaified alias member , %s"%location[0]) if len(identifier)==1: #res = self.visit(identifier[0].IDENTIFIER) res = self.visit(identifier[0]) else: res = self.translate_list(identifier) if not type_argument_list : if isinstance(res, str): return res elif len(res)==1: return res[0] else: z = ".".join(res) return {"type":"objectcreation", "typename": z, "pseudo_type":z.split(".")[-1] } else: targ = self.visit(type_argument_list) if len(targ)==1: if isinstance(targ[0], dict): targ = [targ[0]["pseudo_type"]] if isinstance(res, str): return [res] + targ elif len(res)==1: return res[0] + targ else: z = ".".join(res) return {"type":"objectcreation", "typename": z, "pseudo_type":[z.split(".")[-1]] + targ} """ if len(type_argument_list) == 0: if len(identifier)>1: for id in identifier: names.append(str(id)) z= ".".join(names) res2 = {"type":"objectcreation", "typename": z, "pseudo_type":z.split(".")[-1] } else: z= str(identifier[0]) res2 = z else: if qualified_alias_member is not None: raise PseudoCythonTypeCheckError("Not implemented quaified alias member , %s"%location) else: r = self.visit(type_argument_list) res2=[str(identifier[0]),str(r[0]["type"])] return res2 """
[docs] def visit_objectcreationexpression(self, node,NEW,OPEN_BRACKET,expression_list,CLOSE_BRACKET, type_, anonymous_object_initializer, rank_specifier, array_initializer, object_creation_expression, object_or_collection_initializer, location): z = self.visit(type_) if isinstance(z, list): z = z[0] if object_creation_expression: z_oce = self.visit(object_creation_expression) if len(z_oce["args"]) > 0: return {"type":z["type"], "args": z_oce["args"], "init":z_oce["init"], "pseudo_type":z["pseudo_type"]} else: if z_oce["init"]: return {"type":z["type"], "args": [], "init":z_oce["init"], "pseudo_type":z["pseudo_type"]} else: return {"type":z["type"], "init": [], "args":[], "pseudo_type":z["pseudo_type"]} elif object_or_collection_initializer: z_oci = self.visit(object_or_collection_initializer) return {"type":z["type"], "init":z_oci["init"], "pseudo_type":z["pseudo_type"]} # elif expression_list: dimLen = self.visit(expression_list) # TODO dim = len(dimLen) size = dimLen z["init"] = {"type":"initArray", "value": self.visit(array_initializer) if array_initializer else None} #return {"type":"array"} if array_initializer: return {"type":"array", "dim": dim, "elts":size, "init":z["init"], "pseudo_type":["array",z["pseudo_type"]]} else: return {"type":"array", "dim": dim, "elts":size, "pseudo_type":["array",z["pseudo_type"]]} elif rank_specifier: dim = len(rank_specifier) if array_initializer : init = self.visit(array_initializer) init["dim"] = dim return init #{"type":"array", "dim":dim, "init": init, "pseudo_type": ["array", init[0]["pseudo_type"]]} #raise PseudoCythonTypeCheckError("Not implemented array initializer , %s"%location[0]) else: raise PseudoCythonTypeCheckError("Not implemented object creation , %s"%location[0])
#return z["type"]
[docs] def visit_object_initializer(self, node,member_initializer_list, location): z = {} if member_initializer_list: z["init"] = self.visit(member_initializer_list) else: z["init"] = [] return z
[docs] def visit_array_initializer(self, node,variable_initializer, location): r = self.visit(variable_initializer) res = {"type":"array", "init":{"type":"initCollection", "value": r}, "pseudo_type": ["array", r[0]["pseudo_type"]], "size": str(len(r))} return res """if len (node.children)==1: res = self.visit(variable_initializer) else: args = map(lambda n:self.visit(n), node.children) args = [arg[0] for arg in args if isinstance(arg, list)] return args"""
[docs] def visit_object_creation_expression(self, node, argument_list,object_or_collection_initializer, location): z = {} if argument_list: z["args"] = self.visit(argument_list) else: z["args"]=[] if object_or_collection_initializer: x = self.visit(object_or_collection_initializer) if "init" in x: z["init"] = x["init"] else: z["init"] = x else: z["init"] = [] return z
[docs] def visit_argument_list(self, node, argument,location): res = [] for arg in argument: b = self.visit(arg) res.append(b) return res
[docs] def visit_enum_definition(self, node, identifier, enum_base, enum_body, location): #TODO id = self.visit(identifier) if enum_base: print("ENUM BASE TODO") body = self.visit(enum_body) return {"type":"enum", "name": id, "block":body, "namespace":self.namespace[-1], "class_":self.clas[-1] }
[docs] def visit_collection_initializer(self, node,element_initializer, location): res={} if len (node.children)==1: ini = self.visit(element_initializer) else: args = map(lambda n:self.visit(n), node.children) ini = [arg[0] for arg in args if arg[0] not in ['{','}',","]] res["init"] = {"type":"initCollection", "value":ini} return res
[docs] def visit_element_initializer(self, node, non_assignment_expression, expression_list, location): if non_assignment_expression: return self.visit(non_assignment_expression) if expression_list: return self.visit(expression_list)
[docs] def visit_simple_type(self, node,numeric_type,BOOL, location): if numeric_type: return self.visit(numeric_type) if BOOL: return {"type":"bool", "pseudo_type":"bool"}
[docs] def visit_class_type(self, node,namespace_or_type_name, OBJECT, DYNAMIC, STRING, location): if namespace_or_type_name: x = self.visit(namespace_or_type_name) typ = x[0] if isinstance(x, list) else x return {"type":typ, "pseudo_type":x} if OBJECT: return {"type":"object", "pseudo_type":"object"} if DYNAMIC: return self.visit(DYNAMIC) if STRING: return {"type":"string", "pseudo_type":"string"}
[docs] def visit_type_argument_list(self, node,type_, location): return self.visit(type_)
[docs] def visit_numeric_type(self, node,integral_type,floating_point_type, location): if integral_type: if integral_type=="int": return {"type":"int", "pseudo_type":"int"} elif integral_type=="long": return {"type":"int", "pseudo_type":"int"} elif integral_type=="char": return {"type":"char", "pseudo_type":"char"} else: raise PseudoCythonTypeCheckError("Not implemented integral type , %s"%location[0]) if floating_point_type: if floating_point_type=="float": return {"type":"float", "pseudo_type":"float"} elif floating_point_type=="double": return {"type":"double", "pseudo_type":"double"} else: raise PseudoCythonTypeCheckError("Not implemented floating , %s"%location)
[docs] def visit_arg_declaration(self, node, type_, identifier, expression, location): z= {"type":"local","name":self.visit(identifier), "pseudo_type":self.visit(type_)["pseudo_type"]} self.type_env[z["name"]]=z["pseudo_type"] return z
[docs] def visit_declarationstatement(self, node, local_variable_declaration, local_constant_declaration, local_function_declaration, location): if local_variable_declaration: return self.visit(local_variable_declaration) if local_constant_declaration: return self.visit(local_constant_declaration) if local_function_declaration : raise PseudoCythonTypeCheckError("Not implemented local constant declaration , %s"%location[0])
[docs] def visit_local_constant_declaration(self, node, CONST, type_, constant_declarators, location): res = {} res["type"] = "declaration" res["decl"] = [] typ = self.visit(type_) decls = self.visit(constant_declarators) for d in decls: d["type"] = typ["pseudo_type"] res["decl"].append(d) return res
[docs] def visit_constant_declarator(self, node, identifier, expression, ASSIGNMENT, location): name = self.visit(identifier) value = self.visit(expression) pseudo_type = value["pseudo_type"] #if "value" in value: value = value["value"] # Majeur return {"value": value, "name": name, "pseudo_type":pseudo_type}
[docs] def visit_constant_declaration(self, node, CONST ,type_, constant_declarators, SEMICOLON, location): return self.visit_local_constant_declaration(node, CONST, type_, constant_declarators, location)
[docs] def visit_local_variable_type(self, node, VAR, type_, location): if type_: res = self.visit(type_) else: res = {"type":"var", "pseudo_type":"var"} return res
[docs] def visit_local_variable_declaration(self, node, local_variable_type, local_variable_declarator, location): var = local_variable_declarator if not isinstance(var, list): var = [var] z = {} z["type"] = "declaration" z["decl"] = [] t = self.visit(local_variable_type) for d in var: r = self.visit(d) if r["value"] is not None: if r["value"]["type"] == "if_statement": res1 = {"type":"declaration", "decl":{"type": t["type"], "name":r["name"], "pseudo_type":t["pseudo_type"]}} self.type_env[str(r["name"])] = t["pseudo_type"] res2 = {"type":"if_statement", "test":r["value"]["test"], "block":{"type":"assignment", "target": {"type":"local", "name": r["name"], "pseudo_type":t["pseudo_type"]}, "value":r["value"]["block"], "pseudo_type":"Void", "op":"="}, "otherwise":{ "type":"assignment", "target": {"type":"local", "name": r["name"], "pseudo_type":t["pseudo_type"]}, "value":r["value"]["otherwise"],"op":"=", "pseudo_type":"Void" }, 'pseudo_type': 'Void' } return [res1, res2] """if (t["pseudo_type"]!=r["value"]["pseudo_type"]) and (r["value"]["pseudo_type"]!="todooo") : raise type_check_error('bad declaration at line %s and column %s'%(location[0],location[1]))""" val = r["value"] if isinstance(t, dict): pseudo_type = t["pseudo_type"] type_ = t["type"] else: pseudo_type = val["pseudo_type"] type_ = val["pseudo_type"] res = {"type": type_, "name":r["name"], "value":val, "pseudo_type":pseudo_type} if res["value"] is None: del res["value"] if pseudo_type == "var" and "value" in res: res["pseudo_type"] = res["value"]["pseudo_type"] res["type"] = res["value"]["pseudo_type"][0] if isinstance(res["value"]["pseudo_type"], list) else res["value"]["pseudo_type"] z["decl"].append(res) self.type_env[str(res["name"])] = res["pseudo_type"] return z
[docs] def visit_local_variable_declarator(self, node, identifier, local_variable_initializer, location): name = self.visit(identifier) return {"name":name, "value":self.visit(local_variable_initializer)}
[docs] def visit_local_variable_initializer(self, node, expression,array_initializer,stackalloc_initializer,location): if array_initializer: z = self.visit(array_initializer) return z # {"type":"array", "value":z, "pseudo_type":["array","%s"%z[0]["pseudo_type"]]} if expression: return self.visit(expression) if stackalloc_initializer: print(f"stackalloc_initializer is not implemented at {location}")
[docs] def visit_expression(self, node, assignment, non_assignment_expression, location): if non_assignment_expression: x = self.visit(non_assignment_expression) return x[0] if isinstance(x, list) else x if assignment: return self.visit(assignment)
[docs] def visit_assignment(self, node, unary_expression,assignment_operator,expression, location): if assignment_operator: self.assign= True z = { 'type': 'assignment', 'target':self.visit(unary_expression), 'op':str(assignment_operator), 'value': self.visit(expression), 'pseudo_type': 'Void' } if z["value"]["type"] == "custom_call": arg_modifiers = [] args = z["value"]["args"] if args and args[0]: for arg in args: if "modifiers" in arg: arg_modifiers.append(arg) if arg_modifiers: if z["target"]["type"]=="tuple": z["target"] = {"type":"tuple", "elements":z["target"]["elements"] + arg_modifiers, "pseudo_type":"unknown"} else: z["target"] = {"type":"tuple", "elements":[z["target"]] + arg_modifiers, "pseudo_type":"unknown"} self.assign = False """r = z["value"]["pseudo_type"] if "Function" in z["value"]["pseudo_type"]: r = z["value"]["pseudo_type"][-1] if z["target"]["pseudo_type"]!="double" and z["target"]["pseudo_type"]!=r: jj = (z["target"]["pseudo_type"]!="double" and z["target"]["pseudo_type"]!=r) raise type_check_error( ' Cannot implicitly convert type %s from %s to %s at line %s. An explicit conversion exists (are you missing a cast11? %s)'%(z["target"]["name"],z["target"]["pseudo_type"], z["value"]["pseudo_type"], location[0], jj))""" return z else: raise PseudoCythonTypeCheckError("Not yet implemented part of assignment , %s"%location)
[docs] def visit_non_assignment_expression(self, node, lambda_expression, query_expression, conditional_expression, location): if lambda_expression: raise PseudoCythonTypeCheckError("Not implemented lambda expression , %s"%location) if query_expression: raise PseudoCythonTypeCheckError("Not implemented query_expression , %s"%location) return self.visit(conditional_expression)
[docs] def visit_conditional_expression(self, node,null_coalescing_expression,throwable_expression, location): if null_coalescing_expression: res = self.visit(null_coalescing_expression) if throwable_expression: bodyif = self.visit(throwable_expression[0]) bodyelse = self.visit(throwable_expression[1]) res = { 'type': 'cond_expr_node', 'test': res, 'true_val': bodyif, 'pseudo_type': 'Void', 'false_val': bodyelse } return res
[docs] def visit_expressionstatement(self, node, expression, location): return self.visit(expression)
[docs] def visit_conditional_and_expression(self, node, inclusive_or_expression, OP_AND, location): if len(node.children)==1: return self.visit(inclusive_or_expression) args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"comparison", "op":op, "left":x if not isinstance(x, list) else x[0], "right":y if not isinstance(y, list) else y[0], "pseudo_type":"bool"}, list(args))
[docs] def visit_conditional_or_expression(self, node, conditional_and_expression, OP_OR, location): if len(node.children)==1: return self.visit(conditional_and_expression) args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"comparison", "op":op, "left":x if not isinstance(x, list) else x[0], "right":y if not isinstance(y, list) else y[0], "pseudo_type":"bool"}, list(args))
[docs] def visit_tupleexpression(self, node, argument, location): res = [] for arg in argument: z = self.visit(argument) res.append(z) return res
[docs] def visit_inclusive_or_expression(self, node, exclusive_or_expression, BITWISE_OR, location): if len(node.children)==1: return self.visit(exclusive_or_expression) args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"comparison", "op":op, "left":x if not isinstance(x, list) else x[0], "right":y if not isinstance(x, list) else y[0], "pseudo_type":"bool"}, list(args))
[docs] def visit_exclusive_or_expression(self, node, and_expression, CARET, location): if len(node.children)==1: return self.visit(and_expression) args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"comparison", "op":op, "left":x if not isinstance(x, list) else x[0], "right":y if not isinstance(x, list) else y[0], "pseudo_type":"bool"}, list(args))
[docs] def visit_and_expression(self, node, equality_expression, AMP, location ): if len(node.children)==1: return self.visit(equality_expression) args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"comparison", "op":op, "left":x if not isinstance(x, list) else x[0], "right":y if not isinstance(x, list) else y[0], "pseudo_type":"bool"}, list(args))
[docs] def visit_equality_expression(self, node, relational_expression, OP_EQ,OP_NE,location): if len(node.children)==1: return self.visit(relational_expression) args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"comparison", "op":op, "left":x[0], "right":y[0], "pseudo_type":"bool"}, list(args))
[docs] def visit_relational_expression(self, node,shift_expression,LT, GT,OP_LE,OP_GE,IS,isType,AS,type_,location): if len(shift_expression)==1 and isType: left = self.visit(shift_expression) right = self.visit(isType) return {"type":"isExpression", "left": left, "right":right, "pseudo_type":"Void"} if len(shift_expression)==1 and AS: left = self.visit(shift_expression) right = self.visit(type_) return {"type":"isExpression", "left": left, "right":right, "pseudo_type":"Void"} if len(node.children)==1: return self.visit(shift_expression) else: args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"comparison", "op":op, "left":x, "right":y, "pseudo_type":"bool"}, list(args))
[docs] def visit_istype(self, node, base_type, rank_specifier, isTypePatternArms, identifier, location): typ = self.visit(base_type) if identifier: return {"type":typ, "name":self.visit(identifier)} else: return {"type":typ, "pseudo_type":typ}
[docs] def visit_shift_expression(self, node, additive_expression,OP_LEFT_SHIFT, right_shift, location): if len(node.children)==1: return self.visit(additive_expression)[0] else: #op = OP_LEFT_SHIFT if OP_LEFT_SHIFT else right_shift args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"binary_op", "op":op, "left":x, "right":y}, list(args))
[docs] def visit_additive_expression(self, node,multiplicative_expression, PLUS,MINUS,location): if len(node.children)==1: return self.visit(multiplicative_expression) else: args = map(lambda n:self.visit(n), node.children) args = [arg[0] if isinstance(arg, list) else arg for arg in args] return reduceT(lambda x,y, op: {"type":"binary_op", "op":op,"left":x, "right":y, "pseudo_type":TYPED_API['operators'][op]( x['pseudo_type'], y['pseudo_type'])[-1]}, list(args))
[docs] def visit_multiplicative_expression(self, node,switch_expression, STAR,DIV,PERCENT, location): if len(node.children)==1: return self.visit(switch_expression) else: args = map(lambda n:self.visit(n), node.children) return reduceT(lambda x,y, op: {"type":"binary_op", "op":op, "left":x, "right":y,"pseudo_type":TYPED_API['operators'][op]( x['pseudo_type'], y['pseudo_type'])[-1]}, list(args))
[docs] 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 if type_: tp = self.visit(type_) receiver = self.visit(unary_expression) if receiver["pseudo_type"] != tp["type"]: return {"type":"standard_method_call", "message":tp["type"], "receiver":receiver, "pseudo_type":tp["pseudo_type"]} else: return receiver if unary_expression: if PLUS : op = PLUS elif MINUS : op = MINUS elif OP_INC : op = OP_INC elif OP_DEC : op = OP_DEC elif BANG : op = "not" elif STAR: op = STAR elif TILDE: op = TILDE #else: raise PseudoCythonTypeCheckError("Not implemented unary operator , %s"%location) z = self.visit(unary_expression) if op =="not": z["pseudo_type"] = "bool" res = { 'type': 'unary_op', 'operator': op, 'value': z, 'pseudo_type': z["pseudo_type"] } if op =="not" and z["type"]=="standard_method_call" and z["message"] == "contains?": z["message"] = "not contains?" return z return res
[docs] def visit_returnstatement(self, node,expression,location): z = self.visit(expression) if z: return {'type': 'implicit_return', 'value':z , "pseudo_type":z["pseudo_type"]} else: return {'type': 'implicit_return', 'value':None , "pseudo_type":"Void"}
[docs] def visit_switch_expression(self, node,range_expression,SWITCH,switch_expression_arms, location): if len(node.children)==1: return self.visit(range_expression) else: lhs = self.visit(range_expression) rhs = self.visit(switch_expression_arms) return {"type":"switch", "op":"switch", "left":lhs, "right": rhs}
[docs] def visit_range_expression(self, node,unary_expression,OP_RANGE, location): if len(node.children)==1: res = self.visit(unary_expression) return res[0] else: if OP_RANGE: raise PseudoCythonTypeCheckError("Not implemented OP_RANGE, %s"%location)
[docs] def visit_terminal(self, node, value, location): return self.visit(value)
[docs] def translate(self, member_access): if len(member_access)==1: r = self.visit(member_access) return r[0] else: z = [] for m in member_access: z.append(self.visit(m)) return '.'.join(z)
[docs] def visit_primary_expression(self, node,primary_expression_start,OP_INC,BANG,OP_PTR,identifier, OP_DEC,member_access,method_invocation,bracket_expression, location ): res = self.visit(primary_expression_start) if BANG or OP_PTR or identifier: raise PseudoCythonTypeCheckError("Not implemented, %s"%location) if member_access: 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 "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 "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: raise translation_error('CyMLTx doesn\' t support property %s of %s' % (m, receiver), location, [location[0]], suggestions='CyMLTx supports those %s functions\n %s' % ( receiver, prepare_table(TYPED_API[receiver], ORIGINAL_METHODS.get(receiver)).strip())) elif not isinstance(api, dict): z = api.expand([rec]) return z if method_invocation: args = self.visit(method_invocation) if member_access: if isinstance(m, dict) and m["type"] == "method_invocation": return res elif m.find(".") == -1: method = m 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]) 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: raise translation_error('pseudo-cython doesn\' t support %s %s' % (receiver, method), location, [location[0]], suggestions='pseudo-cython supports those %s functions\n %s' % ( receiver, prepare_table(TYPED_API[receiver], ORIGINAL_METHODS.get(receiver)).strip())) elif not isinstance(api, dict): z = api.expand(args ) return z else: for count, (a, b) in enumerate(list(api.items())): if len(args) == a: return b.expand(args) raise translation_error( '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) if api: res = api.expand([rec]+ args) if self.assign == False and "message" in res and res["message"] not in ("contains?", "index", "len"): res = {"type": 'ExprStatNode', 'expr': res} if not api: raise translation_error('CyMLT doesn\' t support %s %s at line %s' % (receiver_type, method,location[0]), suggestions='CyMLT supports those %s functions\n %s' % ( receiver, prepare_table(TYPED_API[receiver_type], ORIGINAL_METHODS.get(receiver_type)).strip())) else: res["member"] = receiver.split(".")[-1] res = {'type': 'custom_call', 'namespace': res, "function":method, 'args': args, 'pseudo_type': "unknown", "class_": self.clas[-1]} #TODO #if self.assign == False: #res = {"type": 'ExprStatNode', 'expr': res} else: if res in ("int", "float", "double", "ToInt32"): if res == "ToInt32": res = "int" if args[0]["pseudo_type"]!=res: res = {'type': 'standard_method_call', 'receiver': args[0], 'args': [], 'message': res, 'pseudo_type': res} else: res = args[0] else: fname = res["name"] c = self.type_env.top['functions'] if fname in c: pseudo_type = c[fname][-1] else: pseudo_type="unknown" res = { "type": "custom_call", "args": args, "function": res["name"], "pseudo_type":pseudo_type, } ####Todooooooo if bracket_expression: t = self.visit(bracket_expression) res = {'type': 'index', 'sequence': res, 'index': t, 'pseudo_type': res["pseudo_type"][1] if isinstance(res["pseudo_type"], list) else res["pseudo_type"] } if OP_DEC: res = {'type': 'unary_op', 'operator': OP_DEC[0], 'value': res } if OP_INC: res = {'type': 'unary_op', 'operator': OP_INC[0], 'value': res } return res
[docs] def visit_baseaccessexpression(self, node,identifier, type_argument_list, expression_list , location): return { "type":"baseaccess", "class_type":"base", "name": self.visit(identifier), "args": self.visit(type_argument_list) if type_argument_list else [] }
[docs] def visit_typeofexpression(self, node, unbound_type_name , type_ , VOID,location): if unbound_type_name is not None: r = self.visit(unbound_type_name) elif type_: r = self.visit(type_) elif VOID: r = "VOID" res = {"type":"typeofexpression", "class_type":r} return res
[docs] def visit_unbound_type_name(self, node, identifier, DOUBLE_COLON,DOT,generic_dimension_specifier, location): if not generic_dimension_specifier: if isinstance(identifier, list): return ".".join(self.visit(identifier)) else: return self.visit(identifier) else: raise PseudoCythonTypeCheckError("Not implemented")
[docs] def visit_bracket_expression(self, node,indexer_argument, location): if len(indexer_argument) ==1: k = self.visit(indexer_argument) return k else: raise PseudoCythonTypeCheckError("Not implemented bracket expression , %s"%location[0]) return
[docs] def visit_simplenameexpression(self, node,identifier,type_argument_list, location): id_type = self.type_env.top[self.visit(identifier)] if id_type is None: self.non_identifier.append(self.visit(identifier)) """ raise type_check_error( '%s is not defined at line %s and column %s' %(str(identifier), location[0], location[1]))""" # remove cote return {"type":"local", "name": self.visit(identifier), "pseudo_type":id_type}
[docs] def visit_member_access(self, node,identifier, type_argument_list,DOT,INTERR, location): res = self.visit(identifier) if type_argument_list: argument_list = self.visit(type_argument_list) return {"type":"method_invocation", "name":res, "args":argument_list} #raise PseudoCythonTypeCheckError("Not implemented type_argument_list , %s"%location) return res
[docs] def visit_method_invocation(self, node,argument_list, location): return self.visit(argument_list)
[docs] def visit_argument(self, node, location, type_,REF , OUT , IN, identifier, expression): r = self.visit(expression) if REF: r["modifiers"] = "ref" if type_: r2 = self.visit(type_) op = str(r["operator"]) if "operator" in r else str(r2["operator"]) right = r["value"] if "value" in r else r left = {"type":"local", "name":r2["type"], "pseudo_type":self.type_env.top[r2["type"]]} return {"type":"binary_op", "left":left, "op": op, "right":right, "pseudo_type": TYPED_API['operators'][op]( left['pseudo_type'], r['pseudo_type'])[-1]} else: return r
[docs] def visit_literalexpression(self, node,literal,location): return self.visit(literal)
[docs] def visit_literal(self, node,boolean_literal,string_literal,INTEGER_LITERAL,REAL_LITERAL,CHARACTER_LITERAL,NULL,location): if boolean_literal: return {'type': 'bool', 'value': self.visit(boolean_literal), 'pseudo_type': 'bool'} if INTEGER_LITERAL: return {'type': 'int', 'value': self.visit(INTEGER_LITERAL), 'pseudo_type': 'int'} if REAL_LITERAL: val = self.visit(REAL_LITERAL) if val.endswith("d"): return {'type': 'double', 'value': val[:-1], 'pseudo_type': 'double'} else: return {'type': 'float', 'value': val, 'pseudo_type': 'float'} if CHARACTER_LITERAL: return {'type': 'char', 'value': str(self.visit(CHARACTER_LITERAL)), 'pseudo_type': 'char'} if string_literal: val = str(string_literal) if '"' in val: val = val.replace('"', '') val = val.encode('utf-8') return {'type': 'string', 'value': ensure_text(val), 'pseudo_type': 'string'} if NULL: return {'type':"none", "value":"none", "pseudo_type":"none"}
[docs] def visit_ifstatement(self, node,expression,if_body, location,ELSE,IF): otherwise = [] if len(if_body)==1: test = self.visit(expression) block = self.visit(if_body) else: test = self.visit(expression) block = self.visit(if_body[0]) while(node.ELSE and "IF" in dir(node.if_body[1])): z = node.if_body[1] elseif = z.if_body[0] r = self.visit_ifclausenode(z, z.expression, elseif) otherwise.append(r) node = z if "IF" not in dir(node) or "ELSE" not in dir(node): break if "ELSE" in dir(node) and node.ELSE: r = self.visit_elseStatement(node.if_body[1]) otherwise.append(r) R = { 'type': 'if_statement', 'test': test, 'block': block, 'pseudo_type': 'Void', 'otherwise': otherwise } return R
[docs] def visit_ifclausenode(self, node, condition, body): return { 'type': 'elseif_statement', 'test': self.visit(condition), 'block': self.visit(body), 'pseudo_type': 'Void' }
[docs] def visit_elseStatement(self, node): block = self.visit(node) r = { 'type': 'else_statement', 'block': [block] if isinstance(block, dict) else block, 'pseudo_type': 'Void' } return r
[docs] def visit_forstatement(self,node,for_initializer,expression,for_iterator, embedded_statement, location): res = {} init = self.visit(for_initializer) res["type"] = "for_range_statement" res["start"] = init["decl"][0]["value"] if "decl" in init else init[0]["value"] expr = self.visit(expression) if expr["op"] in ["<", ">", '!=']: res["end"] = expr["right"] elif expr["op"] in ["<=", ">="]: res["end"]={'type': 'binary_op', 'op': '+', 'left': expr["right"], 'right': {'type': 'int', 'value': '1', 'pseudo_type': 'int'}, 'pseudo_type': 'int'} r = self.visit(for_iterator)[0] ii = self.visit(for_iterator) if (r["type"] == "unary_op" and r["operator"] == "++") or ("inc" in r): res["step"] = {"type":"int", "value":"1", "pseudo_type":"int"} elif (r["type"] == "unary_op" and r["operator"] == "--") or ("dec" in r): res["step"] = {"type":"int", "value":"-1", "pseudo_type":"int"} elif (r["type"])=="assignment": res["step"] = r["value"] if (r["op"]=="+=" and r["value"]["type"]=="unary_op" and r["value"]["operator"]=="-") or r["op"]=="-=": res["end"]={'type': 'binary_op', 'op': '-', 'left': expr["right"], 'right': {'type': 'int', 'value': '1', 'pseudo_type': 'int'}, 'pseudo_type': 'int'} res["index"] = init["decl"][0] if "decl" in init else init[0]["target"] res["index"]["type"] = "local" if "decl" in init: del res["index"]["value"] res["block"] = self.visit(embedded_statement) res["pseudo_type"] = "Void" return res
[docs] def visit_whilestatement(self,node,expression,embedded_statement, location): test_node = self.visit(expression) return { 'type': 'while_statement', 'test': test_node, 'block': self.visit(embedded_statement), 'pseudo_type': 'Void' }
[docs] def visit_foreachstatement(self, node, local_variable_type, identifier,expression, embedded_statement, location): z = self.visit(local_variable_type) self.label = True res = {'type': 'for_statement', 'sequences': {'type': 'for_sequence', 'sequence': self.visit(expression)}, 'iterators': {'type': 'for_iterator', 'iterator': {'type':'local', 'name':self.visit(identifier), 'pseudo_type':z["pseudo_type"]}}, 'block': self.visit(embedded_statement)} self.label = False return res
[docs] def visit_parenthesisexpressions(self, node,expression, location): z = self.visit(expression) return z
[docs] def visit_trystatement(self, node, TRY, block,catch_clauses, finally_clause, location): return
"""def visit_throwstatement(self, node, THROW, expression,SEMICOLON, location): return {"type":"throwstatement", "exception": self.visit(expression) if expression else None, 'pseudo_type': 'Void'}"""
[docs] def visit_fixed_parameter(self, node, attributes, parameter_modifier, arg_declaration, ARGLIST, location): if arg_declaration: args = self.visit(arg_declaration) else: args = self.visit(ARGLIST) if parameter_modifier: args["modifier"] = self.visit(parameter_modifier) return args
[docs] def visit_continuestatement(self, node, CONTINUE, SEMICOLON, location): return { "type": "continuestatnode" }
[docs] def visit_enum_member_declaration(self, node, attributes, identifier, expression, location): value = None id = self.visit(identifier) if expression: value = self.visit(expression) pseudo_type = value["pseudo_type"] else: pseudo_type = "string" res = {'type':"local", "name":id, "pseudo_type": pseudo_type} if value: res["value"] = value return res
[docs] def visit_yieldstatement(self, node, YIELD, BREAK, RETURN, expression,SEMICOLON, location): if expression: return {"type":"yieldstatement", "value":self.visit(expression)} elif BREAK: return {"type":"breakstatement"}
[docs] def visit_attribute(self, node, namespace_or_type_name,attribute_argument, location): type_ = self.visit(namespace_or_type_name) args = [] if attribute_argument: args = self.visit(attribute_argument) if args: res = {"type":"attribute", "name":type_, "args":args} else: res = {"type":"attribute", "name":type_} return res
[docs] def ensure_text(v): if isinstance(v, bytes): return v.decode("utf-8") return v