示例#1
0
int MacroExpand(int atom, yystypepp * yylvalpp)
{
    Symbol              *sym = LookUpSymbol(macros, atom);
    MacroInputSrc       *in;
    int i,j, token, depth=0;
    const char *message;
	if (atom == __LINE__Atom) {
        yylvalpp->sc_int = GetLineNumber();
        snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
        UngetToken(CPP_INTCONSTANT, yylvalpp);
        return 1;
    }
    if (atom == __FILE__Atom) {
        yylvalpp->sc_int = GetStringNumber();
        snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
        UngetToken(CPP_INTCONSTANT, yylvalpp);
        return 1;
    }
	if (atom == __VERSION__Atom) {
        strcpy(yylvalpp->symbol_name,ESSL_VERSION_STRING);
        yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
        UngetToken(CPP_INTCONSTANT, yylvalpp);
        return 1;
    }
    if (!sym || sym->details.mac.undef) return 0;
    if (sym->details.mac.busy) return 0;        // no recursive expansions
    in = malloc(sizeof(*in));
    memset(in, 0, sizeof(*in));
    in->base.scan = (void *)macro_scan;
    in->base.line = cpp->currentInput->line;
    in->base.name = cpp->currentInput->name;
    in->mac = &sym->details.mac;
    if (sym->details.mac.args) {
        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
		if (token != '(') {
            UngetToken(token, yylvalpp);
            yylvalpp->sc_ident = atom;
            return 0;
        }
        in->args = malloc(in->mac->argc * sizeof(TokenStream *));
        for (i=0; i<in->mac->argc; i++)
            in->args[i] = NewTokenStream("macro arg", 0);
		i=0;j=0;
        do{
            depth = 0;
			while(1) {
                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                if (token <= 0) {
                    StoreStr("EOF in Macro ");
                    StoreStr(GetStringOfAtom(atable,atom));
                    message=GetStrfromTStr();
                    CPPShInfoLogMsg(message);
                    ResetTString();
                    return 1;
                }
                if((in->mac->argc==0) && (token!=')')) break;
                if (depth == 0 && (token == ',' || token == ')')) break;
                if (token == '(') depth++;
                if (token == ')') depth--;
                RecordToken(in->args[i], token, yylvalpp);
                j=1;
			}
            if (token == ')') {
                if((in->mac->argc==1) &&j==0)
                    break;
                i++;
                break;
            }
            i++;
		}while(i < in->mac->argc);

        if (i < in->mac->argc) {
            StoreStr("Too few args in Macro ");
            StoreStr(GetStringOfAtom(atable,atom));
            message=GetStrfromTStr();
            CPPShInfoLogMsg(message);
            ResetTString();
        } else if (token != ')') {
            depth=0;
			while (token >= 0 && (depth > 0 || token != ')')) {
                if (token == ')') depth--;
                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                if (token == '(') depth++;
            }
			
            if (token <= 0) {
                StoreStr("EOF in Macro ");
                StoreStr(GetStringOfAtom(atable,atom));
                message=GetStrfromTStr();
                CPPShInfoLogMsg(message);
                ResetTString();
                return 1;
            }
            StoreStr("Too many args in Macro ");
            StoreStr(GetStringOfAtom(atable,atom));
            message=GetStrfromTStr();
            CPPShInfoLogMsg(message);
            ResetTString();
		}
		for (i=0; i<in->mac->argc; i++) {
            in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
        }
    }
#if 0
    printf("  <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
           loc.line, GetAtomString(atable, atom));
    for (i=0; i<in->mac->argc; i++) {
        printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
        DumpTokenStream(stdout, in->args[i]);
        printf("'\n");
    }
#endif
	/*retain the input source*/
    in->base.prev = cpp->currentInput;
    sym->details.mac.busy = 1;
    RewindTokenStream(sym->details.mac.body);
    cpp->currentInput = &in->base;
    return 1;
} // MacroExpand
示例#2
0
文件: Pp.cpp 项目: 3dcl/glslang
/* MacroExpand
** Check an identifier (atom) to see if it is a macro that should be expanded.
** If it is, push an InputSrc that will produce the appropriate expansion
** and return 1.
** If it is, but undefined, it should expand to 0, push an InputSrc that will 
** expand to 0 and return -1.
** Otherwise, return 0.
*/
int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
{
    Symbol *sym = LookUpSymbol(macros, atom);
    MacroInputSrc *in;
    int i, j, token;
    int depth = 0;

    if (atom == __LINE__Atom) {
        yylvalpp->ival = parseContext.currentLoc.line;
        sprintf(yylvalpp->name, "%d", yylvalpp->ival);
        UngetToken(CPP_INTCONSTANT, yylvalpp);

        return 1;
    }

    if (atom == __FILE__Atom) {
        yylvalpp->ival = parseContext.currentLoc.string;
        sprintf(yylvalpp->name, "%d", yylvalpp->ival);
        UngetToken(CPP_INTCONSTANT, yylvalpp);

        return 1;
    }

    if (atom == __VERSION__Atom) {
        yylvalpp->ival = parseContext.version;
        sprintf(yylvalpp->name, "%d", yylvalpp->ival);
        UngetToken(CPP_INTCONSTANT, yylvalpp);

        return 1;
    }

    // no recursive expansions
    if (sym && sym->details.mac.busy)
        return 0;

    // not expanding of undefined symbols
    if ((! sym || sym->details.mac.undef) && ! expandUndef)
        return 0;

    in = (MacroInputSrc*)malloc(sizeof(*in));
    memset(in, 0, sizeof(*in));
    in->base.line = currentInput->line;
    in->base.name = currentInput->name;

    if ((! sym || sym->details.mac.undef) && expandUndef) {
        // push input
        in->base.scan = zero_scan;
        in->base.prev = currentInput;
        currentInput = &in->base;

        return -1;
    }

    in->base.scan = macro_scan;
    in->mac = &sym->details.mac;
    if (sym->details.mac.args) {
        token = currentInput->scan(this, currentInput, yylvalpp);
        if (token != '(') {
            UngetToken(token, yylvalpp);
            yylvalpp->atom = atom;

            return 0;
        }
        in->args = (TokenStream**)malloc(in->mac->argc * sizeof(TokenStream *));
        for (i = 0; i < in->mac->argc; i++)
            in->args[i] = NewTokenStream("macro arg", 0);
        i = 0;
        j = 0;
        do {
            depth = 0;
            while (1) {
                token = currentInput->scan(this, currentInput, yylvalpp);
                if (token <= 0) {
                    parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetStringOfAtom(&atomTable, atom));

                    return 1;
                }
                if ((in->mac->argc==0) && (token!=')')) break;
                if (depth == 0 && (token == ',' || token == ')')) break;
                if (token == '(') depth++;
                if (token == ')') depth--;
                RecordToken(in->args[i], token, yylvalpp);
                j=1;
            }
            if (token == ')') {
                if ((in->mac->argc==1) &&j==0)
                    break;
                i++;
                break;
            }
            i++;
        } while (i < in->mac->argc);

        if (i < in->mac->argc)
            parseContext.error(yylvalpp->loc, "Too few args in Macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
        else if (token != ')') {
            depth=0;
            while (token >= 0 && (depth > 0 || token != ')')) {
                if (token == ')')
                    depth--;
                token = currentInput->scan(this, currentInput, yylvalpp);
                if (token == '(')
                    depth++;
            }

            if (token <= 0) {
                parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetStringOfAtom(&atomTable, atom));

                return 1;
            }
            parseContext.error(yylvalpp->loc, "Too many args in Macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
        }
        for (i = 0; i<in->mac->argc; i++) {
            in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
        }
    }
#if 0
    printf("  <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
        loc.line, GetAtomString(atable, atom));
    for (i = 0; i<in->mac->argc; i++) {
        printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
        DumpTokenStream(stdout, in->args[i]);
        printf("'\n");
    }
#endif
    /*retain the input source*/
    in->base.prev = currentInput;
    sym->details.mac.busy = 1;
    RewindTokenStream(sym->details.mac.body);
    currentInput = &in->base;

    return 1;
} // MacroExpand