Skip to content

Instantly share code, notes, and snippets.

@Halicea
Created December 2, 2014 15:30
Show Gist options
  • Save Halicea/0f3f54f3f780ec6c4dd9 to your computer and use it in GitHub Desktop.
Save Halicea/0f3f54f3f780ec6c4dd9 to your computer and use it in GitHub Desktop.
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