Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > better way of executing expression/statement in C?

Reply
Thread Tools

better way of executing expression/statement in C?

 
 
David Faden
Guest
Posts: n/a
 
      05-20-2004
Hi,

Given arbitrary Python source code input by the user, I want to get the
result of executing that source as an expression if it is an expression
and otherwise execute the source as a statement. Currently, I'm
accomplishing this as follows (in a category on NSString), but it seems
kludgy to rely on detecting a syntax error.

- (PyObject*)executePythonSourceWithGlobalsPyObjec t*)globals
{
const char* source = [self UTF8String];
PyObject* result = PyRun_String(source, Py_eval_input, globals,
globals);
if (!result && PyErr_ExceptionMatches(PyExc_SyntaxError)) {
PyErr_Clear();
result = PyRun_String(source, Py_file_input, globals, globals);
}
return result;
}

How would you accomplish this? How does the interpreter do it?

Thank you.

David
AIM: pitulx


 
Reply With Quote
 
 
 
 
Rick L. Ratzel
Guest
Posts: n/a
 
      05-21-2004

This might be slightly less kludgy...I tested it by implementing a
crude input loop. Here is the output:

[rlratzel@triumph ~/exp] ./pyexec
>> a=3

RESULT: NULL
>> b=4

RESULT: NULL
>> a+b

RESULT: 7
>> c=4

RESULT: NULL
>> a+c

RESULT: 7
>> import os

RESULT: NULL
>> Done.


Here is the code:

file: pyexec.c
--------
#include <Python.h>
#define INLEN 1024

/*
* get string rep of a Python obj
*/
const char* getPyObjStringRepr( PyObject* pyObj ) {
if( pyObj == NULL ) {
return "NULL";
} else {
return PyString_AsString( PyObject_Str( pyObj ) );
}
}


/*
* print the results of evaluating Python expressions and statements
*/
int main( int argc, char** argv ) {

PyObject* mainModObj;
PyObject* mainDictObj;
PyObject* returnObj;
PyObject* resultObj;
char userInput[INLEN];

Py_Initialize();

/*
* create a different display hook to set a result var
* rather than print to stdout and set __builtin__._
*/
PyRun_SimpleString( "import sys, __main__" );
PyRun_SimpleString( "def my_displayhook(o): __main__.__result=o" );
PyRun_SimpleString( "sys.displayhook=my_displayhook" );

/*
* get the __main__ symbol table for evaluating within the top-most
* scope and retrieving the result
*/
mainModObj = PyImport_AddModule( "__main__" );
if( mainModObj == NULL ) {
return -1;
}
mainDictObj = PyModule_GetDict( mainModObj );

/*
* start an eval loop...only print 2 arrows since we are
* not really trying to be Python
*/
printf( ">> " );

/*
* start the loop
*/
while( fgets( userInput, INLEN, stdin ) != NULL ) {

/*
* run a string from the command line like the interactive interp
* does, handling both expressions and statements
*/
returnObj = PyRun_String( userInput, Py_single_input,
mainDictObj, mainDictObj );

if( returnObj == NULL ) {
PyErr_Print();
return -1;
}

/*
* get the result as set by the displayhook and print it out
*/
resultObj = PyDict_GetItemString( mainDictObj, "__result" );

printf( "RESULT: %s\n", getPyObjStringRepr( resultObj ) );

Py_DECREF( returnObj );
if( Py_FlushLine() ) {
PyErr_Clear();
}

/*
* if a result was set, delete it so statements which dont return
* a value dont return a prior set value
*/
if( resultObj != NULL ) {
PyRun_SimpleString( "del __main__.__result" );
}

printf( ">> " );
}

printf( "Done.\n" );
return 0;
}
--------

Not sure if that is exactly what you were looking for, but it does
allow one to execute statements and expressions and process the result
(if any).

-Rick Ratzel


David Faden wrote:
> Hi,
>
> Given arbitrary Python source code input by the user, I want to get the
> result of executing that source as an expression if it is an expression
> and otherwise execute the source as a statement. Currently, I'm
> accomplishing this as follows (in a category on NSString), but it seems
> kludgy to rely on detecting a syntax error.
>
> - (PyObject*)executePythonSourceWithGlobalsPyObjec t*)globals
> {
> const char* source = [self UTF8String];
> PyObject* result = PyRun_String(source, Py_eval_input, globals,
> globals);
> if (!result && PyErr_ExceptionMatches(PyExc_SyntaxError)) {
> PyErr_Clear();
> result = PyRun_String(source, Py_file_input, globals, globals);
> }
> return result;
> }
>
> How would you accomplish this? How does the interpreter do it?
>
> Thank you.
>
> David
> AIM: pitulx
>
>

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Parsing Binary Structures; Is there a better way / What is your way? Paul Rubin Python 5 08-06-2009 08:06 AM
way way way OT: MCNGP Announcement Neil MCSE 174 04-17-2006 05:55 PM
AMD Opteron: 1-way, 2-way, ... Up to 8-way. John John Windows 64bit 12 12-27-2005 08:17 AM
Is there a way of executing a command in a string? Jerry He Python 2 08-11-2005 01:50 AM
Build a Better Blair (like Build a Better Bush, only better) Kenny Computer Support 0 05-06-2005 04:50 AM



Advertisments