better way of executing expression/statement in C?
Rick L. Ratzel
rick.ratzel at scd.magma-da.com
Fri May 21 17:21:24 EDT 2004
This might be slightly less kludgy...I tested it by implementing a
crude input loop. Here is the output:
[rlratzel at 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:(PyObject*)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
>
>
More information about the Python-list
mailing list