hacking on stuff.
This commit is contained in:
parent
94040dfbd3
commit
4f5bc16508
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
*.pyc
|
||||
*swp
|
||||
*hy*egg*
|
||||
.tox
|
||||
*pycache*
|
||||
|
@ -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
9
hy/lang/bool.py
Normal 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
|
@ -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,
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
20
hy/lang/internals.py
Normal 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
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -6,4 +6,5 @@ class HYSymbol(HYString):
|
||||
self += string
|
||||
|
||||
def eval(self, *args, **kwargs):
|
||||
return self.lookup(self)
|
||||
obj = self.lookup(self)
|
||||
return obj
|
||||
|
@ -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)
|
||||
|
5
setup.py
5
setup.py
@ -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
4
tests/lang/foo.hy
Normal 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
10
tests/lang/kwargs.hy
Normal 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
13
tests/lang/test_import.py
Normal 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
18
tests/lang/test_kwargs.py
Normal 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"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user