rev 523 - in trunk: docs/tutorial pr/test src

SVN User <[email protected]> Thu, 20 May 2004 22:11:22 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-05-20 22:11:19 -0400 (Thu, 20 May 2004)
New Revision: 523

Modified:
   trunk/docs/tutorial/index.htm
   trunk/docs/tutorial/outline2.htm
   trunk/docs/tutorial/tutorial11.htm
   trunk/pr/test/test.pr
   trunk/src/builtins-core.c
Log:
started exception section of tutorial

Modified: trunk/docs/tutorial/index.htm
===================================================================
--- trunk/docs/tutorial/index.htm	2004-05-21 00:00:58 UTC (rev 522)
+++ trunk/docs/tutorial/index.htm	2004-05-21 02:11:19 UTC (rev 523)
@@ -58,9 +58,9 @@
           are subject to change until approximately July of 2004.</p>
         <p>Like Prothon itself, the tutorial is not finished. The following topics 
           are not covered yet: print statement, import, modules, packages, list 
-          comprehensions, gen keyword, exceptions, security system, files, console 
-          line editing. Email <a href="mailto:[email protected]">me</a> about any 
-          things I've not covered that aren't on this list.</p>
+          comprehensions, try/finally, security system, files, console line editing. 
+          Email <a href="mailto:[email protected]">me</a> about any things I've 
+          not covered that aren't on this list.</p>
         <p align="center"><font size="-1">This tutorial is copyright Mark Hahn, 
           2004, all rights reserved. </font></p>
         <p>&nbsp;</p>
Modified: trunk/docs/tutorial/outline2.htm
===================================================================
--- trunk/docs/tutorial/outline2.htm	2004-05-21 00:00:58 UTC (rev 522)
+++ trunk/docs/tutorial/outline2.htm	2004-05-21 02:11:19 UTC (rev 523)
@@ -113,10 +113,31 @@
                 <ul>
                   <li><a href="tutorial10.htm#caller">Caller Explained</a> 
                   <li><a href="tutorial10.htm#calleuses">Uses for Caller &amp; 
-                    Example</a>
+                    Example</a> 
                 </ul>
             </ul>
+          <li>8. <a href="tutorial11.htm#genexc">Generators &amp; Exceptions</a> 
+            <ul>
+              <li><a href="tutorial11.htm#gen">8.1 Generators</a> 
+                <ul>
+                  <li><a href="tutorial10.htm#locscobj">Gen Keyword</a> 
+                  <li><a href="tutorial11.htm#yieldkey">Yield Keyword</a> 
+                  <li><a href="tutorial11.htm#example">Example</a> 
+                  <li><a href="tutorial11.htm#nesting">Nested Generators</a> 
+                  <li><a href="tutorial11.htm#stackless">Stackless Operation</a> 
+                  <li><a href="tutorial11.htm#frames">Execution Frames</a> 
+                </ul>
+              <li><a href="tutorial11.htm#except">8.2 Exceptions</a> 
+                <ul>
+                  <li><a href="tutorial11.htm#lvasc">Raising an Exception</a> 
+                  <li><a href="tutorial11.htm#excobj">Exception Object</a> 
+                  <li><a href="tutorial11.htm#tryexc">Try Except Keywords</a> 
+                  <li><a href="tutorial11.htm#sample">Example</a>
+                </ul>
+            </ul>
+          
         </ul>
+            
       </td>
     </tr>
   </table>
Modified: trunk/docs/tutorial/tutorial11.htm
===================================================================
--- trunk/docs/tutorial/tutorial11.htm	2004-05-21 00:00:58 UTC (rev 522)
+++ trunk/docs/tutorial/tutorial11.htm	2004-05-21 02:11:19 UTC (rev 523)
@@ -33,17 +33,18 @@
   <table width="629" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffee" height="1707">
     <tr> 
       <td height="2569" valign="top"> 
-        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="vsm"></a>8.0 
+        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="genexc"></a>8.0 
           Generators &nbsp;&amp; Exceptions</font></p>
-        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="lvasc"></a>8.1 
-          Generator &amp; Gen Keyword</font></p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="gen"></a>8.1 
+          Generators</font></p>
         <p>In section <a href="tutorial5.htm#forstmt">4.2</a> we learned that 
           the &quot;for&quot; statement uses iterators to generate the sequence 
           of values for each loop, and that an iterator is simply a function that 
           responds to repeated calls of a method &quot;next()&quot; by returning 
           values until it signals the end of the sequence with an exception. </p>
-        <p>Prothon has a &quot;gen&quot; keyword to make a &quot;gen&quot; statement 
-          that looks identical to the &quot;def&quot; statement with &quot;def&quot; 
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="genkey"></a></font>Prothon 
+          has a &quot;gen&quot; keyword to make a &quot;gen&quot; statement that 
+          looks identical to the &quot;def&quot; statement with &quot;def&quot; 
           replaced by &quot;gen&quot;: &quot;gen name(params): body&quot;. So 
           &quot;gen&quot; defines a function-like object with a name, formal parameters, 
           and a code body. The difference is that the object created is always 
@@ -52,16 +53,18 @@
           it produces &quot;generates&quot; values. It works either way. For this 
           discussion we will use the second meaning, that it generates values 
           when it runs.</p>
-        <p>The generator has to use another keyword, &quot;yield&quot; in order 
-          to do the actual generation of values. Yield is somewhat like the &quot;return&quot; 
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="yieldkey"></a></font>The 
+          generator has to use another keyword, &quot;yield&quot; in order to 
+          do the actual generation of values. Yield is somewhat like the &quot;return&quot; 
           keyword in that it has an argument that is used as a return value when 
           &quot;yield&quot; is executed, but unlike &quot;return&quot; the function 
           execution is not terminated. Instead, the state of the function is stored 
           away, or &quot;frozen&quot; if you want to think of it that way so that 
           the function can resume execution at the statement after the yield later 
           when another value is needed.</p>
-        <p>So in it's simplest form, the &quot;gen&quot; is like a function that 
-          runs until it hits a &quot;yield&quot; and then returns the &quot;yield&quot; 
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="example"></a></font>So 
+          in it's simplest form, the &quot;gen&quot; is like a function that runs 
+          until it hits a &quot;yield&quot; and then returns the &quot;yield&quot; 
           value. Then it is paused until &quot;next()&quot; is called on the iterator 
           again and then the function resumes execution until it hits the next 
           yield, returns the second value, pauses again, etc. This continues until 
@@ -77,11 +80,12 @@
 
 for i in odds(10):
     print i,        #  prints 1 3 5 7 9</pre>
-        <p>Prothon also allows you to call other functions with yields in them 
-          to build up more complex code structure. When doing so, only the one 
-          outermost &quot;function&quot; should use the &quot;gen&quot; keyword, 
-          because it is the one producing an iterator, not being called. The others 
-          are being called as normal. </p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="nesting"></a></font>Prothon 
+          also allows you to call other functions with yields in them to build 
+          up more complex code structure. When doing so, only the one outermost 
+          &quot;function&quot; should use the &quot;gen&quot; keyword, because 
+          it is the one producing an iterator, not being called. The others are 
+          being called as normal. </p>
         <pre># Prothon source file tut17.pr
  
 gen evenOdds(max):
@@ -102,18 +106,20 @@
 
 for i in evenOdds(10):
     print i,   #  prints 0 2 4 6 8 1 3 5 7 9</pre>
-        <p>In order to explain how generators and the yield statement works, I 
-          need to explain a bit about function calling in Prothon. Prothon is 
-          &quot;stackless&quot;. What this means is that the interpreter maintains 
-          a data structure that holds the stack of Prothon objects, stack pointer, 
-          code data, program counter, and various scope objects for each &quot;execution 
-          frame&quot; totally seperate from any operating system stack. An execution 
-          frame is the data needed by each scope of running code. Whenever a function 
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="stackless"></a></font>In 
+          order to explain how generators and the yield statement works, I need 
+          to explain a bit about function calling in Prothon. Prothon is &quot;stackless&quot;. 
+          What this means is that the interpreter maintains a data structure that 
+          holds the stack of Prothon objects, stack pointer, code data, program 
+          counter, and various scope objects for each &quot;execution frame&quot; 
+          totally seperate from any operating system stack. An execution frame 
+          is the data needed by each scope of running code. Whenever a function 
           call happens, a new &quot;execution frame&quot; is created and put on 
           the list of running frames. When a function returns, that frame is usually 
           destroyed after the return value is copied from it.</p>
-        <p>When a yield statement is executed, things are done a bit differently. 
-          A reference to the current execution frame is stored in the generator 
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="frames"></a></font>When 
+          a yield statement is executed, things are done a bit differently. A 
+          reference to the current execution frame is stored in the generator 
           object instead of being destroyed. If it was a normal function defined 
           by a &quot;def&quot; keyword, then the next one is stored. This is repeated 
           until one is stored that was created by a &quot;gen&quot; keyword instead 
@@ -125,6 +131,72 @@
           them all back on the active frames list and restarts the code where 
           it left off. This sounds like it might be slow but in actuality it only 
           involves moving a reference pointer for each function and is very fast.</p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="except"></a>8.2 
+          Exceptions</font></p>
+        <p>There are exceptional conditions when the normal flow of code needs 
+          to be interrupted and you need to quit what you are doing and get out 
+          of your current scope fast. These conditions can range from errors like 
+          I/O errors, divide-by-zero errors, to more normal events that are just 
+          expected less often, like running out of some resource.</p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="lvasc"></a></font>Prothon 
+          has an exception mechanism that handles these situations by &quot;raising 
+          an exception&quot; which causes execution to be interrupted at the current 
+          location and resumed at some location outside of the current scope. 
+          This is much like the &quot;break&quot;, &quot;return&quot;, or &quot;yield&quot; 
+          statements except that it can happen anywhere.</p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="excobj"></a></font>When 
+          an exception is raised, Prothon creates an Exception object. This is 
+          an object that has the special object Exception somewhere in its prototype 
+          chain. The exception object may also have an attribute called &quot;doc_&quot; 
+          which contains more information about the exception. &quot;doc_&quot; 
+          may be a string or may not, but printing the string version of the exception 
+          obj by calling it via &quot;obj.str_()&quot; will usually give something 
+          useful to view.</p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="tryexc"></a></font>Prothon 
+          has a statement pair called &quot;try&quot; and &quot;except&quot; that 
+          are used to manage exceptions. The form of the pair is &quot;try: try_block&quot;, 
+          &quot;except proto, name: exception_block&quot;. The try_block is executed 
+          and if any exception occurs inside it, then exection is halted and the 
+          except statement is checked to see if the &quot;proto&quot; in the except 
+          statement is in the prototype chain of the exception object. If it is, 
+          then the exception object is stored in &quot;name&quot; as a local variable 
+          of the &quot;exception_block&quot; and the &quot;exception_block&quot; 
+          is executed. Proto may be a list of prototypes.</p>
+        <p> <font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="sample"></a></font>If 
+          &quot;proto&quot; is not in the chain, then the interpreter continues 
+          outward looking for an except statement that does match. Whenever it 
+          leaves an &quot;execution frame&quot; that frame information is kept 
+          for viewing in an exception stack (which we will see in a moment) and 
+          then the execution frame is destroyed. If no except statement matches, 
+          then that thread is killed and an error message is printed on the error 
+          console showing the exception information and the exception stack.</p>
+        <pre># Prothon source file tut18.pr
+ 
+def func():
+    for i in 4:
+        print i, 1/(i-2)
+        
+try:
+    func()
+     
+except Exception, err:
+    print "Exception:", err
+ 
+print
+ 
+func()</pre>
+        Output results (cleaned up):
+        <pre>0 -.5 
+1 -1 
+Exception: Divide by zero Error 
+ 
+0 -.5 
+1 -1 
+ 
+Uncaught exception:
+--- File: C:\Prothon\pr\tutorial\tut18.pr, line: 8, char: 6
+--- File: C:\Prothon\pr\tutorial\tut18.pr, line: 6, char: 24
+Divide by zero Error</pre>
         <p>&nbsp;</p>
       </td>
     </tr>
Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-05-21 00:00:58 UTC (rev 522)
+++ trunk/pr/test/test.pr	2004-05-21 02:11:19 UTC (rev 523)
@@ -1,3 +1,18 @@
 #!/usr/bin/env prothon
 
-print """"""
\ No newline at end of file
+
+# Prothon source file tut18.pr
+
+def func():
+    for i in 4:
+        print i, 1/(i-2)
+        
+try:
+    func()
+    
+except Exception, err:
+    print "Exception:", err
+
+print
+
+func()

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-05-21 00:00:58 UTC (rev 522)
+++ trunk/src/builtins-core.c	2004-05-21 02:11:19 UTC (rev 523)
@@ -496,6 +496,13 @@
 	return OBJ(NONE);
 }
 
+DEF(Exception, str_,  NULL) {
+	obj_p doc;
+	if (!(doc = get_attr(ist, self, SYM(DOC_))))
+		doc = proto_item(ist, self, 0);
+	return call_func0(ist, doc, SYM(STR_));
+}
+
 // ***************************** GEN ******************************************
 MODULE_START(Gen)
 {
@@ -832,6 +839,7 @@
 
 	MODULE_SUB_INIT(Exception);
 	MODULE_ADD_SYM(Exception, init_);
+	MODULE_ADD_SYM(Exception, str_);
 
 	MODULE_SUB_INIT(Gen);
 	MODULE_ADD_SYM(Gen, iter_);