Getting fib working :>

This commit is contained in:
Paul Tagliamonte 2012-12-18 19:02:50 -05:00
parent c02900412c
commit 7f4b4f8bf8
11 changed files with 59 additions and 46 deletions

11
AUTHORS
View File

@ -1 +1,10 @@
Paul R. Tagliamonte <tag@pault.ag> Code contributors:
- Paul R. Tagliamonte <tag@pault.ag>
I'd also like to thank the following people:
- Kragen Sitaker:
Major thanks goes to Kragen on helping me work through some of the
namespacing crap. I think the majority of the approach taken now
with expressions' eval bits is his doing in one way or another.

6
bin/hython Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env python
from hy.lang.importer import _hy_import_file
import sys
mod = _hy_import_file(sys.argv[1], '<stdin>')

View File

@ -120,7 +120,7 @@ def forge_module(name, fpath, forest):
def shim(): def shim():
ns = globals() ns = globals()
for tree in _hy_forest: for tree in _hy_forest:
tree.set_namespace(ns, {}) tree.set_namespace(ns)
for tree in _hy_forest: for tree in _hy_forest:
tree() tree()

View File

@ -5,5 +5,5 @@ class HYBool(HYObject):
def __init__(self, val): def __init__(self, val):
self._val = val self._val = val
def eval(self, *args, **kwargs): def eval(self, lns, *args, **kwargs):
return self._val == True return self._val == True

View File

@ -1,37 +1,40 @@
# #
import sys import sys
from hy.lang.internals import HYNamespaceCOW
def _define(obj): def _define(obj, lns):
fd = obj.get_invocation() fd = obj.get_invocation()
args = fd['args'] args = fd['args']
obj.namespace[args[0]] = args[1]() obj.namespace[args[0]] = args[1]()
def _fn(obj): def _fn(obj, lns):
fd = obj.get_invocation() fd = obj.get_invocation()
args = fd['args'] args = fd['args']
sig = args[0] sig = args[0]
meth = args[1] meth = args[1]
def _(*args, **kwargs): def _(*args, **kwargs):
l = lns.clone()
m = meth.copy()
for i in range(0, len(sig)): for i in range(0, len(sig)):
name = sig[i] name = sig[i]
value = args[i] value = args[i]
meth.local_namespace[name] = value l[name] = value
ret = meth(*args, **kwargs) ret = m.eval(l, *args, **kwargs)
return ret return ret
return _ return _
def _kwapply(obj): def _kwapply(obj, lns):
fd = obj.get_invocation() fd = obj.get_invocation()
subshell, kwargs = fd['args'] subshell, kwargs = fd['args']
return subshell.eval(**kwargs) return subshell.eval(lns.clone(), **kwargs)
def _import(obj): def _import(obj, lns):
ns = obj.namespace ns = obj.namespace
fd = obj.get_invocation() fd = obj.get_invocation()
args = fd['args'] args = fd['args']
@ -44,13 +47,13 @@ def _import(obj):
ns[basename] = mod ns[basename] = mod
def _if(obj): def _if(obj, lns):
fd = obj.get_invocation() fd = obj.get_invocation()
args = fd['args'] args = fd['args']
if args[0].eval(): if args[0].eval(lns.clone()):
return args[1].eval() return args[1].eval(lns.clone())
else: else:
return args[2].eval() return args[2].eval(lns.clone())
builtins = { builtins = {

View File

@ -2,7 +2,7 @@ from hy.lang.hyobj import HYObject
from hy.lang.builtins import builtins from hy.lang.builtins import builtins
class HYExpression(list, HYObject): class HYExpression(HYObject, list):
def __init__(self, nodes): def __init__(self, nodes):
self += nodes self += nodes
@ -24,17 +24,17 @@ class HYExpression(list, HYObject):
def peek(self): def peek(self):
return self.get_invocation()['function'] return self.get_invocation()['function']
def eval(self, *args, **kwargs): def eval(self, lns, *args, **kwargs):
fn = self.peek() fn = self.peek()
if fn in builtins: if fn in builtins:
# special-case builtin handling. # special-case builtin handling.
return builtins[fn](self) return builtins[fn](self, lns)
things = [] things = []
for child in self.get_children(): for child in self.get_children():
c = child.copy() c = child.copy()
things.append(c()) things.append(c.eval(lns.clone()))
ret = self.lookup(fn)(*things, **kwargs) ret = self.lookup(lns, fn)(*things, **kwargs)
return ret return ret

View File

@ -1,44 +1,38 @@
from hy.lang.internals import HYNamespaceCOW from hy.lang.internals import HYNamespaceCOW
class HYObject(object): class HYObject(object):
def set_namespace(self, ns, ls): def set_namespace(self, ns):
self.namespace = ns self.namespace = ns
nns = HYNamespaceCOW(ls)
self.local_namespace = nns
for c in self.get_children(): for c in self.get_children():
c.set_namespace(ns, nns) c.set_namespace(ns)
def get_children(self): def get_children(self):
return [] return []
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
return self.eval(*args, **kwargs) ns = HYNamespaceCOW({}) # Each invocation needs it's own ns
return self.eval(ns, *args, **kwargs)
def lookup(self, fn): def lookup(self, lns, fn):
callee = None if fn in lns:
if fn in self.local_namespace: return lns[fn]
callee = self.local_namespace[fn]
elif callee is None and fn in self.namespace: if fn in self.namespace:
callee = self.namespace[fn] return self.namespace[fn]
elif callee is None and "." in fn: if "." in fn:
lon, short = fn.rsplit(".", 1) lon, short = fn.rsplit(".", 1)
holder = self.lookup(lon) holder = self.lookup(lns, lon)
callee = getattr(holder, short) return getattr(holder, short)
if callee is not None:
return callee
raise Exception("No such symbol: `%s`" % (fn)) raise Exception("No such symbol: `%s`" % (fn))
def eval(self, *args, **kwargs): def eval(self, lns, *args, **kwargs):
for node in self.get_children(): for node in self.get_children():
node.eval(*args, **kwargs) node.eval(lns, *args, **kwargs)
return self return self
def copy(self): def copy(self):
new = type(self)(self) new = type(self)(self)
new.set_namespace(self.namespace, self.local_namespace) new.set_namespace(self.namespace)
return new return new

View File

@ -18,3 +18,6 @@ class HYNamespaceCOW(object):
def __setitem__(self, key, value): def __setitem__(self, key, value):
self._mute[key] = value self._mute[key] = value
def clone(self):
return HYNamespaceCOW(self)

View File

@ -1,7 +1,7 @@
from hy.lang.hyobj import HYObject from hy.lang.hyobj import HYObject
class HYList(list, HYObject): class HYList(HYObject, list):
def __init__(self, nodes): def __init__(self, nodes):
self += nodes self += nodes

View File

@ -3,10 +3,8 @@ from hy.lang.hyobj import HYObject
class HYNumber(HYObject, int): class HYNumber(HYObject, int):
def __new__(cls, number, *args, **kwargs): def __new__(cls, number, *args, **kwargs):
if isinstance(number, HYObject):
number = number.eval()
number = int(number) number = int(number)
return super(HYNumber, cls).__new__(cls, number) return super(HYNumber, cls).__new__(cls, number)
def eval(self, *args, **kwargs): def eval(self, lns, *args, **kwargs):
return int(self) return int(self)

View File

@ -5,6 +5,6 @@ class HYSymbol(HYString):
def __init__(self, string): def __init__(self, string):
self += string self += string
def eval(self, *args, **kwargs): def eval(self, lns, *args, **kwargs):
obj = self.lookup(self) obj = self.lookup(lns, self)
return obj return obj