Created
December 2, 2014 15:30
-
-
Save Halicea/0f3f54f3f780ec6c4dd9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Symbol(object): | |
def __init__(self, name): | |
self.name = name | |
def __repr__(self): | |
return '$'+str(self.name) | |
def __str__(self): | |
self.__repr__() | |
class SelectScope: | |
ITER_ITEM = '__iter_item__' | |
ITER_INDEX = '__iter_index__' | |
def isa(inst, t): | |
return isinstance(inst, t) | |
class ElementLispSyntaxError(Exception): | |
def __init__(self, message=None): | |
super(ElementLispSyntaxError, self).__init__(message) | |
class Env(dict): | |
"An environment: a dict of {'var':val} pairs, with an outer Env." | |
def __init__(self, name='Global', parms=(), args=(), outer=None): | |
self.name = name | |
self.update(zip(parms, args)) | |
self.outer = outer | |
def find(self, var): | |
"Find the innermost Env where var appears." | |
if var in self: | |
return self | |
elif self.outer: | |
return self.outer.find(var) | |
else: | |
import pdb; pdb.set_trace() # XXX BREAKPOINT | |
raise NotImplementedError('{} is not defined'.format(var)) | |
def __repr__(self): | |
k = self | |
result = self.name | |
while k.outer: | |
result += '<-'+k.outer.name | |
k = k.outer | |
return result | |
def __str__(self): | |
return self.__repr__() | |
class AbstractElementLisp(object): | |
def __init__(self, manager=None, env=None): | |
self.manager = manager | |
self.global_env = self.add_globals(Env(outer=env)) | |
self.context = {} | |
def __eval__(expr, env): | |
raise NotImplementedError() | |
def lisp_sum(self, *items): | |
if len(items) == 0: | |
return 0 | |
in_first_arg = isinstance(items[0], (list, tuple)) | |
has_many = len(items) > 1 | |
param = items[0] if in_first_arg and not has_many else items | |
if len(param) == 0: | |
return 0 | |
operands = param | |
if isinstance(param[0], (list, set)): | |
operands = [] | |
map(lambda x: operands.extend(x), param) | |
if isinstance(operands[0], str): | |
return ''.join([str(x) for x in operands]) | |
else: | |
result = 0 | |
for k in operands: | |
if isinstance(k, (int, float)): | |
result+=k | |
return result | |
def lisp_avg(self, *items): | |
in_first_arg = isinstance(items[0], (list, tuple)) | |
param = items[0] if in_first_arg else items | |
if len(param) > 0: | |
return float(self.lisp_sum(param)) / self.lisp_len(param) | |
else: | |
return float('nan') | |
def lisp_len(self, *items): | |
in_first_arg = isinstance(items[0], (list, tuple)) | |
param = items[0] if in_first_arg else items | |
return len(param) | |
def lisp_select(self, env, selector, source, condition=None): | |
result = [] | |
if self.manager is None: | |
return result | |
src_evaled = self.__eval__(source, env=env) | |
reusable_env = Env('InSelect', outer=env) | |
iter_index = 0 | |
args = src_evaled() | |
for element in self.manager.select(*args): | |
reusable_env[SelectScope.ITER_ITEM] = element | |
reusable_env[SelectScope.ITER_INDEX] = iter_index | |
should_select = True | |
if condition: | |
cond_evaled = self.__eval__(condition, env=reusable_env) | |
should_select = cond_evaled() | |
if should_select: | |
selected_value = self.__eval__(selector, env=reusable_env) | |
result.append(selected_value) | |
return result | |
def lisp_ref(self, *params): | |
def res(item): | |
r = item | |
index = 0 | |
while index < len(params) and hasattr(r, params[index]): | |
r = getattr(r, params[index]) | |
index += 1 | |
if index + 1 < len(params): | |
msg_format = 'item {} with type {} does not ' +\ | |
'have property named {}' | |
msg = msg_format.format( | |
item.uuid, | |
item.__class__.__name__, | |
params[index]) | |
print(msg) | |
raise Exception(msg) | |
if hasattr(r, 'value'): | |
# print('returning value {} from #{}-{}'.format(r.value, r.definition.name, r.uuid)) | |
if isinstance(getattr(r,'value'), (str, unicode)): | |
if r.value.strip().startswith('$'): | |
return float(r.value.strip()[1:].replace('.', '').replace(',', '.')) | |
else: | |
return r.value | |
return r.value | |
else: | |
# print('returning #{}-{} object'.format(r.definition.name, r.uuid)) | |
return r | |
return res | |
def lisp_print(self, *expressions): | |
print(' '.join([self.to_string(ex) for ex in expressions])) | |
def lisp_lambda(self, exp, vars, env): | |
def res(*args): | |
return self.__eval__(exp, Env(name='lambda',parms=[x.name for x in vars], args=args, outer=env)) | |
return res | |
def expand_source_query(self, *query_items): | |
return query_items | |
def lisp_source(self, expression, env): | |
def res(): | |
exp = self.__eval__(expression, env) | |
query_items = exp.split(',') | |
query_items = self.expand_source_query(*query_items) | |
return query_items | |
return res | |
def lisp_cond(self, expression, env): | |
def res(): | |
return self.__eval__(expression, env) | |
return res |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment