]> git.lizzy.rs Git - metalua.git/commitdiff
updated trycatch to work with new match, new catch...then syntax
authorFabien Fleutot <fabien@macfabien.local>
Mon, 18 Feb 2008 18:48:01 +0000 (19:48 +0100)
committerFabien Fleutot <fabien@macfabien.local>
Mon, 18 Feb 2008 18:48:01 +0000 (19:48 +0100)
doc/manual/trycatch-ref.tex [new file with mode: 0644]
src/samples/clist_test.lua [deleted file]
src/samples/clist_test.mlua [new file with mode: 0644]
src/samples/trycatch_test.mlua
src/samples/types_test.lua [deleted file]
src/samples/types_test.mlua [new file with mode: 0644]

diff --git a/doc/manual/trycatch-ref.tex b/doc/manual/trycatch-ref.tex
new file mode 100644 (file)
index 0000000..dcdb9fb
--- /dev/null
@@ -0,0 +1,87 @@
+\section{Extension {\tt trywith}: exceptions and finalization}\r
+Lua offers error handling primitives \verb+pcall()+ and\r
+\veb+xpcall()+. However, they are pretty low level, and their syntax\r
+is cumbersome to use and read back. This extension offers a proper\r
+syntax for the handling of such exceptions.\r
+\r
+\subsection{Syntax}\r
+An error handling statement has the following form:\r
+\r
+\begin{verbatim}\r
+try\r
+   <protected block>\r
+catch <exception pattern #1> then\r
+   <exception handling block #1>\r
+catch <exception pattern #2> then\r
+   <exception handling block #2>\r
+   ...\r
+catch <exception pattern #n> then\r
+   <exception handling block #n>\r
+finally\r
+   <finalization block>\r
+end\r
+\end{verbatim}\r
+\r
+\subsection{Semantics}\r
+When such a statement is executed:\r
+\begin{itemize}\r
+\item the protected code is executed\r
+\item if its execution causes an error, the error message is matched\r
+  against all exception patterns, until one matches or the last one is\r
+  reached (see the \verb+match+ extension for patterns\r
+  semantics). Patterns can include guard clauses. The block\r
+  corresponding to the first matching pattern is executed. If no\r
+  pattern matches, the error will be rethrown.\r
+\item the block following the \verb+finally+ keyword will be executed\r
+  no matter what: if the protected block executes succesfully, if it\r
+  raises an error, if it causes a \verb+return+, if an error occurs in\r
+  an exception handling block, whether an error is caught or\r
+  not... The only reason why the finalization block might not be run\r
+  is because of a sudden death of the process (call to {\tt os.exit()}\r
+  or core dump).\r
+\end{itemize}\r
+\r
+The finally block can be omitted, or there can be no error catching\r
+case. The following examples are legal:\r
+\r
+\begin{verbatim}\r
+try\r
+   f = io.open ('file.txt', 'r')\r
+   num_char = #f:read '*a'\r
+finally\r
+   f:close()\r
+end\r
+\r
+try\r
+   do_stuff()\r
+catch "mismatch" then\r
+   print "match statement failure"\r
+catch "[Ee]of"/_ then -- regexp pattern\r
+   print "An end-of-file error seems to have happened"\r
+catch x if type(x)=='table' then\r
+   print "The error is a table, not a string!"\r
+end\r
+\end{verbatim}\r
+\r
+ \subsection{RAII}\r
+ RAII, or ``Resource Acquisition Is Initialization'', is a common\r
+ programming pattern in which an object's lifetime is strictly\r
+ associated with a given lexical scope. For instance, if a file is\r
+ opened in a given scope, it must be closed as soon as this scope is\r
+ leaved, even if it's leaved due to a {\tt return} or an error. The\r
+ ``finally'' block allows this, but since it's a very common use case,\r
+ there is a dedicated extension ``with/do'': you initialize some resource\r
+ behind the ``with'' keyword, and it will be closed after the ``do''\r
+ block is left. The only constraint is that the resources must have a\r
+ {\tt:close()} method which releases them. Here is a usage example:\r
+\r
+\begin{verbatim}\r
+-{ extension 'withdo' }\r
+\r
+with f1, f2 = io.open 'file1.txt', io.open 'file2.txt' do\r
+   local t1 = f1:read '*a'\r
+   local t2 = f2:read '*a'\r
+   printf("The files contain %i and %i chars respectively", t1, t2)\r
+end\r
+\end{verbatim}\r
+\r
diff --git a/src/samples/clist_test.lua b/src/samples/clist_test.lua
deleted file mode 100644 (file)
index 0db236c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
--{extension "clist"}
-
--- integers from 2 to 50, by steps of 2:
-x = { i for i = 2, 50, 2 }
-
--- the same, obtained by filtering over all integers <= 50:
-y = { i for i = 1, 50 if i%2==0 }
-
--- prime numbers, implemented in an inefficient way:
-local sieve, n = { i for i=2, 100 }, 1
-while n < #sieve do
-   sieve = { 
-      i for i in values(sieve[1 ... n]);
-      i for i in values(sieve[n+1 ... #sieve]) if i%sieve[n] ~= 0 }
-   n += 1
-end
-
-table.print(sieve)
-
diff --git a/src/samples/clist_test.mlua b/src/samples/clist_test.mlua
new file mode 100644 (file)
index 0000000..0db236c
--- /dev/null
@@ -0,0 +1,19 @@
+-{extension "clist"}
+
+-- integers from 2 to 50, by steps of 2:
+x = { i for i = 2, 50, 2 }
+
+-- the same, obtained by filtering over all integers <= 50:
+y = { i for i = 1, 50 if i%2==0 }
+
+-- prime numbers, implemented in an inefficient way:
+local sieve, n = { i for i=2, 100 }, 1
+while n < #sieve do
+   sieve = { 
+      i for i in values(sieve[1 ... n]);
+      i for i in values(sieve[n+1 ... #sieve]) if i%sieve[n] ~= 0 }
+   n += 1
+end
+
+table.print(sieve)
+
index 84123fe237ca485b0a9f350add9b7b1acd0e1e8c..aff10c46c786a0b029d3d64bcda56dbf7cfe2dce 100644 (file)
@@ -12,11 +12,12 @@ end
 print "2) caught error"
 try
    error "some_error"
-catch x ->
+catch x then
    printf("   Successfully caught %q", x)
 end
 
 
+-- [[
 ----------------------------------------------------------------------
 print "3) no error, with a finally"
 try
@@ -31,8 +32,8 @@ print "4) error, with a finally"
 try
    print "   Hi"
    error "bang"
-catch "bang" ->
-   -- nothing
+catch "bang"/_ then
+   print "   Bang caught"
 finally
    print "   Finally OK"
 end
@@ -43,12 +44,12 @@ print "5) nested catchers"
 try
    try
       error "some_error"
-   catch "some_other_error" ->
+   catch "some_other_error" then
       assert (false, "mismatch, this must not happen")
    end
-catch "some_error"/x ->
+catch "some_error"/x then
    printf("   Successfully caught %q across a try that didn't catch", x)
-| x ->
+catch x then
    assert (false, "We shouldn't reach this catch-all")
 end
 
@@ -58,14 +59,14 @@ print "6) nested catchers, with a 'finally in the inner one"
 try
    try
       error "some_error"
-   catch "some_other_error" ->
+   catch "some_other_error" then
       assert (false, "mismatch, this must not happen")
    finally
       print "   Leaving the inner try-catch"
    end
-catch "some_error"/x ->
+catch "some_error"/{x} then
    printf("   Successfully caught %q across a try that didn't catch", x)
-| x ->
+catch x then
    assert (false, "We shouldn't reach this catch-all")
 end
 
@@ -77,7 +78,7 @@ function f()
       print "   into f:"
       return "F_RESULT"
       assert (false, "I'll never go there")
-   catch _ ->
+   catch _ then
       assert (false, "No exception should be thrown")
    finally
       print "   I do the finally before leaving f()"
@@ -94,7 +95,7 @@ function f()
       local function g() return "from g" end
       printf("   g() returns %q", g())
       return "from f"
-   catch _ ->
+   catch _ then
       assert (false, "No exception should be thrown")
    end
 end
@@ -104,3 +105,4 @@ printf("   f returned %q", fr)
 ----------------------------------------------------------------------
 print "*) done."
 
+--]]
diff --git a/src/samples/types_test.lua b/src/samples/types_test.lua
deleted file mode 100644 (file)
index 62f4a91..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
--{ extension "types" }
--{ extension "clist" }
-
--- Uncomment this to turn typechecking code generation off:
--- -{stat: types.enabled=false}
-
-function sum (x :: table(number)) :: number
-   local acc :: number = 0
-   for i=1, #x do
-      acc = acc + x[i] -- .. 'x' -- converts to string
-   end
-   --acc='bug' -- put a string in a number variable
-   return acc
-end
-
-x       = { i for i=1,100 }
---x[23] = 'toto' -- string in a number list, sum() will complain
-y       = sum (x)
-printf ("sum 1 .. %i = %i", #x, y)
\ No newline at end of file
diff --git a/src/samples/types_test.mlua b/src/samples/types_test.mlua
new file mode 100644 (file)
index 0000000..62f4a91
--- /dev/null
@@ -0,0 +1,19 @@
+-{ extension "types" }
+-{ extension "clist" }
+
+-- Uncomment this to turn typechecking code generation off:
+-- -{stat: types.enabled=false}
+
+function sum (x :: table(number)) :: number
+   local acc :: number = 0
+   for i=1, #x do
+      acc = acc + x[i] -- .. 'x' -- converts to string
+   end
+   --acc='bug' -- put a string in a number variable
+   return acc
+end
+
+x       = { i for i=1,100 }
+--x[23] = 'toto' -- string in a number list, sum() will complain
+y       = sum (x)
+printf ("sum 1 .. %i = %i", #x, y)
\ No newline at end of file