diff --git a/executor/handlers/state.py b/executor/handlers/state.py new file mode 100644 index 0000000..2025d55 --- /dev/null +++ b/executor/handlers/state.py @@ -0,0 +1,104 @@ +__author__ = 'RemiZOffAlex' +__email__ = 'remizoffalex@mail.ru' + +from uuid import uuid4 + + +def closure_include(name): + def closure_filter(closure): + return closure['child']==name + return closure_filter + + +def closure_exclude(name): + def closure_filter(closure): + return closure['child']!=name + return closure_filter + + +def scope_addition(context, parent = None): + name = str(uuid4()) + context.scopes[name] = {} + if parent: + context.closures.append({ + 'parent': parent, + 'child': name + }) + else: + context.closures.append({ + 'parent': context.current, + 'child': name + }) + return name + +# def scope_del(context, name): +# closures = [] +# for item in context.closures: +# if item['child'] != name: +# closures.append(item) +# context.closures = closures +# del context.scopes[name] + +def scope_del(context, name): + if name in context.scopes: + context.closures = list( + filter( + closure_exclude, + context.closures + ) + ) + del context.scopes[name] + return + raise Exception('Область видимости {} не найдена'.format(name)) + +def variable_addition(context, name, value = None): + current = context.scopes[context.current] + if name in current: + raise Exception('Double declaration of the variable %s' % name) + current[name] = value + + +def variable_delete(context, name): + current = context.scopes[context.current] + if name in current: + del current[name] + raise Exception('Переменная {} не найдена'.format(name)) + + +def variable_exist(context, name): + current = context.scopes[context.current] + return name in current + + +def variable_get(context, name): + scope = context.scopes[context.current] + if name in scope: + result = scope[name] + return result + stack = [] + if context.current != 'root': + stack.append(context.current) + while len(stack) > 0: + scope_name = stack.pop() + closures = list( + filter( + closure_include(scope_name), + context.closures + ) + ) + for closure in closures: + stack.append(closure['parent']) + scope = context.scopes[scope_name] + if name in scope: + result = scope[name] + return result + + raise Exception('Переменная {} не найдена'.format(name)) + + +def variable_set(context, name, value): + current = context.scopes[context.current] + if name in current: + current[name] = value + return + raise Exception('Переменная {} не найдена'.format(name))