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]:
return customMethodResult[1]
raise MethodNotFoundException(object.type, name)
raise MethodNotFoundException(types([object], False), name)
def _invokeBuiltinMethod(self, object, name, args):
for method in self.methods:
@@ -34,7 +34,7 @@ class Environment():
def _invokeCustomMethod(self, object, name, args):
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)
if signatureCheckresult[0]:
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):
self.customFunctions.append(CustomFunction(name, signature, arguments, body))
def addCustomMethod(self, type, alias, name, signature, arguments, body):
self.customMethods.append(CustomMethod(type, alias, name, signature, arguments, body))
def addCustomMethod(self, typeSignature, alias, name, signature, arguments, body):
self.customMethods.append(CustomMethod(typeSignature, alias, name, signature, arguments, body))
def findVariable(self, name, type=None, pos=None):
for scope in reversed(self.scopes):
@@ -137,8 +137,8 @@ class CustomFunction:
class CustomMethod:
def __init__(self, type, alias, name, signature, arguments, body):
self.type = type
def __init__(self, typeSignature, alias, name, signature, arguments, body):
self.typeSignature = typeSignature
self.alias = alias
self.name = name
self.signature = signature

View File

@@ -49,14 +49,14 @@ class CombinedFunction(Function):
raise IllegalFunctionInvocationException(self.stringSignature(), f"{self.name}{types(args)}")
def types(args):
def types(args, parentheses=True):
output = []
for arg in args:
if arg.type == Type.LIST:
output.append(listTypes(arg.value, []))
else:
output.append(arg.type.name.lower())
return f"({', '.join(output)})"
return f"({', '.join(output)})" if parentheses else ', '.join(output)
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.evaluators.function import argumentsNodeToMethodSignature
from smnp.runtime.evaluators.type import TypeEvaluator
from smnp.runtime.evaluators.function import argumentsNodeToMethodSignature, listSpecifier
from smnp.type.model import Type
class ExtendEvaluator(Evaluator):
@classmethod
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
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
def _evaluateExtend(cls, node, environment, type, variable):
for child in node.children:
@@ -22,4 +32,5 @@ class ExtendEvaluator(Evaluator):
signature = argumentsNodeToMethodSignature(node.arguments)
arguments = [arg.variable.value for arg in node.arguments]
body = node.body
environment.addCustomMethod(type, variable, name, signature, arguments, body)
environment.addCustomMethod(type, variable, name, signature, arguments, body)