1 ----------------------------------------------------------------------
2 -- Metalua: $Id: mlp_meta.lua,v 1.4 2006/11/15 09:07:50 fab13n Exp $
4 -- Summary: Meta-operations: AST quasi-quoting and splicing
6 ----------------------------------------------------------------------
8 -- Copyright (c) 2006, Fabien Fleutot <metalua@gmail.com>.
10 -- This software is released under the MIT Licence, see licence.txt
13 ----------------------------------------------------------------------
16 --------------------------------------------------------------------------------
19 -- * [mlp.splice_content()]
20 -- * [mlp.quote_content()]
22 --------------------------------------------------------------------------------
24 module ("mlp", package.seeall)
26 --------------------------------------------------------------------------------
27 -- External splicing: compile an AST into a chunk, load and evaluate
28 -- that chunk, and replace the chunk by its result (which must also be
30 --------------------------------------------------------------------------------
33 local f = mlc.function_of_ast(ast, '=splice')
38 --------------------------------------------------------------------------------
39 -- Going from an AST to an AST representing that AST
40 -- the only key being lifted in this version is ["tag"]
41 --------------------------------------------------------------------------------
43 --print("QUOTING:", _G.table.tostring(t, 60))
45 function cases.table (t)
46 local mt = { tag = "Table" }
47 --_G.table.insert (mt, { tag = "Pair", quote "quote", { tag = "True" } })
48 if t.tag == "Splice" then
49 assert (#t==1, "Invalid splice")
53 _G.table.insert (mt, { tag = "Pair", quote "tag", quote (t.tag) })
55 for _, v in ipairs (t) do
56 _G.table.insert (mt, quote(v))
60 function cases.number (t) return { tag = "Number", t, quote = true } end
61 function cases.string (t) return { tag = "String", t, quote = true } end
62 return cases [ type (t) ] (t)
65 --------------------------------------------------------------------------------
66 -- when this variable is false, code inside [-{...}] is compiled and
67 -- avaluated immediately. When it's true (supposedly when we're
68 -- parsing data inside a quasiquote), [-{foo}] is replaced by
69 -- [`Splice{foo}], which will be unpacked by [quote()].
70 --------------------------------------------------------------------------------
73 --------------------------------------------------------------------------------
74 -- Parse the inside of a "-{ ... }"
75 --------------------------------------------------------------------------------
76 function splice_content (lx)
77 local parser_name = "expr"
78 if lx:is_keyword (lx:peek(2), ":") then
81 assert (a.tag=="Id", "Invalid splice parser name")
84 local ast = mlp[parser_name](lx)
86 --printf("SPLICE_IN_QUOTE:\n%s", _G.table.tostring(ast, "nohash", 60))
87 return { tag="Splice", ast }
89 if parser_name == "expr" then ast = { { tag="Return", ast } }
90 elseif parser_name == "stat" then ast = { ast }
91 elseif parser_name ~= "block" then
92 error ("splice content must be an expr, stat or block") end
93 --printf("EXEC THIS SPLICE:\n%s", _G.table.tostring(ast, "nohash", 60))
98 --------------------------------------------------------------------------------
99 -- Parse the inside of a "+{ ... }"
100 --------------------------------------------------------------------------------
101 function quote_content (lx)
103 if lx:is_keyword (lx:peek(2), ":") then -- +{parser: content }
104 parser = mlp[id(lx)[1]]
110 local prev_iq = in_a_quote
112 --print("IN_A_QUOTE")
113 local content = parser (lx)
114 local q_content = quote (content)