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"> <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"> </td>
+ <td width="183" valign="middle" align="center" height="25"> </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 & 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"> <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"> </td>
+ <td width="183" valign="middle" align="center" height="25"> </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"> <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() & 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"> <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> </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
+<x >
>>>'<'+" x ".rStrip()+'>' # remove white space from right
-XXX
+< x>
>>>'<'+" x ".strip()+'>' # remove white space from sides
-XXX</pre>
+<x>
+
+</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, & 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 "local" scope object whose
+ attributes are the local variables of the function, every function has
+ another hidden scope object called "self". You have seen "self"
+ in action without knowing it. When a function is "called on an
+ object" such as when a sort function is called on a list in "list.sort!()",
+ the list is the "self" scope object inside the "sort!"
+ 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 "local" scope object whenever
+ you use any normal variable name like "x", but to access the
+ "self" variables you must use the prefix keyword "self"
+ as in "self.x". You may also access the "self" object
+ itself just by saying "self". </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 "self" scope object for
+ a function call and we will wait until later to cover some of them.
+ As you saw in the "list.sort!()" 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 "def" 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
+<func:93e220>
+>>> x.y()
+World
+>>></pre>
+ <p><font face="Verdana, Arial, Helvetica, sans-serif" size="+2"><a name="selfexpl"></a></font>You
+ can also specify the "self" scope object explicitly in the
+ function call by using the form "func{selfObj}(args)". This
+ will call the function "func" with the actual parameters "args"
+ and set the "self" scope object to "selfObj". 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 "local" scope object,
+ but the "self" 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
+ "methods". 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 "self" inside are similar
+ to methods. So Prothon has a terminology convention of calling any function
+ that has the keyword "self" inside a "method". 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 "self" scope
+ object, not just Prothon methods. It is just that only Prothon methods
+ use that "self" 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 "self" object is called "binding" and the
+ combined object is called a "bound method". One usage example
+ of a bound method is a "callback" 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 "boundMethod = method{selfObj}".
+ Note that this is exactly like the call without the parentheses. The
+ "method" will be bound to "selfObj" to become the
+ "boundMethod". Now "boundMethod" can be called like
+ a normal function (method) and it will use the "selfObj" that
+ is bound inside. Note that specifying a different "self" as
+ in "boundMethod{anotherSelf}()" will cause an exception.</p>
+ <pre>>>> x = ['Hello', 'World']
+['Hello', 'World']
+>>> def func(index):
+... print self[index]
+...
+>>> boundMethod = func{x}
+<func:939f00:bound:['Hello', 'World']>
+>>> boundMethod(0)
+Hello
+>>> a = boundMethod
+<func:939f00:bound:['Hello', 'World']>
+>>> 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 "x = 1+2"
into the Prothon statement "x = 1.add_(2)" by replacing the
addition operator + into ".add_()".</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 "0"
-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 "self" 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"> <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 "obj = Object()".
+ This creates an "empty" object. It has no binary data and
+ no attributes. </p>
+ <p> </p>
+ </td>
+ </tr>
+ </table>
+ <table width="630" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="114" height="25" valign="top"> <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);