Add call stack to RuntimeException based errors

This commit is contained in:
Bartłomiej Pluta
2019-07-10 12:53:58 +02:00
parent d10df10282
commit 9ea2202d14
7 changed files with 39 additions and 24 deletions

View File

@@ -27,9 +27,7 @@ class Environment():
def _invokeBuiltinMethod(self, object, name, args):
for method in self.methods:
if method.name == name:
self.callStack.append(CallStackItem(name))
ret = method.call(self, [object, *args])
self.callStack.pop(-1)
if ret is not None:
return (True, ret)
@@ -65,9 +63,7 @@ class Environment():
def _invokeBuiltinFunction(self, name, args):
for function in self.functions:
if function.name == name:
self.callStack.append(CallStackItem(name))
ret = function.call(self, args)
self.callStack.pop(-1)
if ret is not None:
return (True, ret)

View File

@@ -6,8 +6,11 @@ class SmnpException(Exception):
def _title(self):
pass
def _postMessage(self):
return ""
def _position(self):
return "" if self.pos is None else f" [line {self.pos[0]+1}, col {self.pos[1]+1}]"
def message(self):
return f"{self._title()}{self._position()}:\n{self.msg}"
return f"{self._title()}{self._position()}:\n{self.msg}\n{self._postMessage()}"

View File

@@ -1,7 +1,7 @@
from smnp.error.base import SmnpException
from smnp.error.runtime import RuntimeException
class IllegalFunctionInvocationException(SmnpException):
class IllegalFunctionInvocationException(RuntimeException):
def __init__(self, expected, found, pos=None):
super().__init__(f"Expected signature:\n{expected}\n\nFound:\n{found}", pos)
@@ -9,7 +9,7 @@ class IllegalFunctionInvocationException(SmnpException):
return "Invocation Error"
class FunctionNotFoundException(SmnpException):
class FunctionNotFoundException(RuntimeException):
def __init__(self, function, pos=None):
super().__init__(f"Function '{function}' not found", pos)
@@ -17,7 +17,7 @@ class FunctionNotFoundException(SmnpException):
return "Invocation Error"
class MethodNotFoundException(SmnpException):
class MethodNotFoundException(RuntimeException):
def __init__(self, object, method, pos=None):
super().__init__(f"Method '{method}' of type '{object}' not found", pos)
@@ -25,7 +25,7 @@ class MethodNotFoundException(SmnpException):
return "Invocation Error"
class IllegalArgumentException(SmnpException):
class IllegalArgumentException(RuntimeException):
def __init__(self, msg, pos=None):
super().__init__(msg, pos)

View File

@@ -9,6 +9,9 @@ class RuntimeException(SmnpException):
def _title(self):
return "Runtime Error"
def _postMessage(self):
return "\n" + self.environment.callStackToString() if len(self.environment.callStack) > 0 else ""
# def message(self):
# posStr = "" if self.pos is None else f" [line {self.pos[0] + 1}, col {self.pos[1] + 1}]"
# return f"Runtime error{posStr}:\n{self.mmsg}"

View File

@@ -19,9 +19,13 @@ class Function:
return f"{self.name}{self.signature.string}"
def call(self, env, args):
from smnp.environment.environment import CallStackItem
result = self.signature.check(args)
if result[0]:
env.callStack.append(CallStackItem(self.name))
ret = self.function(env, *result[1:])
env.callStack.pop(-1)
if ret is None:
return Type.void()
return ret
@@ -38,10 +42,14 @@ class CombinedFunction(Function):
return "\nor\n".join([f"{self.name}{function.signature.string}" for function in self.functions])
def call(self, env, args):
from smnp.environment.environment import CallStackItem
for function in self.functions:
result = function.signature.check(args)
if result[0]:
env.callStack.append(CallStackItem(self.name))
ret = function.function(env, *result[1:])
env.callStack.pop(-1)
if ret is None:
return Type.void()
return ret

View File

@@ -2,9 +2,9 @@ from smnp.error.function import IllegalArgumentException
from smnp.function.model import Function
from smnp.function.signature import signature
from smnp.type.model import Type
from smnp.type.signature.matcher.type import ofTypes
from smnp.type.signature.matcher.type import ofType
_signature = signature(ofTypes(Type.STRING))
_signature = signature(ofType(Type.STRING))
def _function(env, parameter):
if parameter.value == "environment":
print(env)

View File

@@ -1,5 +1,6 @@
from smnp.ast.parser import parse
from smnp.environment.factory import createEnvironment
from smnp.error.runtime import RuntimeException
from smnp.program.FileReader import readLines
from smnp.runtime.evaluator import evaluate
from smnp.token.tokenizer import tokenize
@@ -9,18 +10,22 @@ class Interpreter:
@staticmethod
def interpretFile(file, printTokens=False, printAst=False):
lines = readLines(file)
tokens = tokenize(lines)
if printTokens:
print(tokens)
ast = parse(tokens)
if printAst:
ast.print()
environment = createEnvironment()
evaluate(ast, environment)
try:
lines = readLines(file)
return environment
tokens = tokenize(lines)
if printTokens:
print(tokens)
ast = parse(tokens)
if printAst:
ast.print()
evaluate(ast, environment)
return environment
except RuntimeException as e:
e.environment = environment
raise e