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> </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 &
- Example</a>
+ Example</a>
</ul>
</ul>
+ <li>8. <a href="tutorial11.htm#genexc">Generators & 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 & Exceptions</font></p>
- <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="lvasc"></a>8.1
- Generator & 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 "for" 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 "next()" by returning
values until it signals the end of the sequence with an exception. </p>
- <p>Prothon has a "gen" keyword to make a "gen" statement
- that looks identical to the "def" statement with "def"
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="genkey"></a></font>Prothon
+ has a "gen" keyword to make a "gen" statement that
+ looks identical to the "def" statement with "def"
replaced by "gen": "gen name(params): body". So
"gen" 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 "generates" 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, "yield" in order
- to do the actual generation of values. Yield is somewhat like the "return"
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="yieldkey"></a></font>The
+ generator has to use another keyword, "yield" in order to
+ do the actual generation of values. Yield is somewhat like the "return"
keyword in that it has an argument that is used as a return value when
"yield" is executed, but unlike "return" the function
execution is not terminated. Instead, the state of the function is stored
away, or "frozen" 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 "gen" is like a function that
- runs until it hits a "yield" and then returns the "yield"
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="example"></a></font>So
+ in it's simplest form, the "gen" is like a function that runs
+ until it hits a "yield" and then returns the "yield"
value. Then it is paused until "next()" 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 "function" should use the "gen" 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
+ "function" should use the "gen" 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
- "stackless". 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 "execution
- frame" 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 "stackless".
+ 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 "execution frame"
+ 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 "execution frame" 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 "def" keyword, then the next one is stored. This is repeated
until one is stored that was created by a "gen" 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 "raising
+ an exception" 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 "break", "return", or "yield"
+ 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 "doc_"
+ which contains more information about the exception. "doc_"
+ may be a string or may not, but printing the string version of the exception
+ obj by calling it via "obj.str_()" 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 "try" and "except" that
+ are used to manage exceptions. The form of the pair is "try: try_block",
+ "except proto, name: exception_block". 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 "proto" in the except
+ statement is in the prototype chain of the exception object. If it is,
+ then the exception object is stored in "name" as a local variable
+ of the "exception_block" and the "exception_block"
+ 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
+ "proto" is not in the chain, then the interpreter continues
+ outward looking for an except statement that does match. Whenever it
+ leaves an "execution frame" 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> </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_);