defclass should add an implicit nil to --init-- functions

To make it easier to write --init-- functions, defclass will now check
any (setv) expressions (and its property list), to find any --init--
declarations, and append a nil to the end.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
This commit is contained in:
Gergely Nagy 2015-08-10 10:58:13 +02:00
parent b1f497ae72
commit c89865aaf0
2 changed files with 36 additions and 6 deletions

View File

@ -2259,6 +2259,22 @@ class HyASTCompiler(object):
@builds("defclass")
@checkargs(min=1)
def compile_class_expression(self, expressions):
def rewire_init(expr):
new_args = []
if expr[0] == HySymbol("setv"):
pairs = expr[1:]
while len(pairs) > 0:
k, v = (pairs.pop(0), pairs.pop(0))
if k == HySymbol("__init__"):
v.append(HySymbol("None"))
new_args.append(k)
new_args.append(v)
expr = HyExpression([
HySymbol("setv")
] + new_args).replace(expr)
return expr
expressions.pop(0) # class
class_name = expressions.pop(0)
@ -2291,14 +2307,14 @@ class HyASTCompiler(object):
if expressions and isinstance(expressions[0], HyList) \
and not isinstance(expressions[0], HyExpression):
expr = expressions.pop(0)
body += self.compile(
HyExpression([
HySymbol("setv")
] + expr).replace(expr)
)
expr = HyExpression([
HySymbol("setv")
] + expr).replace(expr)
body += self.compile(rewire_init(expr))
for expression in expressions:
body += self.compile(macroexpand(expression, self.module_name))
expr = rewire_init(macroexpand(expression, self.module_name))
body += self.compile(expr)
self.allow_builtins = allow_builtins

View File

@ -109,3 +109,17 @@
(assert (= a.y 2))
(assert foo 2)
(assert (.greet a) "hello"))
(defn test-defclass-implicit-nil-for-init []
"NATIVE: test that defclass adds an implicit nil to --init--"
(defclass A []
[--init-- (fn [self] (setv self.x 1) 42)])
(defclass B []
(defn --init-- [self]
(setv self.x 2)
42))
(setv a (A))
(setv b (B))
(assert (= a.x 1))
(assert (= b.x 2)))