Skip to content

Commit

Permalink
Add: attribute access can accept method calls
Browse files Browse the repository at this point in the history
  • Loading branch information
allison-casey committed Jul 20, 2021
1 parent 3e28fe1 commit 44325f3
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
58 changes: 44 additions & 14 deletions hy/core/result_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,23 +440,56 @@ def compile_index_expression(compiler, expr, name, obj, indices):

return ret

@pattern_macro(".", [FORM, many(SYM | brackets(FORM))])


notsym = lambda *dissallowed: some(
lambda x: isinstance(x, Symbol) and str(x) not in dissallowed
)


@pattern_macro(
".",
[
FORM,
many(
SYM
| brackets(FORM)
| pexpr(notsym("unpack-iterable", "unpack-mapping"), many(FORM))
),
],
)
def compile_attribute_access(compiler, expr, name, invocant, keys):
ret = compiler.compile(invocant)

for attr in keys:
if isinstance(attr, Symbol):
ret += asty.Attribute(attr,
value=ret.force_expr,
attr=mangle(attr),
ctx=ast.Load())
else: # attr is a hy List
ret += asty.Attribute(
attr, value=ret.force_expr, attr=mangle(attr), ctx=ast.Load()
)
elif isinstance(attr, Expression):
root, args = attr
func = asty.Attribute(
root, value=ret.force_expr, attr=mangle(root), ctx=ast.Load()
)

args, funcret, keywords = compiler._compile_collect(args, with_kwargs=True)
ret += (
funcret
+ func
+ asty.Call(expr, func=func, args=args, keywords=keywords)
)
else: # attr is a hy List
compiled_attr = compiler.compile(attr[0])
ret = compiled_attr + ret + asty.Subscript(
attr,
value=ret.force_expr,
slice=ast.Index(value=compiled_attr.force_expr),
ctx=ast.Load())
ret = (
compiled_attr
+ ret
+ asty.Subscript(
attr,
value=ret.force_expr,
slice=ast.Index(value=compiled_attr.force_expr),
ctx=ast.Load(),
)
)

return ret

Expand Down Expand Up @@ -820,9 +853,6 @@ def compile_with_expression(compiler, expr, root, args, body):
# * `switch`
# ------------------------------------------------

notsym = lambda *dissallowed: some(
lambda x: isinstance(x, Symbol) and str(x) not in dissallowed
)
keepsym = lambda wanted: some(lambda x: x == Symbol(wanted))
_pattern = forward_decl()
_pattern.define(
Expand Down
5 changes: 5 additions & 0 deletions tests/native_tests/language.hy
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

(import tests.resources [kwtest function-with-a-dash AsyncWithTest]
os.path [exists isdir isfile]
os
sys :as systest
re
operator [or_]
Expand Down Expand Up @@ -1528,6 +1529,10 @@ cee\"} dee" "ey bee\ncee dee"))
(assert (is (. foo [(+ 1 1)] __class__) mycls))
(assert (= (. foo [(+ 1 1)] __class__ __name__ [0]) "m"))
(assert (= (. foo [(+ 1 1)] __class__ __name__ [1]) "y"))
(assert (= (. os (getcwd) (isalpha) __class__ __name__ [0]) "b"))
(assert (= (. "ab hello" (strip "ab ") (upper)) "HELLO"))
(assert (= (. "hElLO\twoRld" (expandtabs :tabsize 4) (lower)) "hello world"))


(setv bar (mycls))
(setv (. foo [1]) bar)
Expand Down

0 comments on commit 44325f3

Please sign in to comment.