rev 492 - in trunk: docs/tutorial include/prothon pr/test pr/tutorial src

SVN User <[email protected]> Sun, 16 May 2004 21:23:14 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-05-16 21:23:10 -0400 (Sun, 16 May 2004)
New Revision: 492

Added:
   trunk/docs/tutorial/index2.htm
   trunk/docs/tutorial/tutorial8.htm
Modified:
   trunk/docs/tutorial/index.htm
   trunk/docs/tutorial/tutorial1.htm
   trunk/docs/tutorial/tutorial3.htm
   trunk/docs/tutorial/tutorial7.htm
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/pr/test/test.pr
   trunk/pr/tutorial/tut3.pr
   trunk/src/argproc.c
   trunk/src/builtins-string.c
   trunk/src/builtins-thread.c
   trunk/src/console.c
   trunk/src/interp.c
   trunk/src/interp.h
   trunk/src/main.c
   trunk/src/memory_mgr.c
   trunk/src/object.c
   trunk/src/object.h
   trunk/src/src.vcproj
   trunk/src/symbol.c
   trunk/src/sys.c
   trunk/src/thread.h
Log:
added methods, binding, and started objects section, 
fixed bug in console for accesing built-in objects,
added -s cmd-line option, tutorial section 1.3 example works now, changed proto of str to seq, fixed str.upper and lower, 

Modified: trunk/docs/tutorial/index.htm
===================================================================
--- trunk/docs/tutorial/index.htm	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/docs/tutorial/index.htm	2004-05-17 01:23:10 UTC (rev 492)
@@ -24,9 +24,9 @@
     <tr> 
       <td width="114" height="25" valign="top">&nbsp;<a href="http://prothon.org">Prothon 
         Home</a></td>
-      <td width="194" valign="middle" align="center" height="25">Previous Page</td>
-      <td width="183" valign="middle" align="center" height="25">Tutorial Outline</td>
-      <td width="139" valign="middle" align="center" height="25"><a href="tutorial1.htm">Next 
+      <td width="194" valign="middle" align="center" height="25">&nbsp;</td>
+      <td width="183" valign="middle" align="center" height="25">&nbsp;</td>
+      <td width="139" valign="middle" align="center" height="25"><a href="index2.htm">Next 
         Page</a></td>
     </tr>
   </table>
@@ -184,8 +184,20 @@
                   <li><a href="tutorial6.htm#passref">Pass By Reference</a> 
                   <li><a href="tutorial6.htm#noneobj">None Object</a> 
                   <li><a href="tutorial6.htm#rtrnstmt">Return Statement</a> 
+                  </ul>
+				  
+              <li><a href="tutorial7.htm#self">5.4 Self, Methods &amp; Binding</a> 
+                <ul>
+                  <li><a href="tutorial7.htm#selfscope">Self Scope Object</a> 
+                  <li><a href="tutorial7.htm#selfkeyword">Self Keyword</a> 
+                  <li><a href="tutorial7.htm#selfcall">Default Self</a> 
+                  <li><a href="tutorial7.htm#selfexpl">Explicit Self</a> 
+                  <li><a href="tutorial7.htm#methods">Methods</a> 
+                  <li><a href="tutorial7.htm#binding">Binding</a> 
+                  <li><a href="tutorial7.htm#boundmethod">Bound Methods</a>
                 </ul>
-              <li><a href="tutorial7.htm#expr">5.4 Expressions</a>
+               
+              <li><a href="tutorial7.htm#expr">5.5 Expressions</a> 
                 <ul>
                   <li><a href="tutorial7.htm#exprfunc">Operators = Functions</a> 
                   <li><a href="tutorial7.htm#numfunc">Numeric Functions</a> 
@@ -195,9 +207,10 @@
                   <li><a href="tutorial7.htm#samplexpr">Sample Expressions</a> 
                   <li><a href="tutorial7.htm#opchain">Chained Comparisons</a> 
                   <li><a href="tutorial7.htm#shortckt">Short-Circuit Expr Eval</a> 
-                  <li><a href="tutorial7.htm#andorres">And-Or Result Objects</a>
+                  <li><a href="tutorial7.htm#andorres">And-Or Result Objects</a> 
                 </ul>
-        </ul></ul>
+            </ul>
+        </ul>
       </td>
     </tr>
   </table>
@@ -206,9 +219,9 @@
     <tr> 
       <td width="114" height="25" valign="top">&nbsp;<a href="http://prothon.org">Prothon 
         Home</a></td>
-      <td width="194" valign="middle" align="center" height="25">Previous Page</td>
-      <td width="183" valign="middle" align="center" height="25">Tutorial Outline</td>
-      <td width="139" valign="middle" align="center" height="25"><a href="tutorial1.htm">Next 
+      <td width="194" valign="middle" align="center" height="25">&nbsp;</td>
+      <td width="183" valign="middle" align="center" height="25">&nbsp;</td>
+      <td width="139" valign="middle" align="center" height="25"><a href="index2.htm">Next 
         Page</a></td>
     </tr>
   </table>
Added: trunk/docs/tutorial/index2.htm
===================================================================
--- trunk/docs/tutorial/index2.htm	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/docs/tutorial/index2.htm	2004-05-17 01:23:10 UTC (rev 492)
@@ -0,0 +1,69 @@
+<html>
+<head>
+<title>Prothon Tutorial - Outline - Page 2</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000">
+<div align="center">
+  <table width="630" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFCC">
+    <tr>
+      <td height="121" width="109"><img src="../images/logo_left.jpg" width="109" height="135"></td>
+      <td valign="center" height="43"> 
+        <div align="center">
+          <p><font size="5" face="Verdana, Arial, Helvetica, sans-serif">Prothon 
+            Tutorial</font></p>
+          <p><font face="Times New Roman, Times, serif" size="5">Outline - Page 
+            2 </font></p>
+        </div>
+      </td>
+      <td valign="center" height="121" width="106"><img src="../images/logo_right.jpg" width="109" height="135"></td>
+    </tr>
+  </table>
+  <br>
+  <table width="630" border="0" cellpadding="0" cellspacing="0">
+    <tr> 
+      <td width="114" height="25" valign="top">&nbsp;<a href="http://prothon.org">Prothon 
+        Home</a></td>
+      <td width="194" valign="middle" align="center" height="25"><a href="index.htm">Previous 
+        Page</a></td>
+      <td width="183" valign="middle" align="center" height="25"><a href="index.htm">Tutorial 
+        Outline</a></td>
+      <td width="139" valign="middle" align="center" height="25"><a href="tutorial1.htm">Next 
+        Page</a></td>
+    </tr>
+  </table>
+  <br>
+  <table width="630" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffee" height="1707">
+    <tr> 
+      <td height="2203" valign="top"> 
+        <ul>
+          <li>6. <a href="tutorial8.htm#myoo">Making Your Own Objects</a> 
+            <ul>
+              <li><a href="tutorial8.htm#oaok">6.1 Object() &amp; Object Keyword</a> 
+                <ul>
+                  <li><a href="tutorial8.htm#oeof">obj = Object()</a>
+                </ul>
+              
+            </ul>
+        </ul>
+      </td>
+    </tr>
+  </table>
+
+  <table width="630" border="0" cellpadding="0" cellspacing="0">
+    <tr> 
+      <td width="114" height="25" valign="top">&nbsp;<a href="http://prothon.org">Prothon 
+        Home</a></td>
+      <td width="194" valign="middle" align="center" height="25"><a href="index.htm">Previous 
+        Page</a></td>
+      <td width="183" valign="middle" align="center" height="25"><a href="index.htm">Tutorial 
+        Outline</a></td>
+      <td width="139" valign="middle" align="center" height="25"><a href="tutorial1.htm">Next 
+        Page</a></td>
+    </tr>
+  </table>
+  </div>
+</body>
+
+</html>
Modified: trunk/docs/tutorial/tutorial1.htm
===================================================================
--- trunk/docs/tutorial/tutorial1.htm	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/docs/tutorial/tutorial1.htm	2004-05-17 01:23:10 UTC (rev 492)
@@ -139,20 +139,30 @@
 >>> print Argv[0]
 tut2.pr</pre>
         <p><a name="toption"></a>There is even a way to run the console at the 
-          same time your file is executing. Here is the source code for a simple 
-          prothon program, tut3.pr, that adds 1 to a global variable called timer 
-          every second:</p>
-        <pre>for i in 1_000_000:
-    timer = i
-    Sleep(1.0)
-</pre>
+          same time your file is executing. Here is a simple prothon program that 
+          adds 1 to a global variable called Object.timer every second:</p>
+        <pre># Prothon source file tut3.pr
+
+for i in 1_000_000:
+    Object.timer = i
+    Sleep(1.0)</pre>
         If you run this as a background program then you can examine the timer 
-        variable in the console at the same time. The -t command line option starts 
-        a prothon file executing as a background thread: 
-        <pre>C:\Prothon\pr\tutorial>prothon -t tut3.pr XXX
-</pre>
-        <p>You can actually start many files executing with the -t option and 
-          the console all at once, but we won't show that right now.</p>
+        variable in the console at the same time. The -s command line option starts 
+        a prothon file executing as a background thread. Hint: to repeat a command 
+        in the console, use the up arrow: 
+        <pre>C:\Prothon\pr\tutorial>prothon -s tut3.pr -i
+
+Prothon 0.1 Interactive Console, Build 477, May 16 2004 (Ctrl-D to exit)
+>>> print Object.timer
+6
+>>> print Object.timer
+7
+>>> print Object.timer
+9
+>>></pre>
+        <p>You can actually start many files executing with the -s option and 
+          the console all at once, but we won't show that here.</p>
+        <p>&nbsp;</p>
       </td>
     </tr>
   </table>
Modified: trunk/docs/tutorial/tutorial3.htm
===================================================================
--- trunk/docs/tutorial/tutorial3.htm	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/docs/tutorial/tutorial3.htm	2004-05-17 01:23:10 UTC (rev 492)
@@ -183,8 +183,8 @@
           number to access the chars in reverse:</p>
         <pre>>>> x = "abcdefghijklm"
 abcdefghijklm
->>> print x[2], x[1:3], x[0:10:2], x[12:-1:-1]
-XXX</pre>
+>>> print x[2], x[1:3], x[0:10:2], x[12:6:-1]
+c bc acegi mlkjih</pre>
         <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="negnum"></a></font>If 
           you use a negative number for an index, it is treated as an offset from 
           the end of the string. The number -1 will index the last character in 
@@ -200,26 +200,29 @@
           from the first:</p>
         <pre>>>> x = "abcdef"
 abcdef
->>> print x[-2], x[-3:-1], x[3:], x[:2], x[:2:-1], x[-1:-1:-1], x[:]
-XXX</pre>
+>>> print x[-2], x[-3:-1], x[3:], x[:2], x[:2:-1], x[::-1], x[:]
+e de def ab fed fedcba abcdef</pre>
         <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="strfunc"></a></font>There 
           are many useful string functions, but we will point out just a few here:</p>
         <pre>>>>Len("abc")             # number of chars in string
-XXX
+3
 >>>"abc".upper()          # convert string to uppercase
 XXX
 >>>"ABC".lower()          # converts string to lowercase
 XXX
 >>>"abc def".capitalize() # capitalize string
-XXX
+Abc def
 >>>"abc def".capWords()   # capitalize words in string
-XXX
+Abc Def
 >>>'<'+" x ".lStrip()+'>' # remove white space from left
-XXX
+&lt;x &gt;
 >>>'<'+" x ".rStrip()+'>' # remove white space from right
-XXX
+&lt; x&gt;
 >>>'<'+" x ".strip()+'>'  # remove white space from sides
-XXX</pre>
+&lt;x&gt;
+
+</pre>
+
       </td>
     </tr>
   </table>
Modified: trunk/docs/tutorial/tutorial7.htm
===================================================================
--- trunk/docs/tutorial/tutorial7.htm	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/docs/tutorial/tutorial7.htm	2004-05-17 01:23:10 UTC (rev 492)
@@ -25,15 +25,123 @@
         Page</a></td>
       <td width="183" valign="middle" align="center" height="25"><a href="index.htm">Tutorial 
         Outline</a></td>
-      <td width="139" valign="middle" align="center" height="25"><a href="index.htm">Next 
+      <td width="139" valign="middle" align="center" height="25"><a href="tutorial8.htm">Next 
         Page</a></td>
     </tr>
   </table>
   <br>
   <table width="630" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffee" height="1707">
     <tr> 
-      <td height="3515" valign="top"> 
-        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="expr"></a>5.4 
+      <td height="3212" valign="top"> 
+        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="self"></a>5.4 
+          Self, Methods, &amp; Binding</font></p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="selfscope"></a></font>Just 
+          as every function has a hidden &quot;local&quot; scope object whose 
+          attributes are the local variables of the function, every function has 
+          another hidden scope object called &quot;self&quot;. You have seen &quot;self&quot; 
+          in action without knowing it. When a function is &quot;called on an 
+          object&quot; such as when a sort function is called on a list in &quot;list.sort!()&quot;, 
+          the list is the &quot;self&quot; scope object inside the &quot;sort!&quot; 
+          function when it is executing. </p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="selfkeyword"></a></font>The 
+          local variables default to the &quot;local&quot; scope object whenever 
+          you use any normal variable name like &quot;x&quot;, but to access the 
+          &quot;self&quot; variables you must use the prefix keyword &quot;self&quot; 
+          as in &quot;self.x&quot;. You may also access the &quot;self&quot; object 
+          itself just by saying &quot;self&quot;. </p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="selfcall"></a></font>There 
+          are a number of ways to specify the &quot;self&quot; scope object for 
+          a function call and we will wait until later to cover some of them. 
+          As you saw in the &quot;list.sort!()&quot; example, calling a function 
+          on an object will set the self scope object by default. The simplest 
+          way to call a function on an object is to make the function an attribute 
+          of the object. You can do this in the &quot;def&quot; statement itself 
+          or by assignment:</p>
+        <pre>>>> x = ['Hello', 'World']
+['Hello', 'World']
+>>> def x.func():
+...    print self[0]
+...
+>>> x.func()
+Hello
+>>> def func2():
+...    print self[1]
+...
+>>> x.y = func2
+&lt;func:93e220&gt;
+>>> x.y()
+World
+>>></pre>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="selfexpl"></a></font>You 
+          can also specify the &quot;self&quot; scope object explicitly in the 
+          function call by using the form &quot;func{selfObj}(args)&quot;. This 
+          will call the function &quot;func&quot; with the actual parameters &quot;args&quot; 
+          and set the &quot;self&quot; scope object to &quot;selfObj&quot;. You 
+          might be tempted to think this is like one more actual parameter being 
+          passed to the function but it is not. Parameters are assigned into local 
+          variables that are attributes of the &quot;local&quot; scope object, 
+          but the &quot;self&quot; is a scope object of its own.</p>
+        <pre>>>> def func(index):
+...    if (index == -1):
+...       index = self.defIndex
+...    print self[index]
+...
+>>> x = ['Hello', 'World']
+['Hello', 'World']
+>>> x.defIndex = 0
+0
+>>> func{x}(0)
+Hello
+>>> func{x}(1)
+World
+>>> func{x}(-1)
+Hello
+>>></pre>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="methods"></a></font>In 
+          object-oriented languages that have classes, there are things called 
+          &quot;methods&quot;. A method is a function attached to a class. Since 
+          Prothon doesn't have classes, Prothon doesn't have any difference between 
+          a method and a function. For reasons that you will learn later, Prothon's 
+          functions that have references to &quot;self&quot; inside are similar 
+          to methods. So Prothon has a terminology convention of calling any function 
+          that has the keyword &quot;self&quot; inside a &quot;method&quot;. Don't 
+          forget that there is no difference between how a Prothon method and 
+          a Prothon function works, it it just two words for the same thing. Also, 
+          don't forget that all Prothon functions have the &quot;self&quot; scope 
+          object, not just Prothon methods. It is just that only Prothon methods 
+          use that &quot;self&quot; scope object.</p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="binding"></a></font>There 
+          are times when it is convenient to have a function object (method) with 
+          a "self" object permanently attached for future use. This attaching 
+          of the &quot;self&quot; object is called &quot;binding&quot; and the 
+          combined object is called a &quot;bound method&quot;. One usage example 
+          of a bound method is a &quot;callback&quot; method. This is where you 
+          send a bound method as an argument in a call to a remote function and 
+          when some event occurs, that remote function invokes that callback method 
+          as a signal.</p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="boundmethod"></a></font>To 
+          make a bound method use this form &quot;boundMethod = method{selfObj}&quot;. 
+          Note that this is exactly like the call without the parentheses. The 
+          &quot;method&quot; will be bound to &quot;selfObj&quot; to become the 
+          &quot;boundMethod&quot;. Now &quot;boundMethod&quot; can be called like 
+          a normal function (method) and it will use the &quot;selfObj&quot; that 
+          is bound inside. Note that specifying a different &quot;self&quot; as 
+          in &quot;boundMethod{anotherSelf}()&quot; will cause an exception.</p>
+        <pre>>>> x = ['Hello', 'World']
+['Hello', 'World']
+>>> def func(index):
+...    print self[index]
+...
+>>> boundMethod = func{x}
+&lt;func:939f00:bound:['Hello', 'World']&gt;
+>>> boundMethod(0)
+Hello
+>>> a = boundMethod
+&lt;func:939f00:bound:['Hello', 'World']&gt;
+>>> a(1)
+World
+>>></pre>
+        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="expr"></a>5.5 
           Expressions</font></p>
         <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="exprfunc"></a></font>We 
           have been using expressions all along, such as when we say 1+2, but 
@@ -44,12 +152,11 @@
           the parser) quickly changes the simple expression &quot;x = 1+2&quot; 
           into the Prothon statement &quot;x = 1.add_(2)&quot; by replacing the 
           addition operator + into &quot;.add_()&quot;.</p>
-        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="numfunc"></a></font>And 
-          numbers (which are objects also of course) can have functions called 
-          on them:</p>
-        <pre>>>> 48.chr()   # chr() changes integer 48 into string &quot;0&quot;
-0
->>> 1.add_(2)  # same as 1 + 2
+        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="numfunc"></a></font>Numbers 
+          (which are objects of course) can have functions (methods) called on 
+          them. Note that in these binary operators the left side of the operator 
+          is always the &quot;self&quot; object and the right side is a parameter:</p>
+        <pre>>>> 1.add_(2)  # same as 1 + 2
 3
 >>></pre>
         <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="numdp"></a></font>We 
@@ -146,7 +253,7 @@
         Page</a></td>
       <td width="183" valign="middle" align="center" height="25"><a href="index.htm">Tutorial 
         Outline</a></td>
-      <td width="139" valign="middle" align="center" height="25"><a href="index.htm">Next 
+      <td width="139" valign="middle" align="center" height="25"><a href="tutorial8.htm">Next 
         Page</a></td>
     </tr>
   </table>
Added: trunk/docs/tutorial/tutorial8.htm
===================================================================
--- trunk/docs/tutorial/tutorial8.htm	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/docs/tutorial/tutorial8.htm	2004-05-17 01:23:10 UTC (rev 492)
@@ -0,0 +1,65 @@
+<html>
+<head>
+<title>Prothon Tutorial - 6.0</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000">
+<div align="center">
+  <table width="630" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFCC">
+    <tr>
+      <td height="121" width="109"><img src="../images/logo_left.jpg" width="109" height="135"></td>
+      <td valign="center" height="43"> 
+        <div align="center"><font size="5" face="Verdana, Arial, Helvetica, sans-serif">Prothon 
+          Tutorial</font></div>
+      </td>
+      <td valign="center" height="121" width="106"><img src="../images/logo_right.jpg" width="109" height="135"></td>
+    </tr>
+  </table>
+  <br>
+  <table width="630" border="0" cellpadding="0" cellspacing="0">
+    <tr> 
+      <td width="114" height="25" valign="top">&nbsp;<a href="http://prothon.org">Prothon 
+        Home</a></td>
+      <td width="194" valign="middle" align="center" height="25"><a href="tutorial7.htm">Previous 
+        Page</a></td>
+      <td width="183" valign="middle" align="center" height="25"><a href="index.htm">Tutorial 
+        Outline</a></td>
+      <td width="139" valign="middle" align="center" height="25"><a href="index.htm">Next 
+        Page</a></td>
+    </tr>
+  </table>
+  <br>
+  <table width="630" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffee" height="1707">
+    <tr> 
+      <td height="3212" valign="top"> 
+        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="myoo"></a>6.0 
+          Making Your Own Objects</font></p>
+        <p align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="oaok"></a>6.1 
+          Object() and Object Keyword</font></p>
+        <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="oeof"></a></font>So 
+          far you have created many objects using special creation methods built 
+          into the Prothon language such as integer and string and list constants. 
+          It's time to learn how to build objects from scratch. The most fundamental 
+          way to build an object is to use the for &quot;obj = Object()&quot;. 
+          This creates an &quot;empty&quot; object. It has no binary data and 
+          no attributes. </p>
+        <p>&nbsp;</p>
+        </td>
+    </tr>
+  </table>
+  <table width="630" border="0" cellpadding="0" cellspacing="0">
+    <tr> 
+      <td width="114" height="25" valign="top">&nbsp;<a href="http://prothon.org">Prothon 
+        Home</a></td>
+      <td width="194" valign="middle" align="center" height="25"><a href="tutorial7.htm">Previous 
+        Page</a></td>
+      <td width="183" valign="middle" align="center" height="25"><a href="index.htm">Tutorial 
+        Outline</a></td>
+      <td width="139" valign="middle" align="center" height="25"><a href="index.htm">Next 
+        Page</a></td>
+    </tr>
+  </table>
+</div>
+</body>
+</html>
Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/include/prothon/prothon.h	2004-05-17 01:23:10 UTC (rev 492)
@@ -231,7 +231,6 @@
 typedef struct user_thread_s {
 	obj_p func;
 	obj_p params;
-	int   access;
 } user_thread_t;
 
 typedef user_thread_t* user_thread_p;
@@ -239,10 +238,10 @@
 typedef struct {
 	apr_os_thread_t		apr_os_thread;
 	apr_thread_t*		apr_thread;
+	isp					ist;
 	int					main_id;
 	user_thread_t		user_thread_data;
 	int					running;
-	isp					ist;
 	frame_p				frame;
 	int					save_frame;
 } pr_thread_t;
@@ -423,6 +422,7 @@
 	CALL_,
 	BINDOBJ_,
 	PREV_SCOPE_,
+	ACCLEVEL_,
 
 	SYM_ENUM_COUNT
 } sym_enum_t;
@@ -799,7 +799,9 @@
 // Note: thread_func must call register_thread() (see below) immediately after
 // starting.
 // You may provide a blank thread_obj as an input parameter if you wish.
-obj_p new_thread_obj(isp ist, apr_thread_start_t thread_func, void *thread_data, obj_p thread_obj);
+// You must provide a thread obj or an acc level.
+obj_p new_thread_obj( isp ist, apr_thread_start_t thread_func, 
+					  void *thread_data, obj_p thread_obj, int acc_level );
 
 // REGISTER_THREAD: Register a newly started thread
 // This tells Prothon that a thread has actually started, releasees the
@@ -809,7 +811,7 @@
 // the thread_func function (see APR docs).
 // Example thread_func: void *main_thread(apr_thread_t *handle, void *argv);
 // The handle parameter is used for this_thread:  register_thread(handle);
-obj_p register_thread(isp ist, apr_thread_t *this_thread);
+obj_p register_thread(apr_thread_t *this_thread);
 
 //****************** HIGHER LEVEL OBJECT ACCESS ROUTINES ************************
 

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/include/prothon/prothon_dll.h	2004-05-17 01:23:10 UTC (rev 492)
@@ -66,7 +66,7 @@
 	void		(*raise_exception)(isp ist, obj_p proto_obj, const char *format, ...)
 		                            __attribute__((format(printf,3,4)));
 	apr_pool_t* (*get_pr_head_pool)(void);
-	isp			(*get_ist)(access_t access);
+	isp			(*new_ist)(access_t access);
 	obj_p		(*get_attr)(isp ist, obj_p obj, obj_p key);
 	void		(*set_attr)(isp ist, obj_p object, obj_p key, obj_p value);
 	int			(*del_attr)(isp ist, obj_p obj, obj_p key);
@@ -214,7 +214,7 @@
 PR_DECLARE_EXPORT void name##_dll_entry(pr_services_t* srvcs)	\
 {																\
 	services = srvcs;											\
-	ist = get_ist(ACC_SYSTEM);									\
+	ist = new_ist(ACC_SYSTEM);									\
 	name##_module_install();									\
 }																\
 static void name##_module_install(void)
@@ -264,7 +264,7 @@
 
 #ifndef OBJECT_H
 
-#define get_ist				(*services->get_ist)
+#define new_ist				(*services->new_ist)
 #define get_attr			(*services->get_attr)
 #define set_attr			(*services->set_attr)
 #define del_attr			(*services->del_attr)

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/pr/test/test.pr	2004-05-17 01:23:10 UTC (rev 492)
@@ -1,4 +1,35 @@
-#!/usr/bin/env prothon
 
-for i in 10:
-	print i
+def err(n):
+	print 'test',n,'failed'
+	Sys.exit(1)
+
+x = "abcdefghijklm"
+
+if "c:bc:acegi:mlkjih" !=  x[2]+':'+x[1:3]+':'+x[0:10:2]+':'+x[12:6:-1]:
+	err(1)
+
+x = "abcdef"
+
+if "e:de:def:ab:fed:fedcba:abcdef" !=  x[-2]+':'+x[-3:-1]+':'+x[3:]+':'+x[:2]+':'+x[:2:-1]+':'+x[::-1]+':'+x[:]:
+	err(2)
+
+if 3 !=  Len("abc"):  err(3)
+
+print "abc".upper()
+
+print "ABC".lower()
+
+if "Abc def" !=  "abc def".capitalize(): err(6)
+
+if "Abc Def" !=  "abc def".capWords(): err(7)
+
+if "<x >" != '<'+" x ".lStrip()+'>': err(8)
+
+if "< x>" !=  '<'+" x ".rStrip()+'>': err(9)
+
+if "<x>" !=  '<'+" x ".strip()+'>': err(10)
+
+print '\nall tests passed\n'
+
+
+

Modified: trunk/pr/tutorial/tut3.pr
===================================================================
--- trunk/pr/tutorial/tut3.pr	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/pr/tutorial/tut3.pr	2004-05-17 01:23:10 UTC (rev 492)
@@ -1,4 +1,6 @@
 
+# Prothon source file tut3.pr
+
 for i in 1_000_000:
-    timer = i
+    Object.timer = i
     Sleep(1.0)
Modified: trunk/src/argproc.c
===================================================================
--- trunk/src/argproc.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/argproc.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -125,7 +125,14 @@
 				if (++i == argc) goto err;
 				if (!(thread_argv = parse_argv(ist, argv[i]))) goto err;
 				list_append(ist, thread_list, thread_argv);
+				set_attr(ist, thread_argv, SYM(ACCLEVEL_), NEW_INT(ACC_USER2));
 				break;
+			case 's': 
+				if (++i == argc) goto err;
+				if (!(thread_argv = parse_argv(ist, argv[i]))) goto err;
+				list_append(ist, thread_list, thread_argv);
+				set_attr(ist, thread_argv, SYM(ACCLEVEL_), NEW_INT(ACC_SYSTEM));
+				break;
 			case 'i': 
 				set_attr(ist, res, sym(ist, "i"), OBJ(PR_TRUE));							
 				break;
@@ -166,8 +173,11 @@
 				printf("      surround the file name and parameters in quotes.  To nest quotes in the\n");
 				printf("      command use single quote characters.\n");
 				printf("\n");
+				printf("   -s --system filename\n");
+				printf("      Same as the -t (thread) option, except that the thread runs at system\n");
+				printf("      security level.  This should only be used for trusted code.\n");
+				printf("\n");
 				printf("   -i --interact\n");
-				printf("      (Not implemented yet)\n");
 				printf("      Enter interactive session after the main-thread code terminates, leaving\n");
 				printf("      variables from that code intact. Other threads may still be running\n");
 				printf("      that you may interact with.\n");

Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/builtins-string.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -139,40 +139,24 @@
 static obj_p changeCase(isp ist,obj_p self,int (*changer)(int), size_t howMany) {
 	size_t str_len = pr_strlen(self), ii = 0;
 	char *src_ptr, *dest_ptr = 0;
-	obj_p obj=0;
-	pr_str_p obj_str=0;
+	obj_p obj;
 	int atStart = 1;
 
-	obj = NEW_OBJ(String_OBJ);
-	obj_str = obj_malloc(ist, OBJ(STRING_PROTO), obj, sizeof(pr_str_t)+str_len+1);
-	if(!obj_str) {
-		raise_exception(ist, OBJ(OUTOFMEMORY_EXC),
-						"memory allocation failed for string.changeCase (used by lower(), upper(), etc.)");
-		return NULL;
-	}
-	obj_str->len = str_len;
-	dest_ptr = obj_str->str;
+	obj = copy_object(ist, self);
+	dest_ptr  = pr_strptr(obj);
 
-	// Fill the copy.
+	// Change the copy.
 	src_ptr = pr_strptr(self);
 	for (ii=0; ii<str_len; ++ii) {
 		if (howMany == AT_WORD_START) {
-			if (atStart) {
+			if (atStart)
 				dest_ptr[ii] = (char)(*changer)(src_ptr[ii]);
-			} else {
-				dest_ptr[ii] = src_ptr[ii];
-			}
 			if (isspace(src_ptr[ii])) atStart = 1; else atStart = 0;
 		} else {
-			if (ii<howMany) {
+			if (ii<howMany)
 				dest_ptr[ii] = (char)(*changer)(src_ptr[ii]);
-			} else {
-				dest_ptr[ii] = src_ptr[ii];
-			}
 		}
 	}
-	dest_ptr[str_len] = 0;
-
 	return obj;
 }
 

Modified: trunk/src/builtins-thread.c
===================================================================
--- trunk/src/builtins-thread.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/builtins-thread.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -92,11 +92,10 @@
 /* New threads must call this first thing, it will release the
  * thread_registry_lock so that other threads can start. 
  * Returns the matching thread object */
-obj_p register_thread(isp ist, apr_thread_t *this_thread)
+obj_p register_thread(apr_thread_t *this_thread)
 {
 	obj_p res = new_thread_object;
 	pr_thread_p thread_ptr    = res->data.ptr;
-	thread_ptr->ist           = ist;
 	thread_ptr->apr_os_thread = apr_os_thread_current();
 	thread_ptr->apr_thread    = this_thread;
 	clist_append(thread_registry, res);
@@ -110,9 +109,10 @@
 
 //********************************* new_thread_obj ****************************
 obj_p new_thread_obj( isp ist, apr_thread_start_t thread_func, 
-					  void *thread_data, obj_p thread_obj ) {
+					  void *thread_data, obj_p thread_obj, int acc_level ) {
 	apr_status_t aprerr;
 	apr_thread_t *new_thread = NULL;
+	pr_thread_p thread_p;
 
 	if (!thread_pool) {
 		aprerr = apr_pool_create(&thread_pool, get_pr_head_pool());
@@ -130,12 +130,15 @@
 	 * calls register_thread(). */
 	pr_lock(&thread_registry_lock);
 
-	if (!thread_obj) {
+	if (thread_obj)
+		thread_p = thread_obj->data.ptr;
+	else {
 		thread_obj = NEW_OBJ(OBJ(THREAD_PROTO));
 		SET_TYPE_IF_EXC(OBJ(THREAD_PROTO), thread_obj, DATA_TYPE_DATAPTR) return NULL;
-		thread_obj->data.ptr  = pr_malloc(sizeof(pr_thread_t));
+		thread_p = thread_obj->data.ptr = pr_malloc(sizeof(pr_thread_t));
 		memset(thread_obj->data.ptr, 0, sizeof(pr_thread_t));
 	}
+	thread_p->ist = new_ist(acc_level);
 
 	aprerr = apr_thread_create(&new_thread, thread_attr, thread_func, thread_data, thread_pool);
 	IF_APR_ERR("apr_thread_create") return NULL;
@@ -209,6 +212,7 @@
 	char buf[30];
 	obj_p name_obj;
 	user_thread_p uthread;
+	int access_level;
 
 	BIN_EMPTY_CHK();
 	CHECK_TYPE_EXC(parms[1], OBJ(FUNC_PROTO),   "function");
@@ -223,9 +227,9 @@
 	uthread = &(((pr_thread_p)self->data.ptr)->user_thread_data);
 	uthread->func   = parms[1]; 
 	uthread->params = parms[3]; 
-	uthread->access = (int) parms[7]->data.i64;
-	if (uthread->access == -1) uthread->access = ist->access;
-	if (ist->access < uthread->access) {
+	access_level = (int) parms[7]->data.i64;
+	if (access_level == -1) access_level = ist->access;
+	if (ist->access < access_level) {
 		raise_exception(ist, OBJ(PERMISSION_EXC), 
 			"attempt to start thread with higher access level than own");	
 		return NULL;
@@ -237,7 +241,7 @@
 		name_obj = parms[5];
 	read_unlock(ist, self);
 	set_attr(ist, self, sym(ist, "name"), name_obj);
-	new_thread_obj(ist, (apr_thread_start_t) user_thread, uthread, self);
+	new_thread_obj(ist, (apr_thread_start_t) user_thread, uthread, self, access_level);
 	read_lock(ist, self);
 	self->unclonable = TRUE;
 	return OBJ(NONE);

Modified: trunk/src/console.c
===================================================================
--- trunk/src/console.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/console.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -189,7 +189,7 @@
 	new_self = new_object(ist, NULL);
 	if (!ist->frame) {
 		new_locals  = NEW_OBJ(NULL);
-		frame = create_frame(ist, new_self, new_locals, new_locals, new_locals, NULL, NULL);
+		frame = create_frame(ist, new_self, NULL, NULL, new_locals, NULL, NULL);
 	}
 
 	if ((home = getenv("HOME")) != NULL)

Modified: trunk/src/interp.c
===================================================================
--- trunk/src/interp.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/interp.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -74,7 +74,7 @@
 
 static int prt_code_line(frame_p frame, code_p code, int pc, FILE* fout);
 
-isp get_ist(access_t access) {
+isp new_ist(access_t access) {
 	isp ist = pr_malloc(sizeof(interp_state_t));
 	ist->frame = NULL;
 	ist->exception_obj = 0;
@@ -1693,7 +1693,7 @@
 
 //******************************** main_thread ***********************************
 void *main_thread(apr_thread_t *handle, void *argv){
-	isp ist = get_ist(ACC_USER2);
+	isp ist = new_ist(ACC_USER2);
 	int i, main_index=1;
 	obj_p main_sym, module, thread_obj;
 	pr_thread_p thread_p;
@@ -1703,8 +1703,9 @@
 	printf("Starting a main thread\n");
 #endif
 
-	thread_obj = register_thread(ist, handle);
+	thread_obj = register_thread(handle);
 	thread_p = thread_obj->data.ptr;
+	ist = thread_p->ist;
 
 	pr_lock(&start_main_lock);
 	
@@ -1736,7 +1737,6 @@
 	SetThreadName(symch(ist, main_sym));
 #endif
 
-	ist = get_ist(ACC_USER2);
 	set_attr(ist, module, sym(ist, "Argv"), (obj_p) argv);
 	if (!load_module(ist, main_sym, NULL, NULL, NULL, filename, 
 									":a top-level module", module, NULL)) {
@@ -1762,14 +1762,15 @@
 #define MAX_NUM_PARAMS	64
 void* user_thread(apr_thread_t *handle, void *argv) {
 	user_thread_p uthread = (user_thread_p) argv;
-	isp ist = get_ist(uthread->access);
 	obj_p thread_module, func_obj = uthread->func;
 	frame_p new_frame;
 	obj_p new_locals, lbl_val_arr[MAX_NUM_PARAMS]; 
-	int i, parm_cnt = (int) list_len(ist, uthread->params) * 2;
-	obj_p thread_obj = register_thread(ist, handle);
+	int i, parm_cnt;
+	obj_p thread_obj = register_thread(handle);
 	pr_thread_p thread_p = thread_obj->data.ptr;
+	isp ist = thread_p->ist;
 
+	parm_cnt = (int) list_len(ist, uthread->params) * 2;
 	if (parm_cnt > MAX_NUM_PARAMS) {
 		printf("User thread error: too many user thread parameters");
 		thread_p->running = FALSE;

Modified: trunk/src/interp.h
===================================================================
--- trunk/src/interp.h	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/interp.h	2004-05-17 01:23:10 UTC (rev 492)
@@ -61,7 +61,7 @@
 
 #include <apr_thread_proc.h>
 
-isp get_ist(access_t access);
+isp new_ist(access_t access);
 
 extern i32_t main_threads_started;
 extern i32_t main_threads_running;

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/main.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -111,7 +111,7 @@
 	}
 
 	/* Now that apr is ready, on to our stuff */
-	ist = get_ist(ACC_SYSTEM);
+	ist = new_ist(ACC_SYSTEM);
 
 
 #ifdef TRACE_PARSER
@@ -133,7 +133,7 @@
 
 	main_argv_obj = get_attr(ist, sys_argv_obj, sym(ist, "argv"));
 	if (main_argv_obj && list_len(ist, main_argv_obj)) {
-		main1_thread_obj = new_thread_obj(ist, (apr_thread_start_t)main_thread, main_argv_obj, NULL);
+		main1_thread_obj = new_thread_obj(ist, (apr_thread_start_t)main_thread, main_argv_obj, NULL, ACC_USER2);
 		main1_thread_ptr = main1_thread_obj->data.ptr;
 		if (cmd_line_option_i_flg) 
 			main1_thread_ptr->save_frame = TRUE;
@@ -142,11 +142,15 @@
 	threads = get_attr(ist, sys_argv_obj, sym(ist, "threads"));
 	if (threads) {
 		int i;
-		for (i = 0; i < (int) list_len(ist, threads); i++)
-			new_thread_obj(ist, (apr_thread_start_t)main_thread, list_item(ist, threads, i), NULL);
+		for (i = 0; i < (int) list_len(ist, threads); i++) {
+			obj_p thrd_argv = list_item(ist, threads, i);
+			obj_p acc_level = get_attr(ist, thrd_argv, SYM(ACCLEVEL_));  if_exc_return 0;
+			new_thread_obj( ist, (apr_thread_start_t) main_thread, thrd_argv, 
+				            NULL, (int) acc_level->data.i64 );
+		}
 	}
 
-	new_thread_obj(ist, (apr_thread_start_t)mem_mgr_thread, NULL, NULL);
+	new_thread_obj(ist, (apr_thread_start_t)mem_mgr_thread, NULL, NULL, ACC_SYSTEM);
 
 #ifdef DEBUG_THREADS
 	SetThreadName("main");

Modified: trunk/src/memory_mgr.c
===================================================================
--- trunk/src/memory_mgr.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/memory_mgr.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -107,13 +107,14 @@
 
 //********************************* mem_mgr_thread ******************************
 void *mem_mgr_thread(apr_thread_t *handle, void *dummy) {
-	isp ist = get_ist(ACC_SYSTEM);
+	obj_p thread_obj = register_thread(handle);
+	pr_thread_p thread_p = thread_obj->data.ptr;
+	isp ist = thread_p->ist;
+
 	obj_p mm_obj_list = NEW_LIST(100);
 	obj_p mm_obj_act_param[] = {NULL, mm_obj_list}; 
 	int last_obj_del_count = 0, last_obj_count = 0;     
 
-	register_thread(ist, handle);
-
 #ifdef DEBUG_THREADS
 	printf("Memory manager thread started\n");
 	SetThreadName("mmgr");

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/object.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -123,7 +123,7 @@
 	}
 
 	/* Setup the services struct */
-	dll_services.get_ist		  = get_ist;		
+	dll_services.new_ist		  = new_ist;		
 	dll_services.get_attr		  = get_attr;		
 	dll_services.set_attr		  = set_attr;		
 	dll_services.del_attr		  = del_attr;		
@@ -224,7 +224,7 @@
 	OBJ(EXCEPTION)          = NEW_OBJ(NULL);
 	OBJ(GEN_PROTO)          = NEW_OBJ(NULL);
 	OBJ(INT_PROTO)          = NEW_OBJ(NULL);
-	OBJ(STRING_PROTO)       = NEW_OBJ(NULL);
+	OBJ(STRING_PROTO)       = NEW_OBJ(OBJ(SEQ_PROTO));
 	OBJ(DICT_PROTO)         = NEW_OBJ(NULL);
 	OBJ(FUNC_PROTO)         = NEW_OBJ(NULL);
 	OBJ(METHOD_PROTO)       = NEW_OBJ(OBJ(FUNC_PROTO));

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/object.h	2004-05-17 01:23:10 UTC (rev 492)
@@ -144,7 +144,7 @@
 obj_p arginit(isp its, int argc, char* argv[]);
 void sysinit(isp ist, char* prog_path, obj_p argv_obj);
 
-isp get_ist(access_t access);
+isp new_ist(access_t access);
 
 obj_p load_sys_module(isp ist, char* prog_path, obj_p argv_obj);
 #define get_sys_path_list()  \

Modified: trunk/src/src.vcproj
===================================================================
--- trunk/src/src.vcproj	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/src.vcproj	2004-05-17 01:23:10 UTC (rev 492)
@@ -256,7 +256,7 @@
 				RelativePath="..\status.txt">
 			</File>
 			<File
-				RelativePath="..\pr\test.pr">
+				RelativePath="..\pr\test\test.pr">
 			</File>
 		</Filter>
 	</Files>
Modified: trunk/src/symbol.c
===================================================================
--- trunk/src/symbol.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/symbol.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -151,7 +151,8 @@
 	{ "fromStorProxy_", 0},
 	{ "call_",          0},
 	{ "bindObj_",		0},
-	{ "prev_scope_",    0}
+	{ "prev_scope_",    0},
+	{ "accLevel_",      0}
 };
 
 typedef struct trie_node_s* trie_p;

Modified: trunk/src/sys.c
===================================================================
--- trunk/src/sys.c	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/sys.c	2004-05-17 01:23:10 UTC (rev 492)
@@ -245,7 +245,7 @@
 				if (!(*p) || *p == '#') continue;
 				if (!strncmp(p, "import ", 7)) {
 					char doc[300];
-					isp ist = get_ist(ACC_USER2);
+					isp ist = new_ist(ACC_USER2);
 					apr_snprintf(modname, sizeof(modname), "PthMod%d", ++modname_cnt);
 					apr_snprintf(doc, sizeof(doc), ": a module loaded by %s",
 							file_info.name);

Modified: trunk/src/thread.h
===================================================================
--- trunk/src/thread.h	2004-05-16 17:59:02 UTC (rev 491)
+++ trunk/src/thread.h	2004-05-17 01:23:10 UTC (rev 492)
@@ -70,7 +70,7 @@
 #define thread_running(thread_obj)   (((pr_thread_p)((thread_obj)->data.ptr))->running)
 
 void thread_init(isp ist);
-obj_p register_thread(isp ist, apr_thread_t *this_thread);
+obj_p register_thread(apr_thread_t *this_thread);
 apr_thread_t* os_thread_2_apr(apr_os_thread_t os_thread);