hacking on stuff.

This commit is contained in:
Paul Tagliamonte 2012-12-18 09:11:42 -05:00
parent 94040dfbd3
commit 4f5bc16508
18 changed files with 207 additions and 22 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
*.pyc
*swp
*hy*egg*
.tox
*pycache*

View File

@ -1,11 +1,13 @@
from __future__ import print_function
from hy.lex.tokenize import tokenize
import imp
def _add_native_methods(mod):
def shim():
from hy.lang.bool import HYBool
def _print(*args, **kwargs):
print " ".join([str(x) for x in args])
print(" ".join([str(x) for x in args]))
def _plus(*args):
@ -40,14 +42,67 @@ def _add_native_methods(mod):
return ret
def _eq(*args):
car, cdr = args[0], args[1:]
for arg in cdr:
if arg != car:
return False
return True
def _ne(*args):
seen = set()
for arg in args:
if arg in seen:
return False
seen.add(arg)
return True
def _gt(*args):
arg = args[0]
for i in range(1, len(args)):
if not (args[i - 1] > args[i]):
return False
return True
def _ge(*args):
arg = args[0]
for i in range(1, len(args)):
if not (args[i - 1] >= args[i]):
return False
return True
def _le(*args):
arg = args[0]
for i in range(1, len(args)):
if not (args[i - 1] <= args[i]):
return False
return True
def _lt(*args):
arg = args[0]
for i in range(1, len(args)):
if not (args[i - 1] < args[i]):
return False
return True
natives = {
"print": _print,
"puts": _print,
"+": _plus,
"-": _subtract,
"*": _mult,
"/": _divide,
"true": True,
"false": False
"==": _eq,
">": _gt,
">=": _ge,
"<": _lt,
"<=": _le,
"!=": _ne
}
for native in natives:
@ -65,7 +120,7 @@ def forge_module(name, fpath, forest):
def shim():
ns = globals()
for tree in _hy_forest:
tree.set_namespace(ns)
tree.set_namespace(ns, {})
for tree in _hy_forest:
tree()

9
hy/lang/bool.py Normal file
View File

@ -0,0 +1,9 @@
from hy.lang.hyobj import HYObject
class HYBool(HYObject):
def __init__(self, val):
self._val = val
def eval(self, *args, **kwargs):
return self._val == True

View File

@ -18,12 +18,18 @@ def _fn(obj):
for i in range(0, len(sig)):
name = sig[i]
value = args[i]
obj.namespace[name] = value
obj.local_namespace[name] = value
return meth(*args, **kwargs)
return _
def _kwapply(obj):
fd = obj.get_invocation()
subshell, kwargs = fd['args']
return subshell.eval(**kwargs)
def _import(obj):
ns = obj.namespace
fd = obj.get_invocation()
@ -37,8 +43,19 @@ def _import(obj):
ns[basename] = mod
def _if(obj):
fd = obj.get_invocation()
args = fd['args']
if args[0].eval():
return args[1].eval()
else:
return args[2].eval()
builtins = {
"def": _define,
"fn": _fn,
"import": _import
"import": _import,
"kwapply": _kwapply,
"if": _if,
}

View File

@ -5,7 +5,6 @@ from hy.lang.builtins import builtins
class HYExpression(list, HYObject):
def __init__(self, nodes):
self += nodes
self.namespace = globals()
def get_children(self):
ret = []
@ -27,6 +26,7 @@ class HYExpression(list, HYObject):
def eval(self, *args, **kwargs):
fn = self.peek()
if fn in builtins:
# special-case builtin handling.
return builtins[fn](self)
@ -35,4 +35,5 @@ class HYExpression(list, HYObject):
for child in self.get_children():
things.append(child())
return self.lookup(fn)(*things)
ret = self.lookup(fn)(*things, **kwargs)
return ret

View File

@ -1,8 +1,13 @@
from hy.lang.internals import HYNamespaceCOW
class HYObject(object):
def set_namespace(self, ns):
def set_namespace(self, ns, ls):
self.namespace = ns
nns = HYNamespaceCOW(ls)
self.local_namespace = nns
for c in self.get_children():
c.set_namespace(ns)
c.set_namespace(ns, ls=nns)
def get_children(self):
return []
@ -12,16 +17,18 @@ class HYObject(object):
def lookup(self, fn):
callee = None
if fn in self.local_namespace:
callee = self.local_namespace[fn]
if fn in self.namespace:
if callee is None and fn in self.namespace:
callee = self.namespace[fn]
if "." in fn:
if callee is None and "." in fn:
lon, short = fn.rsplit(".", 1)
holder = self.lookup(lon)
callee = getattr(holder, short)
if callee:
if callee is not None:
return callee
raise Exception("No such symbol: `%s`" % (fn))

View File

@ -5,9 +5,7 @@ import imp
import os
def _hy_import_file(fd):
name = 'hython file'
def _hy_import_file(fd, name):
m = forge_module(
name,
fd,
@ -34,8 +32,11 @@ class MetaImporter(object):
def load_module(self, name):
if name not in sys.modules:
sys.modules[name] = None
sys.modules[name] = _hy_import_file(self.path)
sys.modules[name].__loader__ = self
mod = _hy_import_file(self.path, name)
mod.__file__ = self.path
mod.__name__ = name
mod.__loader__ = self
sys.modules[name] = mod
return sys.modules[name]

20
hy/lang/internals.py Normal file
View File

@ -0,0 +1,20 @@
#
class HYNamespaceCOW(object):
def __init__(self, inmutable_copy):
self._inmute = inmutable_copy
self._mute = {}
def __contains__(self, key):
if key in self._mute:
return True
return key in self._inmute
def __getitem__(self, key):
if key in self._mute:
return self._mute[key]
return self._inmute[key]
def __setitem__(self, key, value):
self._mute[key] = value

View File

@ -7,4 +7,9 @@ class HYMap(dict, HYObject):
self[node] = nodes[node]
def get_children(self):
return self.keys() + self.values()
ret = []
for v in self.keys():
ret.append(v)
for v in self.values():
ret.append(v)
return ret

View File

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

View File

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

View File

@ -5,6 +5,7 @@ from hy.lang.symbol import HYSymbol
from hy.lang.number import HYNumber
from hy.lex.machine import Machine
from hy.lang.list import HYList
from hy.lang.bool import HYBool
from hy.lang.map import HYMap
@ -12,6 +13,11 @@ WHITESPACE = [" ", "\t", "\n", "\r"]
def _resolve_atom(value):
if value == "true":
return HYBool(True)
elif value == "false":
return HYBool(False)
if value.isdigit():
return HYNumber(value)
return HYSymbol(value)

View File

@ -2,7 +2,10 @@
from setuptools import setup
long_description = open('README.md', 'r').read()
long_description = """This thing does stuff and
things with other things until things looks like other
things. """
appname = "hy"
version = "0.6.0"

4
tests/lang/foo.hy Normal file
View File

@ -0,0 +1,4 @@
; vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 filetype=lisp
(def square (fn [arg]
(* arg arg)))

10
tests/lang/kwargs.hy Normal file
View File

@ -0,0 +1,10 @@
; vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 filetype=lisp
(import ["tests.lang.test_kwargs"])
(def kiwi (fn []
(kwapply (tests.lang.test_kwargs.shim "one" "two") {
"three" "three"
"four" "four"
})
))

13
tests/lang/test_import.py Normal file
View File

@ -0,0 +1,13 @@
import hy.lang.importer
import tests.lang.foo
def square(x):
return x * x
def test_squares_properly():
assert tests.lang.foo.square
assert tests.lang.foo.square(2) == 4
for x in range(0, 10):
tests.lang.foo.square(x)

18
tests/lang/test_kwargs.py Normal file
View File

@ -0,0 +1,18 @@
import hy.lang.importer
def shim(*args, **kwargs):
return {"a": args,
"k": kwargs}
def test_kwargs_proper():
import tests.lang.kwargs
val = tests.lang.kwargs.kiwi()
assert val == {
"a": ('one', 'two'),
"k": {
"three": "three",
"four": "four"
}
}

7
tox.ini Normal file
View File

@ -0,0 +1,7 @@
# content of: tox.ini , put in same dir as setup.py
[tox]
envlist = py27,pypy,py32,py33
# jython -- jython fails?
[testenv]
commands = nosetests
deps = nose