static int CPPerror(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); const char *message; while (token != '\n') { if (token <= 0){ CPPErrorToInfoLog("unexpected end of input in #error preprocessor directive - expected a newline"); return 0; }else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){ StoreStr(yylvalpp->symbol_name); }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){ StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident)); }else { StoreStr(GetStringOfAtom(atable,token)); } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } DecLineNumber(); //store this msg into the shader's information log..set the Compile Error flag!!!! message=GetStrfromTStr(); CPPShInfoLogMsg(message); ResetTString(); cpp->CompileError=1; IncLineNumber(); return '\n'; }//CPPerror
static int CPPerror(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); const char *message; while (token != '\n') { if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT) { StoreStr(yylvalpp->symbol_name); } else if (token == CPP_IDENTIFIER || token == CPP_STRCONSTANT) { StoreStr(GetStringOfAtom(atable, yylvalpp->sc_ident)); } else { StoreStr(GetStringOfAtom(atable, token)); } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } DecLineNumber(); /*store this msg into the shader's information log..set the Compile Error flag!!!! */ message = GetStrfromTStr(); CPPShInfoLogMsg(message); ResetTString(); cpp->CompileError = 1; IncLineNumber(); return '\n'; } /*CPPerror */
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
int readCPPline(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); const char *message; if (token == CPP_IDENTIFIER) { if (yylvalpp->sc_ident == defineAtom) { token = CPPdefine(yylvalpp); } else if (yylvalpp->sc_ident == elseAtom) { if(ChkCorrectElseNesting()){ if (!cpp->ifdepth ){ CPPErrorToInfoLog("#else mismatch"); cpp->CompileError=1; return 0; } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != '\n') { CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline"); while (token != '\n') { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token <= 0) { // EOF or error CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline"); return 0; } } } token = CPPelse(0, yylvalpp); }else{ CPPErrorToInfoLog("#else after a #else"); cpp->ifdepth = 0; cpp->elsetracker = 0; cpp->pastFirstStatement = 1; cpp->CompileError = 1; return 0; } } else if (yylvalpp->sc_ident == elifAtom) { if (!cpp->ifdepth){ CPPErrorToInfoLog("#elif mismatch"); cpp->CompileError=1; return 0; } // this token is really a dont care, but we still need to eat the tokens token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); while (token != '\n') { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token <= 0) { // EOF or error CPPErrorToInfoLog("unexpect tokens following #elif preprocessor directive - expected a newline"); cpp->CompileError = 1; return 0; } } token = CPPelse(0, yylvalpp); } else if (yylvalpp->sc_ident == endifAtom) { if (!cpp->ifdepth){ CPPErrorToInfoLog("#endif mismatch"); cpp->CompileError=1; return 0; } else --cpp->ifdepth; if (cpp->elsetracker) --cpp->elsetracker; } else if (yylvalpp->sc_ident == ifAtom) { token = CPPif(yylvalpp); } else if (yylvalpp->sc_ident == ifdefAtom) { token = CPPifdef(1, yylvalpp); } else if (yylvalpp->sc_ident == ifndefAtom) { token = CPPifdef(0, yylvalpp); } else if (yylvalpp->sc_ident == lineAtom) { token = CPPline(yylvalpp); } else if (yylvalpp->sc_ident == pragmaAtom) { token = CPPpragma(yylvalpp); } else if (yylvalpp->sc_ident == undefAtom) { token = CPPundef(yylvalpp); } else if (yylvalpp->sc_ident == errorAtom) { token = CPPerror(yylvalpp); } else if (yylvalpp->sc_ident == versionAtom) { token = CPPversion(yylvalpp); } else if (yylvalpp->sc_ident == extensionAtom) { token = CPPextension(yylvalpp); } else { StoreStr("Invalid Directive"); StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident)); message=GetStrfromTStr(); CPPShInfoLogMsg(message); ResetTString(); } } while (token != '\n' && token != 0 && token != EOF) { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } cpp->pastFirstStatement = 1; return token; } // readCPPline
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
TParseTables* GenerateParseTables(void) { size_t IP, IPStart; int NNonTerms, NSymbols; int iRule, iTerminal; SymIt NonTerm; TSymbol* Symbol; TParseTables* Tables; SYMBOLS LLNonTerms; int Reduced; int TerminalsEmitted; printf("GenerateParseTables() begins\n"); Tables = NEW(TParseTables); assert(Tables != NULL); Tables->LLNonTerms = LLNonTerms = GetLLNonTerms(); /* get list of only nonterminals we care about */ /* assign integers to any undefined tokens */ DefineTokens(Tables); IP = BLC_HDR_SIZE; /* skip over initial header containing 5 two-byte table sizes */ NNonTerms = SymbolListCount(LLNonTerms); /* generate terminal symbol table */ IPStart = IP; TerminalsEmitted = 0; for(iTerminal=Tables->MinTokenVal; iTerminal <= Tables->MaxTokenVal; ++iTerminal) { Symbol = SymbolFromValue(iTerminal); if(Symbol) { /* store token ID, followed by its null-terminated string */ IP = Store8(Tables, IP, iTerminal); IP = StoreStr(Tables, IP, SymbolStr(Symbol)); ++TerminalsEmitted; } } IP = Store8(Tables, IP, 0); /* sentinel byte */ Store16(Tables, BLC_HDR_TERMSYMTAB_SIZE, IP - IPStart); /* generate nonterminal symbol table */ IPStart = IP; NonTerm = SymItNew(LLNonTerms); while(SymbolIterate(&NonTerm)) { IP = StoreStr(Tables, IP, SymbolStr(NonTerm.Symbol)); } IP = Store8(Tables, IP, 0); /* sentinel byte */ Store16(Tables, BLC_HDR_NONTERMSYMTAB_SIZE, IP - IPStart); /* for each production of <start>, add an entry point */ IPStart = IP; Symbol = SymbolStart(); assert(Symbol != NULL); for(iRule = 0; iRule < RuleCount(Symbol); ++iRule) { /* actual value will have to be backpatched */ MarkPatch(IP, AddRule(Tables, Symbol->Rules[iRule], Symbol)); IP = Store16(Tables, IP, 0); } Store16(Tables, BLC_HDR_ENTRYTABLE_SIZE, IP - IPStart); /* for each nonterminal, generate its SELECT body*/ IPStart = IP; Tables->SelSectOfs = IPStart; NonTerm = SymItNew(LLNonTerms); while(SymbolIterate(&NonTerm)) IP = GenerateSelect(Tables, IP, NonTerm.Symbol); Store16(Tables, BLC_HDR_SELECTTABLE_SIZE, IP - IPStart); Dump("Generate opcodes for each unique rule\n"); /* generate opcodes for each unique rule */ IPStart = IP; Tables->RuleSectOfs = IPStart; for(iRule = 0; iRule < Tables->NRules; ++iRule) { int iProdItem; TRule* Rule = Tables->Rules[iRule]; IntAdd(&Tables->RuleOffsets, IP); Reduced = FALSE; /* have not performed a reduction for this rule yet */ NSymbols = SymbolListCount(Rule->Symbols); fprintf(stdout, "-> "); SymbolListDump(stdout, Rule->Symbols, " "); fprintf(stdout, "\n"); for(iProdItem = 0; iProdItem < NSymbols; ++iProdItem) { TSymbol* Symbol = SymbolListGet(Rule->Symbols, iProdItem); if(SymbolGetBit(Symbol, SYM_TERMINAL)) { IP = Store8(Tables, IP, BLCOP_MATCH); IP = Store8(Tables, IP, Symbol->Value); if(Symbol == SymbolFind(EOFToken)) { IP = Store8(Tables, IP, BLCOP_HALT); Reduced = TRUE; } } else if(SymbolIsAction(Symbol)) { int FinalAction, ArgCount; assert(Rule->RuleId < 255); assert(iProdItem < 255); FinalAction = FALSE; if(iProdItem == NSymbols-1) FinalAction = TRUE; else if(Rule->TailRecursive && iProdItem == NSymbols-2) FinalAction = TRUE; ArgCount = iProdItem; if(Rule->TailRecursive == 2) ++ArgCount; fprintf(stdout, "iProdItem=%d, NSymbols=%d,TailRecursive=%d,FinalAction=%d\n", iProdItem, NSymbols, Rule->TailRecursive, FinalAction); IP = Store8(Tables, IP, FinalAction?BLCOP_ACTRED:BLCOP_ACTION8); IP = Store8(Tables, IP, Symbol->Action->Number); IP = Store8(Tables, IP, ArgCount); Symbol->Action->ArgCount = ArgCount; if(FinalAction) Reduced = TRUE; } else if(SymbolListContains(LLNonTerms, Symbol)) /* non-terminal */ { int iSymbol = SymbolListContains(LLNonTerms, Symbol); if(RuleCount(Symbol) > 1) { if(Symbol->Name.Text[0] == '`') /* if a tail recursive rule... */ { IP = Store8(Tables, IP, BLCOP_TAILSELECT); IP = Store8(Tables, IP, iProdItem); Reduced = TRUE; /* TAILSELECT opcode must do the reducing to shuffle stack correctly */ } else IP = Store8(Tables, IP, BLCOP_LLSELECT); IP = Store16(Tables, IP, Symbol->SelectOffset); } /* else, only 1 rule to choose from, so just transfer control to that rule! */ else { int iRule = AddRule(Tables, Symbol->Rules[0], Symbol); IP = Store8(Tables, IP, BLCOP_CALL); IP = MarkPatch(IP, iRule); } assert(iSymbol>0); /* ???TODO why is this???*/ } else // else, it's an operator trigger { assert(Symbol->LR0 != NULL); fprintf(stderr, "watch out: we don't handle LR(0) yet!\n"); } } if(!Reduced) { IP = Store8(Tables, IP, BLCOP_REDUCE); IP = Store8(Tables, IP, NSymbols); } } Store16(Tables, BLC_HDR_RULEOPCODE_SIZE, IP - IPStart); DumpVerbose("Backpatch opcode addresses.\n"); for(iRule = 0; iRule < Tables->NRules; ++iRule) BackPatch(Tables, iRule, Tables->RuleOffsets.v[iRule] - IPStart); DumpVerbose("Backpatching complete.\n"); assert(IP < (1024*64)); // Opcodes = realloc(Opcodes, IP * sizeof(Opcodes[0])); Tables->NOpcodes = IP; Dump("GenerateParseTables() returns after %d opcodes\n", Tables->NOpcodes); return Tables; }
int readCPPline(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); const char *message; int isVersion = 0; if (token == CPP_IDENTIFIER) { if (yylvalpp->sc_ident == defineAtom) { token = CPPdefine(yylvalpp); } else if (yylvalpp->sc_ident == elseAtom) { token = CPPgotoEndOfIfBlock(1, yylvalpp); if (yylvalpp->sc_ident != endifAtom) { CPPErrorToInfoLog("#else or #elif mismatch"); cpp->CompileError=1; } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != '\n') CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline"); if (!cpp->ifdepth){ CPPErrorToInfoLog("#else or #elif mismatch"); cpp->CompileError=1; } else --cpp->ifdepth; } else if (yylvalpp->sc_ident == elifAtom) { token = CPPgotoEndOfIfBlock(0, yylvalpp); assert(yylvalpp->sc_ident == endifAtom); token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (!cpp->ifdepth){ CPPErrorToInfoLog("#else or #elif mismatch"); cpp->CompileError=1; } else --cpp->ifdepth; } else if (yylvalpp->sc_ident == endifAtom) { if (!cpp->ifdepth){ CPPErrorToInfoLog("#endif mismatch"); cpp->CompileError=1; } else --cpp->ifdepth; } else if (yylvalpp->sc_ident == ifAtom) { token = CPPif(yylvalpp); } else if (yylvalpp->sc_ident == ifdefAtom) { token = CPPifdef(1, yylvalpp); } else if (yylvalpp->sc_ident == ifndefAtom) { token = CPPifdef(0, yylvalpp); } else if (yylvalpp->sc_ident == lineAtom) { token = CPPline(yylvalpp); } else if (yylvalpp->sc_ident == pragmaAtom) { token = CPPpragma(yylvalpp); } else if (yylvalpp->sc_ident == undefAtom) { token = CPPundef(yylvalpp); } else if (yylvalpp->sc_ident == errorAtom) { token = CPPerror(yylvalpp); } else if (yylvalpp->sc_ident == versionAtom) { token = CPPversion(yylvalpp); isVersion = 1; } else { StoreStr("Invalid Directive"); StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident)); message=GetStrfromTStr(); CPPShInfoLogMsg(message); ResetTString(); } } while (token != '\n' && token != 0 && token != EOF) { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); } cpp->notAVersionToken = !isVersion; return token; } // readCPPline