By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,853 Members | 1,541 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,853 IT Pros & Developers. It's quick & easy.

better way of executing expression/statement in C?

P: n/a
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*)executePythonSourceWithGlobals:(PyObjec 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
Jul 18 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a

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*)executePythonSourceWithGlobals:(PyObjec 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

Jul 18 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.