⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compile.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 3 页
字号:
LIST *compile_local(    PARSE   *parse,    FRAME *frame ){    LIST *l;    SETTINGS *s = 0;    LIST    *nt = parse_evaluate( parse->left, frame );    LIST    *ns = parse_evaluate( parse->right, frame );    LIST    *result;    if( DEBUG_COMPILE )    {        debug_compile( 0, "local", frame);        list_print( nt );        printf( " = " );        list_print( ns );        printf( "\n" );    }    /* Initial value is ns */    for( l = nt; l; l = list_next( l ) )        s = addsettings( s, VAR_SET, l->string, list_copy( (LIST*)0, ns ) );    list_free( ns );    list_free( nt );    /* Note that callees of the current context get this "local" */    /* variable, making it not so much local as layered. */    pushsettings( s );    result = parse_evaluate( parse->third, frame );    popsettings( s );    freesettings( s );    return result;}/* * compile_null() - do nothing -- a stub for parsing */LIST *compile_null(    PARSE   *parse,    FRAME *frame ){    return L0;}/* * compile_on() - run rule under influence of on-target variables * * 	parse->left	list of files to include (can only do 1) *	parse->right	rule to run * * EXPERIMENTAL! */LIST *compile_on(	PARSE	*parse,	FRAME	*frame ){	LIST    *nt = parse_evaluate( parse->left, frame );	LIST	*result = 0;	if( DEBUG_COMPILE )	{	    debug_compile( 0, "on", frame );	    list_print( nt );	    printf( "\n" );	}	if( nt )	{	    TARGET *t = bindtarget( nt->string );	    pushsettings( t->settings );	    result = parse_evaluate( parse->right, frame );	    popsettings( t->settings );	}	list_free( nt );	return result;}/* * compile_rule() - compile a single user defined rule * *  parse->string   name of user defined rule *  parse->left parameters (list of lists) to rule, recursing left * * Wrapped around evaluate_rule() so that headers() can share it. */LIST *compile_rule(    PARSE   *parse,    FRAME *frame ){    FRAME       inner[1];    LIST    *result;    PARSE   *p;        /* Build up the list of arg lists */    frame_init( inner );    inner->prev = frame;    inner->prev_user = frame->module->user_module ? frame : frame->prev_user;    inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below */    inner->procedure = parse;    for( p = parse->left; p; p = p->left )        lol_add( inner->args, parse_evaluate( p->right, frame ) );    /* And invoke rule */    result = evaluate_rule( parse->string, inner );    frame_free( inner );    return result;}static void argument_error( char* message, RULE* rule, FRAME* frame, LIST* arg ){    LOL* actual = frame->args;    assert( frame->procedure != 0 );    backtrace_line( frame->prev );    printf( "*** argument error\n* rule %s ( ", frame->rulename );    lol_print( rule->arguments->data );    printf( " )\n* called with: ( " );    lol_print( actual );    printf( " )\n* %s %s\n", message, arg ? arg->string : "" );    print_source_line( rule->procedure );    printf( "see definition of rule '%s' being called\n", rule->name );    backtrace( frame->prev );    exit(1);}/* define delimiters for type check elements in argument lists (and * return type specifications, eventually) */# define TYPE_OPEN_DELIM '['# define TYPE_CLOSE_DELIM ']'/* is_type_name - true iff the given string represents a type check * specification */static intis_type_name( char* s ){    return s[0] == TYPE_OPEN_DELIM        && s[strlen(s) - 1] == TYPE_CLOSE_DELIM;}/* * arg_modifier - if the next element of formal is a single character, * return that; return 0 otherwise.  Used to extract "*+?" modifiers * from argument lists. */static chararg_modifier( LIST* formal ){    if ( formal->next )    {        char *next = formal->next->string;        if ( next && next[0] != 0 && next[1] == 0 )            return next[0];    }    return 0;}/* * type_check - checks that each element of values satisfies the * requirements of type_name. * *      caller   - the frame of the rule calling the rule whose *                 arguments are being checked * *      called   - the rule being called * *      arg_name - a list element containing the name of the argument *                 being checked */static voidtype_check( char* type_name, LIST *values, FRAME* caller, RULE* called, LIST* arg_name ){    static module_t *typecheck = 0;    /* if nothing to check, bail now */    if ( !values || !type_name )        return;    if ( !typecheck )        typecheck = bindmodule(".typecheck");    /* if the checking rule can't be found, also bail */    {        RULE checker_, *checker = &checker_;        checker->name = type_name;        if ( !typecheck->rules || !hashcheck( typecheck->rules, (HASHDATA**)&checker ) )            return;    }        exit_module( caller->module );        while ( values != 0 )    {        LIST *error;        FRAME frame[1];        frame_init( frame );        frame->module = typecheck;        frame->prev = caller;        frame->prev_user = caller->module->user_module ? caller : caller->prev_user;        enter_module( typecheck );        /* Prepare the argument list */        lol_add( frame->args, list_new( L0, values->string ) );        error = evaluate_rule( type_name, frame );                exit_module( typecheck );                if ( error )            argument_error( error->string, called, caller, arg_name );        frame_free( frame );		values = values->next;    }    enter_module( caller->module );}/* * collect_arguments() - local argument checking and collection */static SETTINGS *collect_arguments( RULE* rule, FRAME* frame ){    SETTINGS *locals = 0;        LOL* all_actual = frame->args;    LOL *all_formal = rule->arguments ? rule->arguments->data : 0;    if ( all_formal ) /* Nothing to set; nothing to check */    {        int max = all_formal->count > all_actual->count            ? all_formal->count            : all_actual->count;                int n;        for ( n = 0; n < max ; ++n )        {            LIST *actual = lol_get( all_actual, n );            char *type_name = 0;                        LIST *formal;            for ( formal = lol_get( all_formal, n ); formal; formal = formal->next )            {                char* name = formal->string;                if ( is_type_name(name) )                {                    if ( type_name )                        argument_error( "missing argument name before type name:", rule, frame, formal );                                        if ( !formal->next )                        argument_error( "missing argument name after type name:", rule, frame, formal );                    type_name = formal->string;                }                else                {                    LIST* value = 0;                    char modifier;                    LIST* arg_name = formal; /* hold the argument name for type checking */                                        /* Stop now if a variable number of arguments are specified */                    if ( name[0] == '*' && name[1] == 0 )                        return locals;                    modifier = arg_modifier( formal );                                    if ( !actual && modifier != '?' && modifier != '*' )                        argument_error( "missing argument", rule, frame, formal );                    switch ( modifier )                    {                    case '+':                    case '*':                        value = list_copy( 0, actual );                        actual = 0;                        /* skip an extra element for the modifier */                        formal = formal->next;                         break;                    case '?':                        /* skip an extra element for the modifier */                        formal = formal->next;                         /* fall through */                    default:                        if ( actual ) /* in case actual is missing */                        {                            value = list_new( 0, actual->string );                            actual = actual->next;                        }                    }                                    locals = addsettings( locals, VAR_SET, name, value );                    type_check( type_name, value, frame, rule, arg_name );                    type_name = 0;                }            }                        if ( actual )            {                argument_error( "extra argument", rule, frame, actual );            }        }    }    return locals;}static int python_instance_number = 0;RULE *enter_rule( char *rulename, module_t *target_module );#ifdef HAVE_PYTHONstatic LIST*call_python_function(RULE* r, FRAME* frame){    LIST* result = 0;    PyObject* arguments = PyTuple_New(frame->args->count);    int i ;    PyObject* py_result;    for(i = 0; i < frame->args->count; ++i)    {        PyObject* arg = PyList_New(0);        LIST* l = lol_get( frame->args, i);        for(; l; l = l->next)        {            PyObject* v = PyString_FromString(l->string);            /* Steals reference to 'v' */            PyList_Append(arg, v);                    }        /* Steals reference to 'arg' */        PyTuple_SetItem(arguments, i, arg);    }    frame_before_python_call = frame;    py_result = PyObject_CallObject(r->python_function, arguments);    Py_DECREF(arguments);    if (py_result != NULL) {                if (PyList_Check(py_result)) {            int size = PyList_Size(py_result);            int i;            for(i = 0; i < size; ++i)            {                PyObject* item = PyList_GetItem(py_result, i);                if (PyString_Check(item))                {                    result = list_new(result,                                       newstr(PyString_AsString(item)));                }                else                {                    fprintf(stderr, "Non-string object returned by Python call\n");                }            }        }        else if (PyInstance_Check(py_result))        {            static char instance_name[1000];            static char imported_method_name[1000];            module_t* m;            PyObject* method;            PyObject* method_name = PyString_FromString("foo");            RULE* r;            fprintf(stderr, "Got instance!\n");            snprintf(instance_name, 1000,                     "pyinstance%d", python_instance_number);            snprintf(imported_method_name, 1000,                     "pyinstance%d.foo", python_instance_number);            ++python_instance_number;                        m = bindmodule(instance_name);            /* This is expected to get bound method. */            method = PyObject_GetAttr(py_result, method_name);                        r = bindrule( imported_method_name, root_module() );            r->python_function = method;            result = list_new(0, newstr(instance_name));                Py_DECREF(method_name);        }        else if (py_result == Py_None)        {            result = L0;        }        else        {            fprintf(stderr, "Non-list object returned by Python call\n");        }        Py_DECREF(py_result);    }    else {        PyErr_Print();        fprintf(stderr,"Call failed\n");    }        return result;}module_t* python_module(){    static module_t* python = 0;    if ( !python )        python = bindmodule("__python__");    return python;}#endif/* * evaluate_rule() - execute a rule invocation */LIST *evaluate_rule(    char    *rulename,    FRAME *frame ){    LIST      *result = L0;    RULE          *rule;    profile_frame prof[1];    module_t    *prev_module = frame->module;        LIST      *l;    {        LOL arg_context_, *arg_context = &arg_context_;        if ( !frame->prev )            lol_init(arg_context);        else            arg_context = frame->prev->args;                l = var_expand( L0, rulename, rulename+strlen(rulename), arg_context, 0 );    }    if ( !l )    {        backtrace_line( frame->prev );        printf( "warning: rulename %s expands to empty string\n", rulename );        backtrace( frame->prev );        return result;    }    rulename = l->string;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -