Improve creating custom methods to checking specifier of generic types (list)

This commit is contained in:
Bartłomiej Pluta
2019-07-08 18:18:40 +02:00
parent 6d56706354
commit 05dfe46f9f
3 changed files with 23 additions and 12 deletions

View File

@@ -21,7 +21,7 @@ class Environment():
if customMethodResult[0]: if customMethodResult[0]:
return customMethodResult[1] return customMethodResult[1]
raise MethodNotFoundException(object.type, name) raise MethodNotFoundException(types([object], False), name)
def _invokeBuiltinMethod(self, object, name, args): def _invokeBuiltinMethod(self, object, name, args):
for method in self.methods: for method in self.methods:
@@ -34,7 +34,7 @@ class Environment():
def _invokeCustomMethod(self, object, name, args): def _invokeCustomMethod(self, object, name, args):
for method in self.customMethods: for method in self.customMethods:
if method.type.value == object.type and method.name == name: if method.typeSignature.check([object])[0] and method.name == name: #Todo sprawdzic sygnature typu
signatureCheckresult = method.signature.check(args) signatureCheckresult = method.signature.check(args)
if signatureCheckresult[0]: if signatureCheckresult[0]:
self.scopes.append({argName: argValue for argName, argValue in zip(method.arguments, args)}) self.scopes.append({argName: argValue for argName, argValue in zip(method.arguments, args)})
@@ -81,8 +81,8 @@ class Environment():
def addCustomFunction(self, name, signature, arguments, body): def addCustomFunction(self, name, signature, arguments, body):
self.customFunctions.append(CustomFunction(name, signature, arguments, body)) self.customFunctions.append(CustomFunction(name, signature, arguments, body))
def addCustomMethod(self, type, alias, name, signature, arguments, body): def addCustomMethod(self, typeSignature, alias, name, signature, arguments, body):
self.customMethods.append(CustomMethod(type, alias, name, signature, arguments, body)) self.customMethods.append(CustomMethod(typeSignature, alias, name, signature, arguments, body))
def findVariable(self, name, type=None, pos=None): def findVariable(self, name, type=None, pos=None):
for scope in reversed(self.scopes): for scope in reversed(self.scopes):
@@ -137,8 +137,8 @@ class CustomFunction:
class CustomMethod: class CustomMethod:
def __init__(self, type, alias, name, signature, arguments, body): def __init__(self, typeSignature, alias, name, signature, arguments, body):
self.type = type self.typeSignature = typeSignature
self.alias = alias self.alias = alias
self.name = name self.name = name
self.signature = signature self.signature = signature

View File

@@ -49,14 +49,14 @@ class CombinedFunction(Function):
raise IllegalFunctionInvocationException(self.stringSignature(), f"{self.name}{types(args)}") raise IllegalFunctionInvocationException(self.stringSignature(), f"{self.name}{types(args)}")
def types(args): def types(args, parentheses=True):
output = [] output = []
for arg in args: for arg in args:
if arg.type == Type.LIST: if arg.type == Type.LIST:
output.append(listTypes(arg.value, [])) output.append(listTypes(arg.value, []))
else: else:
output.append(arg.type.name.lower()) output.append(arg.type.name.lower())
return f"({', '.join(output)})" return f"({', '.join(output)})" if parentheses else ', '.join(output)
def listTypes(l, output=None): def listTypes(l, output=None):

View File

@@ -1,16 +1,26 @@
from smnp.ast.node.none import NoneNode
from smnp.library.signature import ofType, signature
from smnp.runtime.evaluator import Evaluator from smnp.runtime.evaluator import Evaluator
from smnp.runtime.evaluators.function import argumentsNodeToMethodSignature from smnp.runtime.evaluators.function import argumentsNodeToMethodSignature, listSpecifier
from smnp.runtime.evaluators.type import TypeEvaluator from smnp.type.model import Type
class ExtendEvaluator(Evaluator): class ExtendEvaluator(Evaluator):
@classmethod @classmethod
def evaluator(cls, node, environment): def evaluator(cls, node, environment):
type = TypeEvaluator.evaluate(node.type, environment).value #TODO check if it isn't necessary to verify 'result' attr of EvaluatioNResult type = cls._typeToMethodSignature(node.type) # TODO check if it isn't necessary to verify 'result' attr of EvaluatioNResult
variable = node.variable.value variable = node.variable.value
cls._evaluateExtend(node.methods, environment, type, variable) cls._evaluateExtend(node.methods, environment, type, variable)
@classmethod
def _typeToMethodSignature(cls, node):
if type(node.specifier) == NoneNode:
return signature(ofType(node.type))
elif node.type == Type.LIST:
return signature(listSpecifier(node.specifier))
@classmethod @classmethod
def _evaluateExtend(cls, node, environment, type, variable): def _evaluateExtend(cls, node, environment, type, variable):
for child in node.children: for child in node.children:
@@ -22,4 +32,5 @@ class ExtendEvaluator(Evaluator):
signature = argumentsNodeToMethodSignature(node.arguments) signature = argumentsNodeToMethodSignature(node.arguments)
arguments = [arg.variable.value for arg in node.arguments] arguments = [arg.variable.value for arg in node.arguments]
body = node.body body = node.body
environment.addCustomMethod(type, variable, name, signature, arguments, body) environment.addCustomMethod(type, variable, name, signature, arguments, body)