Skip to content

Commit b71cda7

Browse files
committed
updates
added handling all the exceptions from functions (for example, in case exception is from external function). Also now for global namespace using separated namespace to avoid using std as a global namespace
1 parent bd944a3 commit b71cda7

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

pycalc/interpreter/interpret.py

+13-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
from pycalc.tokentypes.tokens import Token, Tokens, Function
99
from pycalc.tokentypes.types import (TokenKind, TokenType, Stack, Namespace, Number,
1010
NamespaceValue, ArgumentsError, NameNotFoundError,
11-
InvalidSyntaxError, NoCodeError)
11+
InvalidSyntaxError, ExternalFunctionError,
12+
PyCalcError, NoCodeError)
1213

1314

1415
Value = Union[Number, Function]
@@ -107,7 +108,10 @@ def interpret(self, code: str, namespace: Namespace) -> Value:
107108
tokens = self.tokenizer.tokenize(code)
108109
stacks = self.stackbuilder.build(tokens)
109110
namespaces = NamespaceStack()
110-
namespaces.add_namespace(namespace)
111+
# empty namespace especially for global namespace
112+
# because default one must not be overridden by
113+
# global namespace of code
114+
namespaces.add_namespaces(namespace, {})
111115

112116
return self._interpreter(stacks, namespaces)
113117

@@ -164,14 +168,15 @@ def _interpret_line(self, expression: Stack[Token], namespaces: NamespaceStack)
164168
call_result = func(*(arg.value for arg in args))
165169
except ArgumentsError as exc:
166170
raise ArgumentsError(str(exc), token.pos) from None
171+
except PyCalcError as exc:
172+
raise exc from None
173+
except Exception as exc:
174+
raise ExternalFunctionError(str(exc), token.pos)
167175

168176
stack.append(self._token(call_result, token.pos))
169177
elif token.type == TokenType.FUNCDEF:
170-
func_namespace = namespaces.copy()
171-
func_namespace.add_namespace({})
172-
173178
func = self._spawn_function(
174-
namespace=func_namespace,
179+
namespace=namespaces.copy(),
175180
name=token.value.name,
176181
fargs=[tok.value for tok in token.value.args],
177182
body=token.value.body
@@ -201,9 +206,6 @@ def _interpret_line(self, expression: Stack[Token], namespaces: NamespaceStack)
201206

202207
return result.value
203208

204-
def _import(self, path: str):
205-
...
206-
207209
def _spawn_function(self,
208210
namespace: NamespaceStack,
209211
name: str,
@@ -212,7 +214,7 @@ def _spawn_function(self,
212214
def real_function(*args) -> Number:
213215
if not fargs and args:
214216
raise ArgumentsError("function takes no arguments", (-1, -1))
215-
if len(fargs) != len(args):
217+
elif len(fargs) != len(args):
216218
text = (
217219
"not enough arguments",
218220
"too much arguments"
@@ -229,7 +231,7 @@ def real_function(*args) -> Number:
229231
return self._interpret_line(body, namespace)
230232

231233
return Function(
232-
name=f"{name}({','.join(fargs)})",
234+
name=f"{name or '<lambda>'}({','.join(fargs)})",
233235
target=real_function
234236
)
235237

0 commit comments

Comments
 (0)