from smnp.ast.node.none import NoneNode from smnp.function.signature import signature from smnp.runtime.evaluator import Evaluator from smnp.runtime.tools.signature import argumentsNodeToMethodSignature, listSpecifier, mapSpecifier from smnp.type.model import Type from smnp.type.signature.matcher.type import ofType class ExtendEvaluator(Evaluator): @classmethod def evaluator(cls, node, environment): type = cls._typeToMethodSignature(node.type) # TODO check if it isn't necessary to verify 'result' attr of EvaluatioNResult variable = node.variable.value cls._evaluateExtend(node.methods, environment, type, variable) @classmethod def _typeToMethodSignature(cls, node): if type(node.specifiers) == NoneNode: return signature(ofType(node.type.value)) elif node.type.value == Type.LIST: return signature(listSpecifier(node.specifiers[0])) elif node.type.value == Type.MAP: return signature(mapSpecifier(node.specifiers[0], node.specifiers[1])) @classmethod def _evaluateExtend(cls, node, environment, type, variable): for child in node.children: cls._evaluateMethodDefinition(child, environment, type, variable) @classmethod def _evaluateMethodDefinition(cls, node, environment, type, variable): name = node.name.value defaultArguments, signature = argumentsNodeToMethodSignature(node.arguments, environment) arguments = [arg.variable.value for arg in node.arguments] body = node.body environment.addCustomMethod(type, variable, name, signature, arguments, body, defaultArguments)