Exemple #1
0
static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp)
{
	int token;
	TokenStream *n;
	RewindTokenStream(a);
	do {
		token = ReadToken(a, yylvalpp);
		if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->sc_ident))
			break;
	} while (token > 0);
	if (token <= 0)
		return a;
	n = NewTokenStream("macro arg", 0);
	PushEofSrc();
	ReadFromTokenStream(a, 0, 0);
	while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) {
		if (token == CPP_IDENTIFIER
				&& MacroExpand(yylvalpp->sc_ident, yylvalpp))
			continue;
		RecordToken(n, token, yylvalpp);
	}
	PopEofSrc();
	DeleteTokenStream(a);
	return n;
} /* PrescanMacroArg */
Exemple #2
0
void PredefineIntMacro(const char *name, int value) {
    SourceLoc location = {0, 0};
    Symbol *symbol = NULL;
    MacroSymbol macro = {0, NULL, NULL, 0, 0};
    yystypepp val = {0, 0.0, 0, {0}};
    int atom = 0;

    macro.body = NewTokenStream(name, macros->pool);
    val.sc_int = value;
    snprintf(val.symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", value);
    RecordToken(macro.body, CPP_INTCONSTANT, &val);
    atom = LookUpAddString(atable, name);
    symbol = AddSymbol(&location, macros, atom, MACRO_S);
    symbol->details.mac = macro;
}
Exemple #3
0
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken * yylvalpp)
{
    int token;
    TokenStream *n;
    RewindTokenStream(a);
    do {
        token = ReadToken(a, yylvalpp);
        if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->atom))
            break;
    } while (token > 0);
    if (token <= 0) return a;
    n = NewTokenStream("macro arg", 0);
    PushEofSrc();
    ReadFromTokenStream(a, 0, 0);
    while ((token = currentInput->scan(this, currentInput, yylvalpp)) > 0) {
        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->atom, yylvalpp, 0) == 1)
            continue;
        RecordToken(n, token, yylvalpp);
    }
    PopEofSrc();
    DeleteTokenStream(a);
    return n;
} // PrescanMacroArg
Exemple #4
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
Exemple #5
0
static int CPPdefine(yystypepp * yylvalpp)
{
    int token, name, args[MAX_MACRO_ARGS], argc;
    const char *message;
    MacroSymbol mac;
    Symbol *symb;
    SourceLoc dummyLoc;
    memset(&mac, 0, sizeof(mac));
    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    if (token != CPP_IDENTIFIER) {
        CPPErrorToInfoLog("#define");
        return token;
    }
    name = yylvalpp->sc_ident;
    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    if (token == '(' && !yylvalpp->sc_int) {
        // gather arguments
        argc = 0;
        do {
            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
            if (argc == 0 && token == ')') break;
            if (token != CPP_IDENTIFIER) {
				CPPErrorToInfoLog("#define");
                return token;
            }
            if (argc < MAX_MACRO_ARGS)
                args[argc++] = yylvalpp->sc_ident;
            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
        } while (token == ',');
        if (token != ')') {
            CPPErrorToInfoLog("#define");
            return token;
        }
        mac.argc = argc;
        mac.args = mem_Alloc(macros->pool, argc * sizeof(int));
        memcpy(mac.args, args, argc * sizeof(int));
        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
	}
    mac.body = NewTokenStream(GetAtomString(atable, name), macros->pool);
    while (token != '\n') {
        if (token == '\\') {
            CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
            return token;
        } else if (token <= 0) { // EOF or error
            CPPErrorToInfoLog("unexpected end of input in #define preprocessor directive - expected a newline");
            return 0;
        }
        RecordToken(mac.body, token, yylvalpp);
        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    };

    symb = LookUpSymbol(macros, name);
    if (symb) {
        if (!symb->details.mac.undef) {
            // already defined -- need to make sure they are identical
            if (symb->details.mac.argc != mac.argc) goto error;
            for (argc=0; argc < mac.argc; argc++)
                if (symb->details.mac.args[argc] != mac.args[argc])
                    goto error;
            RewindTokenStream(symb->details.mac.body);
            RewindTokenStream(mac.body);
            do {
                int old_lval, old_token;
                old_token = ReadToken(symb->details.mac.body, yylvalpp);
                old_lval = yylvalpp->sc_int;
                token = ReadToken(mac.body, yylvalpp);
                if (token != old_token || yylvalpp->sc_int != old_lval) { 
                error:
                    StoreStr("Macro Redefined");
                    StoreStr(GetStringOfAtom(atable,name));
                    message=GetStrfromTStr();
                    DecLineNumber();
                    CPPShInfoLogMsg(message);
                    IncLineNumber();
                    ResetTString();
                    break; }
            } while (token > 0);
        }
        //FreeMacro(&symb->details.mac);
    } else {
        dummyLoc.file = 0;
        dummyLoc.line = 0;
        symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
    }
    symb->details.mac = mac;
    return '\n';
} // CPPdefine
Exemple #6
0
/* 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
Exemple #7
0
int TPpContext::CPPdefine(TPpToken * yylvalpp)
{
    int token, name, args[maxMacroArgs], argc;
    MacroSymbol mac;
    Symbol *symb;
    memset(&mac, 0, sizeof(mac));
    token = currentInput->scan(this, currentInput, yylvalpp);
    if (token != CPP_IDENTIFIER) {
        parseContext.error(yylvalpp->loc, "must be followed by macro name", "#define", "");
        return token;
    }
    name = yylvalpp->atom;
    token = currentInput->scan(this, currentInput, yylvalpp);
    if (token == '(' && !yylvalpp->ival) {
        // gather arguments
        argc = 0;
        do {
            token = currentInput->scan(this, currentInput, yylvalpp);
            if (argc == 0 && token == ')') 
                break;
            if (token != CPP_IDENTIFIER) {
                parseContext.error(yylvalpp->loc, "bad argument", "#define", "");

                return token;
            }
            if (argc < maxMacroArgs)
                args[argc++] = yylvalpp->atom;
            token = currentInput->scan(this, currentInput, yylvalpp);
        } while (token == ',');
        if (token != ')') {            
            parseContext.error(yylvalpp->loc, "missing parenthesis", "#define", "");

            return token;
        }
        mac.argc = argc;
        mac.args = (int*)mem_Alloc(macros->pool, argc * sizeof(int));
        memcpy(mac.args, args, argc * sizeof(int));
        token = currentInput->scan(this, currentInput, yylvalpp);
    }
    mac.body = NewTokenStream(GetAtomString(&atomTable, name), macros->pool);
    while (token != '\n') {
        while (token == '\\') {
            token = currentInput->scan(this, currentInput, yylvalpp);
            if (token == '\n')
                token = currentInput->scan(this, currentInput, yylvalpp);
            else
                RecordToken(mac.body, '\\', yylvalpp);
        }
        RecordToken(mac.body, token, yylvalpp);
        token = currentInput->scan(this, currentInput, yylvalpp);
    };

    symb = LookUpSymbol(macros, name);
    if (symb) {
        if (!symb->details.mac.undef) {
            // already defined -- need to make sure they are identical
            if (symb->details.mac.argc != mac.argc)
                goto error;
            for (argc=0; argc < mac.argc; argc++)
                if (symb->details.mac.args[argc] != mac.args[argc])
                    goto error;
            RewindTokenStream(symb->details.mac.body);
            RewindTokenStream(mac.body);
            do {
                int old_lval, old_token;
                old_token = ReadToken(symb->details.mac.body, yylvalpp);
                old_lval = yylvalpp->ival;
                token = ReadToken(mac.body, yylvalpp);
                if (token != old_token || yylvalpp->ival != old_lval) { 
error:
                    parseContext.error(yylvalpp->loc, "Macro Redefined", "#define", GetStringOfAtom(&atomTable, name));
                    break; 
                }
            } while (token > 0);
        }
        //FreeMacro(&symb->details.mac);
    } else {
        symb = AddSymbol(&yylvalpp->loc, macros, name, MACRO_S);
    }
    symb->details.mac = mac;

    return '\n';
} // CPPdefine