]> git.lizzy.rs Git - metalua.git/blobdiff - src/lib/metalua/extension/xloop.mlua
Merge branch 'master' of ssh://git.eclipse.org/gitroot/koneki/org.eclipse.koneki...
[metalua.git] / src / lib / metalua / extension / xloop.mlua
diff --git a/src/lib/metalua/extension/xloop.mlua b/src/lib/metalua/extension/xloop.mlua
deleted file mode 100644 (file)
index b8b20e6..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
--{ extension 'match' }
--{ extension 'log' }
-
-require 'metalua.walk'
-
-----------------------------------------------------------------------
--- Back-end:
-----------------------------------------------------------------------
-
--- Parse additional elements in a loop
-loop_element = gg.multisequence{
-   { 'while',  mlp.expr, builder = |x| `Until{ `Op{ 'not', x[1] } } },
-   { 'until',  mlp.expr, builder = |x| `Until{ x[1] } },
-   { 'if',     mlp.expr, builder = |x| `If{ x[1] } },
-   { 'unless', mlp.expr, builder = |x| `If{ `Op{ 'not', x[1] } } },
-   { 'for',    mlp.for_header, builder = |x| x[1] } }
-
--- Recompose the loop
-function xloop_builder(x)
-   local first, elements, body = unpack(x)
-
-   -------------------------------------------------------------------
-   -- If it's a regular loop, don't bloat the code
-   -------------------------------------------------------------------
-   if not next(elements) then
-      table.insert(first, body)
-      return first
-   end
-
-   -------------------------------------------------------------------
-   -- There's no reason to treat the first element in a special way
-   -------------------------------------------------------------------
-   table.insert(elements, 1, first)
-
-   -------------------------------------------------------------------
-   -- if a header or a break must be able to exit the loops, ti will
-   -- set exit_label and use it (a regular break wouldn't be enough,
-   -- as it couldn't escape several nested loops.)
-   -------------------------------------------------------------------
-   local exit_label
-   local function exit()
-      if not exit_label then exit_label = mlp.gensym 'break' [1] end
-      return `Goto{ exit_label }
-   end
-
-   -------------------------------------------------------------------
-   -- Compile all headers elements, from last to first
-   -------------------------------------------------------------------
-   for i = #elements, 1, -1 do
-      local e = elements[i]
-      match e with
-      | `If{ cond }    ->
-         body = `If{ cond, {body} }
-      | `Until{ cond } ->
-         body = +{stat: if -{cond} then -{exit()} else -{body} end }
-      | `Forin{ ... } | `Fornum{ ... } ->
-         table.insert (e, {body}); body=e
-      end
-   end
-
-   -------------------------------------------------------------------
-   -- Change breaks into gotos that escape all loops at once.
-   -------------------------------------------------------------------
-   local cfg = { stat = { }, expr = { } }
-   function cfg.stat.down(x)
-      match x with
-      | `Break -> x <- exit()
-      | `Forin{ ... } | `Fornum{ ... } | `While{ ... } | `Repeat{ ... } ->
-         return 'break'
-      | _ -> -- pass
-      end
-   end
-   function cfg.expr.down(x) if x.tag=='Function' then return 'break' end end
-   walk.stat(cfg, body)
-
-   if exit_label then body = { body, `Label{ exit_label } } end
-   return body
-end
-
-----------------------------------------------------------------------
--- Front-end:
-----------------------------------------------------------------------
-
-mlp.lexer:add 'unless'
-mlp.stat:del  'for'
-mlp.stat:del  'while'
-
-loop_element_list = gg.list{ loop_element, terminators='do' }
-
-mlp.stat:add{
-   'for', mlp.for_header, loop_element_list, 'do', mlp.block, 'end',
-   builder = xloop_builder }
-
-mlp.stat:add{
-   'while', mlp.expr, loop_element_list, 'do', mlp.block, 'end',
-   builder = |x| xloop_builder{ `While{x[1]}, x[2], x[3] } }
-
-mlp.stat:add{
-   'unless', mlp.expr, 'then', mlp.block, 'end',
-   builder = |x| +{stat: if not -{x[1]} then -{x[2]} end} }