Extra "ports" of juce-based plugins using the distrho build system
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
6.1KB

  1. -- iluaembed.lua
  2. -- based on Steve Donovan's executable ilua.lua (2007)
  3. -- "A more friendly Lua interactive prompt
  4. -- doesn't need '='
  5. -- will try to print out tables recursively, subject to the pretty_print_limit value."
  6. --
  7. -- version by osar.fr to embed the interactive Lua console in C/C++ programs
  8. -- creates a global function to be called by the host
  9. --
  10. local pretty_print_limit = 20
  11. local max_depth = 7
  12. local table_clever = true
  13. local prompt = '> '
  14. local verbose = false
  15. local strict = true
  16. -- suppress strict warnings
  17. _ = true
  18. -- imported global functions
  19. local sub = string.sub
  20. local match = string.match
  21. local find = string.find
  22. local push = table.insert
  23. local pop = table.remove
  24. local append = table.insert
  25. local concat = table.concat
  26. local floor = math.floor
  27. local write = io.write
  28. local read = io.read
  29. local savef
  30. local collisions = {}
  31. local G_LIB = {}
  32. local declared = {}
  33. local line_handler_fn, global_handler_fn
  34. local print_handlers = {}
  35. ilua = {}
  36. local num_prec
  37. local num_all
  38. local jstack = {}
  39. local function oprint(...)
  40. if savef then
  41. savef:write(concat({...},' '),'\n')
  42. end
  43. print(...)
  44. end
  45. local function join(tbl,delim,limit,depth)
  46. if not limit then limit = pretty_print_limit end
  47. if not depth then depth = max_depth end
  48. local n = #tbl
  49. local res = ''
  50. local k = 0
  51. -- very important to avoid disgracing ourselves with circular referencs...
  52. if #jstack > depth then
  53. return "..."
  54. end
  55. for i,t in ipairs(jstack) do
  56. if tbl == t then
  57. return "<self>"
  58. end
  59. end
  60. push(jstack,tbl)
  61. -- this is a hack to work out if a table is 'list-like' or 'map-like'
  62. -- you can switch it off with ilua.table_options {clever = false}
  63. local is_list
  64. if table_clever then
  65. local index1 = n > 0 and tbl[1]
  66. local index2 = n > 1 and tbl[2]
  67. is_list = index1 and index2
  68. end
  69. if is_list then
  70. for i,v in ipairs(tbl) do
  71. res = res..delim..ilua.val2str(v)
  72. k = k + 1
  73. if k > limit then
  74. res = res.." ... "
  75. break
  76. end
  77. end
  78. else
  79. for key,v in pairs(tbl) do
  80. if type(key) == 'number' then
  81. key = '['..tostring(key)..']'
  82. else
  83. key = tostring(key)
  84. end
  85. res = res..delim..key..'='..ilua.val2str(v)
  86. k = k + 1
  87. if k > limit then
  88. res = res.." ... "
  89. break
  90. end
  91. end
  92. end
  93. pop(jstack)
  94. return sub(res,2)
  95. end
  96. function ilua.val2str(val)
  97. local tp = type(val)
  98. if print_handlers[tp] then
  99. local s = print_handlers[tp](val)
  100. return s or '?'
  101. end
  102. if tp == 'function' then
  103. return tostring(val)
  104. elseif tp == 'table' then
  105. if val.__tostring then
  106. return tostring(val)
  107. else
  108. return '{'..join(val,',')..'}'
  109. end
  110. elseif tp == 'string' then
  111. return "'"..val.."'"
  112. elseif tp == 'number' then
  113. -- we try only to apply floating-point precision for numbers deemed to be floating-point,
  114. -- unless the 3rd arg to precision() is true.
  115. if num_prec and (num_all or floor(val) ~= val) then
  116. return num_prec:format(val)
  117. else
  118. return tostring(val)
  119. end
  120. else
  121. return tostring(val)
  122. end
  123. end
  124. function ilua.pretty_print(...)
  125. local arg = {...}
  126. for i,val in ipairs(arg) do
  127. oprint(ilua.val2str(val))
  128. end
  129. _G['_'] = arg[1]
  130. end
  131. function ilua.compile(line)
  132. if verbose then oprint(line) end
  133. local f,err = loadstring(line,'local')
  134. return err,f
  135. end
  136. function ilua.evaluate(chunk)
  137. local ok,res = pcall(chunk)
  138. if not ok then
  139. return res
  140. end
  141. return nil -- meaning, fine!
  142. end
  143. function ilua.eval_lua(line)
  144. if savef then
  145. savef:write(prompt,line,'\n')
  146. end
  147. -- is the line handler interested?
  148. if line_handler_fn then
  149. line = line_handler_fn(line)
  150. -- returning nil here means that the handler doesn't want
  151. -- Lua to see the string
  152. if not line then return end
  153. end
  154. -- is it an expression?
  155. local err,chunk = ilua.compile('ilua.pretty_print('..line..')')
  156. if err then
  157. -- otherwise, a statement?
  158. err,chunk = ilua.compile(line)
  159. end
  160. -- if compiled ok, then evaluate the chunk
  161. if not err then
  162. err = ilua.evaluate(chunk)
  163. end
  164. -- if there was any error, print it out
  165. if err then
  166. oprint(err)
  167. end
  168. end
  169. -- functions available in scripts
  170. function ilua.precision(len,prec,all)
  171. if not len then num_prec = nil
  172. else
  173. num_prec = '%'..len..'.'..prec..'f'
  174. end
  175. num_all = all
  176. end
  177. function ilua.table_options(t)
  178. if t.limit then pretty_print_limit = t.limit end
  179. if t.depth then max_depth = t.depth end
  180. if t.clever ~= nil then table_clever = t.clever end
  181. end
  182. -- inject @tbl into the global namespace
  183. function ilua.import(tbl,dont_complain,lib)
  184. lib = lib or '<unknown>'
  185. if type(tbl) == 'table' then
  186. for k,v in pairs(tbl) do
  187. local key = rawget(_G,k)
  188. -- NB to keep track of collisions!
  189. if key and k ~= '_M' and k ~= '_NAME' and k ~= '_PACKAGE' and k ~= '_VERSION' then
  190. append(collisions,{k,lib,G_LIB[k]})
  191. end
  192. _G[k] = v
  193. G_LIB[k] = lib
  194. end
  195. end
  196. if not dont_complain and #collisions > 0 then
  197. for i, coll in ipairs(collisions) do
  198. local name,lib,oldlib = coll[1],coll[2],coll[3]
  199. write('warning: ',lib,'.',name,' overwrites ')
  200. if oldlib then
  201. write(oldlib,'.',name,'\n')
  202. else
  203. write('global ',name,'\n')
  204. end
  205. end
  206. end
  207. end
  208. function ilua.print_handler(name,handler)
  209. print_handlers[name] = handler
  210. end
  211. function ilua.line_handler(handler)
  212. line_handler_fn = handler
  213. end
  214. function ilua.global_handler(handler)
  215. global_handler_fn = handler
  216. end
  217. function ilua.print_variables()
  218. for name,v in pairs(declared) do
  219. print(name,type(_G[name]))
  220. end
  221. end
  222. function ilua_runline(line)
  223. ilua.eval_lua(line)
  224. end