8
8
from pycalc .tokentypes .tokens import Token , Tokens , Function
9
9
from pycalc .tokentypes .types import (TokenKind , TokenType , Stack , Namespace , Number ,
10
10
NamespaceValue , ArgumentsError , NameNotFoundError ,
11
- InvalidSyntaxError , NoCodeError )
11
+ InvalidSyntaxError , ExternalFunctionError ,
12
+ PyCalcError , NoCodeError )
12
13
13
14
14
15
Value = Union [Number , Function ]
@@ -107,7 +108,10 @@ def interpret(self, code: str, namespace: Namespace) -> Value:
107
108
tokens = self .tokenizer .tokenize (code )
108
109
stacks = self .stackbuilder .build (tokens )
109
110
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 , {})
111
115
112
116
return self ._interpreter (stacks , namespaces )
113
117
@@ -164,14 +168,15 @@ def _interpret_line(self, expression: Stack[Token], namespaces: NamespaceStack)
164
168
call_result = func (* (arg .value for arg in args ))
165
169
except ArgumentsError as exc :
166
170
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 )
167
175
168
176
stack .append (self ._token (call_result , token .pos ))
169
177
elif token .type == TokenType .FUNCDEF :
170
- func_namespace = namespaces .copy ()
171
- func_namespace .add_namespace ({})
172
-
173
178
func = self ._spawn_function (
174
- namespace = func_namespace ,
179
+ namespace = namespaces . copy () ,
175
180
name = token .value .name ,
176
181
fargs = [tok .value for tok in token .value .args ],
177
182
body = token .value .body
@@ -201,9 +206,6 @@ def _interpret_line(self, expression: Stack[Token], namespaces: NamespaceStack)
201
206
202
207
return result .value
203
208
204
- def _import (self , path : str ):
205
- ...
206
-
207
209
def _spawn_function (self ,
208
210
namespace : NamespaceStack ,
209
211
name : str ,
@@ -212,7 +214,7 @@ def _spawn_function(self,
212
214
def real_function (* args ) -> Number :
213
215
if not fargs and args :
214
216
raise ArgumentsError ("function takes no arguments" , (- 1 , - 1 ))
215
- if len (fargs ) != len (args ):
217
+ elif len (fargs ) != len (args ):
216
218
text = (
217
219
"not enough arguments" ,
218
220
"too much arguments"
@@ -229,7 +231,7 @@ def real_function(*args) -> Number:
229
231
return self ._interpret_line (body , namespace )
230
232
231
233
return Function (
232
- name = f"{ name } ({ ',' .join (fargs )} )" ,
234
+ name = f"{ name or '<lambda>' } ({ ',' .join (fargs )} )" ,
233
235
target = real_function
234
236
)
235
237
0 commit comments