]> git.lizzy.rs Git - metalua.git/commitdiff
fixed trycatch
authorFabien Fleutot <fabien@macfabien.local>
Wed, 27 Feb 2008 19:15:32 +0000 (20:15 +0100)
committerFabien Fleutot <fabien@macfabien.local>
Wed, 27 Feb 2008 19:15:32 +0000 (20:15 +0100)
src/lib/extension/trycatch.mlua
src/lib/extension/withdo.mlua

index 2dc0015e2c6631c6c02690aaa3655771163a2ec9..fe99396bbe26e5b829c1a793b354a366a0616db0 100644 (file)
@@ -27,12 +27,13 @@ local mkpcall = |block| +{pcall(function() -{block} end)}
 function trycatch_builder(x)\r
    --$log ("trycatch_builder", x, 'nohash', 60)\r
    local try_code, catch_cases, finally_code = unpack(x)\r
-   local insert_return_catcher = false\r
+   local insert_return_catcher = false   \r
 \r
    -- Can't be hygienize automatically by the current version of H, as\r
    -- it must bridge from inside user code (hacjed return statements)\r
    -- to outside macro code.\r
    local caught_return = !mlp.gensym 'caught_return'\r
+   local saved_args\r
 \r
    !try_code; !(finally_code or { })\r
    -- FIXME: Am I sure there's no need to hygienize inside?\r
@@ -68,7 +69,7 @@ function trycatch_builder(x)
    -- allows to avoid inserting return-handling code in the result\r
    -- when not needed.\r
    ----------------------------------------------------------------\r
-   local replace_returns do\r
+   local replace_returns_and_dots do\r
       local function f(x)\r
          match x with \r
          | `Return{...} -> \r
@@ -80,15 +81,18 @@ function trycatch_builder(x)
             return 'break'\r
          | `Function{...} -> return 'break' \r
             -- inside this, returns would be the nested function's, not ours.\r
+         | `Dots ->\r
+            if not saved_args then saved_args = mlp.gensym 'args' end\r
+            x <- `Call{ `Id 'unpack', saved_args }               \r
          | _ -> -- pass\r
          end\r
       end\r
       local cfg = { stat = {down=f}, expr = {down=f} }\r
-      replace_returns = |x| walk.block(cfg, x)\r
+      replace_returns_and_dots = |x| walk.block(cfg, x)\r
    end\r
 \r
    -- parse returns in the try-block:\r
-   replace_returns (try_code)\r
+   replace_returns_and_dots (try_code)\r
 \r
    -- code handling the error catching process:\r
    local catch_result do\r
@@ -101,7 +105,7 @@ function trycatch_builder(x)
          for x in ivalues (catch_cases) do\r
             local case_code = x[3]\r
             -- handle rogue returns:\r
-            replace_returns (case_code)\r
+            replace_returns_and_dots (case_code)\r
             -- in case of error in the catch, we still need to run "finally":\r
             x[3] = +{block: catch_success, catch_error = -{mkpcall(case_code)}}\r
          end\r
@@ -129,6 +133,9 @@ function trycatch_builder(x)
          caught_return_init, caught_return_rethrow = { }, { }\r
       end\r
    end\r
+   \r
+   local saved_args_init =\r
+      saved_args and `Local{ {saved_args}, { `Table{`Dots} } } or { }\r
 \r
    -- The finally code, to execute no matter what:\r
    local finally_result = finally_code or { }\r
@@ -136,6 +143,7 @@ function trycatch_builder(x)
    -- And the whole statement, gluing all taht together:\r
    local result = +{stat: \r
       do\r
+         -{ saved_args_init }\r
          -{ caught_return_init }\r
          local user_success,  user_error  = -{mkpcall(try_code)}\r
          local catch_success, catch_error = false, user_error\r
index c5db10008fc2c85deb19485c893dd19448d3869a..ea7f3200a500572561bcf755370523978b3180bd 100644 (file)
@@ -15,12 +15,12 @@ function withdo_builder (x)
    local names, vals, body = unpack(x)
    for i = #names, 1, -1 do
       local name, val = names[i], vals[i]
-      body = trycatch_builder{
-         { `Set{ {name}, {val} }, body }, -- try-block
-         { }, -- catch-block
-         {  +{ print ("closing "..-{`String{name[1]}}) },
-            `Invoke{ name, `String "close" } } }
+      body = trycatch_builder{ { `Set{ {name}, {val} }, body }, -- try-block
+                               { }, -- catch-block
+                               { +{ print ("closing "..-{`String{name[1]}}) },
+                                 `Invoke{ name, `String "close" } } } }
    end
+   table.insert(body, 1, `Local{ names })
    return body
 end