]> git.lizzy.rs Git - metalua.git/commitdiff
added destructuring set extension
authorFabien Fleutot <fabien@macfabien.local>
Mon, 18 Feb 2008 18:49:13 +0000 (19:49 +0100)
committerFabien Fleutot <fabien@macfabien.local>
Mon, 18 Feb 2008 18:49:13 +0000 (19:49 +0100)
src/lib/extension/dset.mlua [new file with mode: 0644]
src/samples/dset_test.mlua [new file with mode: 0644]

diff --git a/src/lib/extension/dset.mlua b/src/lib/extension/dset.mlua
new file mode 100644 (file)
index 0000000..6a88ad7
--- /dev/null
@@ -0,0 +1,72 @@
+require 'extension.match'
+require 'walk.id'
+
+local function destructuring_set (x)
+   local patterns, values = unpack(x)
+   
+   local code, vars do
+      local mcfg = {
+         on_failure = mlp.gensym 'mismatch' [1],
+         locals = { },
+         code = { } }
+      spmatch.pattern_seq_builder(patterns, values, mcfg)
+      local on_success = mlp.gensym 'on_success' [1]
+      code = { 
+         mcfg.code; 
+         `Goto{ on_success }; 
+         `Label{ mcfg.on_failure }; 
+         +{error "Destructuring bind error"};
+         `Label{ on_success } }
+      vars = mcfg.locals
+   end
+   
+   local vars_in_pattern do
+      vars_in_pattern = { }
+      local wcfg = { id = { } }
+      function wcfg.id.free(v) printf("%s is free", v[1]); vars_in_pattern[v[1]]=true end
+      walk_id.expr_list(wcfg, patterns)
+   end
+
+   local vars_not_in_pattern do
+      vars_not_in_pattern = { }
+      for k in keys(vars) do
+         if not vars_in_pattern[k] then
+            vars_not_in_pattern[k] = true
+         end
+      end
+   end
+
+   if next(vars_not_in_pattern) then
+      local loc = { }
+      for k in keys (vars_not_in_pattern) do 
+         table.insert (loc, `Id{k})
+      end
+      table.insert (code, 1, `Local{ loc, { } })
+   end
+
+   local decl_list do
+      decl_list = { }
+      for k in keys (vars_in_pattern) do
+         table.insert (decl_list, `Id{k})
+      end
+   end
+
+   return code, decl_list
+end
+
+function local_destructuring_set(x)
+   local code, vars = destructuring_set (x)
+   return { `Local{ vars, { } }; code }
+end
+
+function non_local_destructuring_set(x)
+   local code, _ = destructuring_set (x)
+   code.tag = 'Do'
+   return code
+end
+
+mlp.lexer:add 'bind'
+mlp.stat:add{ 'bind', mlp.expr_list, '=', mlp.expr_list, 
+   builder = non_local_destructuring_set }
+mlp.stat:get'local'[2]:add{ 'bind', mlp.expr_list, '=', mlp.expr_list, 
+   builder = local_destructuring_set }
\ No newline at end of file
diff --git a/src/samples/dset_test.mlua b/src/samples/dset_test.mlua
new file mode 100644 (file)
index 0000000..5581b39
--- /dev/null
@@ -0,0 +1,17 @@
+-{ extension 'dset' }
+
+require 'strict'
+
+bind {a, b} = {'o', 'k'}
+
+print(a..b)
+
+c, d = 'k', 'o'
+
+do
+   local bind {c, {d}} = {'o', {'k'}}
+   print(c..d)
+end
+
+print(d..c)
+