Add disassemble function to hy.core.language
This function dumps the AST or the python code generated by evaluating a quoted expression to stdout. Fixes #58
This commit is contained in:
parent
2f7d40b409
commit
d3fa1fd1a8
@ -45,6 +45,19 @@
|
||||
(_numeric-check n)
|
||||
(- n 1))
|
||||
|
||||
(defn disassemble [tree &optional [codegen false]]
|
||||
"Dump the python AST for a given Hy tree to standard output
|
||||
If the second argument is true, generate python code instead."
|
||||
(import astor)
|
||||
(import hy.compiler)
|
||||
|
||||
(fake-source-positions tree)
|
||||
(setv compiled (hy.compiler.hy_compile tree (calling-module-name)))
|
||||
(print ((if codegen
|
||||
astor.codegen.to_source
|
||||
astor.dump)
|
||||
compiled)))
|
||||
|
||||
(defn distinct [coll]
|
||||
"Return a generator from the original collection with duplicates
|
||||
removed"
|
||||
@ -81,6 +94,15 @@
|
||||
(_numeric-check n)
|
||||
(= (% n 2) 0))
|
||||
|
||||
(defn fake-source-positions [tree]
|
||||
"Fake the source positions for a given tree"
|
||||
(if (and (iterable? tree) (not (string? tree)))
|
||||
(for* [subtree tree]
|
||||
(fake-source-positions subtree)))
|
||||
(for* [attr '[start-line end-line start-column end-column]]
|
||||
(if (not (hasattr tree attr))
|
||||
(setattr tree attr 1))))
|
||||
|
||||
(defn filter [pred coll]
|
||||
"Return all elements from `coll` that pass `pred`"
|
||||
(let [[citer (iter coll)]]
|
||||
@ -276,7 +298,7 @@
|
||||
(_numeric_check n)
|
||||
(= n 0))
|
||||
|
||||
(def *exports* '[calling-module-name cycle dec distinct drop
|
||||
(def *exports* '[calling-module-name cycle dec distinct disassemble drop
|
||||
drop-while empty? even? filter flatten float? gensym
|
||||
inc instance? integer integer? iterable? iterate
|
||||
iterator? macroexpand macroexpand-1 neg? nil? none?
|
||||
|
@ -868,3 +868,23 @@
|
||||
"NATIVE: Test the calling-module-name function"
|
||||
(assert (= (calling-module-name -1) "hy.core.language"))
|
||||
(assert (= (calling-module-name 0) "tests.native_tests.language")))
|
||||
|
||||
|
||||
(defn test-disassemble []
|
||||
"NATIVE: Test the disassemble function"
|
||||
(import sys)
|
||||
(if-python2
|
||||
(import [io [BytesIO :as StringIO]])
|
||||
(import [io [StringIO]]))
|
||||
(setv prev-stdout sys.stdout)
|
||||
(setv sys.stdout (StringIO))
|
||||
(disassemble '(do (leaky) (leaky) (macros)))
|
||||
(setv stdout (.getvalue sys.stdout))
|
||||
(setv sys.stdout prev-stdout)
|
||||
(assert (in "leaky" stdout))
|
||||
(assert (in "macros" stdout))
|
||||
(setv sys.stdout (StringIO))
|
||||
(disassemble '(do (leaky) (leaky) (macros)) true)
|
||||
(setv stdout (.getvalue sys.stdout))
|
||||
(setv sys.stdout prev-stdout)
|
||||
(assert (= stdout "leaky()\nleaky()\nmacros()\n")))
|
||||
|
Loading…
Reference in New Issue
Block a user