SymbolTable::SymbolTable(string file_name) { file = file_name; ifstream fin(file.c_str()); ofstream fout("data/symbol_table.txt"); Symbol symbol = Symbol(file); Table table[ symbol.GetCount() ]; string line; int count = 0; int level_max = 0; /*------temp save for table------*/ int level = 0; string symbol_name = ""; string type_name = ""; bool array_bool = false; bool function_bool = false; Origin(); while(getline(fin, line)) { istringstream fin_word(line); string word = ""; string remain = ""; int pos = 0; while(fin_word >> word) { while(word != "") { if((pos = Check(word)) != -1) { if(pos != 0) { remain = word.substr(pos); word = word.substr(0, pos); } else { remain = word.substr(pos + length(word)); word = word.substr(0, length(word)); } } /*-----save in table------*/ if( FindKeyWord(word) ) { type_name = word; } else { if(type_name != "") { if(word == ";" || word == "," || word == ")" || word == "=" || word == "(" || word == "[") { if(word == ";" || word == "," || word == ")" || word == "=") { array_bool = false; function_bool = false; } else if(word == "(") { level = 0; array_bool = false; function_bool = true; } else if(word == "[") { array_bool = true; function_bool = false; } table[count].Set(level, symbol_name, type_name, array_bool, function_bool); count = count + 1; type_name = ""; } else { symbol_name = word; } } } if(word == "{" || word == "(") { level = level + 1; } else if(word == ")") { level = level - 1; } if(level > level_max) { level_max = level; } /*------------------------*/ pos = 0; word = remain; remain = ""; } } } int level_temp = 0; while(level_temp <= level_max) { for(int i = 0; i < (sizeof(table)/sizeof(*table)); i++) { if(table[i].GetLevel() == level_temp) { if(table[i].GetLevel() == table[i - 1].GetLevel() + 1) { scope = scope + 1; } table[i].SetScope(scope); } } level_temp = level_temp + 1; } //sort table for(int i = 0; i < (sizeof(table)/sizeof(*table)); i++) { for(int j = i + 1; j < (sizeof(table)/sizeof(*table)); j++) { if(table[j].GetScope() < table[i].GetScope()) { Table temp = Table(); temp.Set(table[j].GetLevel(), table[j].GetSymbol(), table[j].GetType(), table[j].GetArray(), table[j].GetFunction()); temp.SetScope(table[j].GetScope()); for(int k = j; k >= i + 1; k--) { table[k].Set(table[k - 1].GetLevel(), table[k - 1].GetSymbol(), table[k - 1].GetType(), table[k - 1].GetArray(), table[k - 1].GetFunction()); table[k].SetScope(table[k - 1].GetScope()); } table[i].Set(temp.GetLevel(), temp.GetSymbol(), temp.GetType(), temp.GetArray(), temp.GetFunction()); table[i].SetScope(temp.GetScope()); } } } int temp = 0; for(int i = 0; i < (sizeof(table)/sizeof(*table)); i++) { if(temp != table[i].GetScope()) { temp = table[i].GetScope(); fout << endl; } fout << table[i].GetScope() << " "; fout << table[i].GetSymbol() << " "; fout << table[i].GetType() << " "; fout << (table[i].GetArray() ? "true" : "false") << " "; fout << (table[i].GetFunction() ? "true" : "false") << " "; fout << endl; } fin.close(); fout.close(); }
StsgRule::StsgRule(const Subgraph &fragment) : m_targetSide(fragment, true) { // Source side const std::set<const Node *> &sinkNodes = fragment.GetLeaves(); // Collect the subset of sink nodes that excludes target nodes with // empty spans. std::vector<const Node *> productiveSinks; productiveSinks.reserve(sinkNodes.size()); for (std::set<const Node *>::const_iterator p = sinkNodes.begin(); p != sinkNodes.end(); ++p) { const Node *sink = *p; if (!sink->GetSpan().empty()) { productiveSinks.push_back(sink); } } // Sort them into the order defined by their spans. std::sort(productiveSinks.begin(), productiveSinks.end(), PartitionOrderComp); // Build a map from target nodes to source-order indices, so that we // can construct the Alignment object later. std::map<const Node *, std::vector<int> > sinkToSourceIndices; std::map<const Node *, int> nonTermSinkToSourceIndex; m_sourceSide.reserve(productiveSinks.size()); int srcIndex = 0; int nonTermCount = 0; for (std::vector<const Node *>::const_iterator p = productiveSinks.begin(); p != productiveSinks.end(); ++p, ++srcIndex) { const Node &sink = **p; if (sink.GetType() == TREE) { m_sourceSide.push_back(Symbol("X", NonTerminal)); sinkToSourceIndices[&sink].push_back(srcIndex); nonTermSinkToSourceIndex[&sink] = nonTermCount++; } else { assert(sink.GetType() == SOURCE); m_sourceSide.push_back(Symbol(sink.GetLabel(), Terminal)); // Add all aligned target words to the sinkToSourceIndices map const std::vector<Node *> &parents(sink.GetParents()); for (std::vector<Node *>::const_iterator q = parents.begin(); q != parents.end(); ++q) { if ((*q)->GetType() == TARGET) { sinkToSourceIndices[*q].push_back(srcIndex); } } } } // Alignment std::vector<const Node *> targetLeaves; m_targetSide.GetTargetLeaves(targetLeaves); m_alignment.reserve(targetLeaves.size()); m_nonTermAlignment.resize(nonTermCount); for (int i = 0, j = 0; i < targetLeaves.size(); ++i) { const Node *leaf = targetLeaves[i]; assert(leaf->GetType() != SOURCE); if (leaf->GetSpan().empty()) { continue; } std::map<const Node *, std::vector<int> >::iterator p = sinkToSourceIndices.find(leaf); assert(p != sinkToSourceIndices.end()); std::vector<int> &sourceNodes = p->second; for (std::vector<int>::iterator r = sourceNodes.begin(); r != sourceNodes.end(); ++r) { int srcIndex = *r; m_alignment.push_back(std::make_pair(srcIndex, i)); } if (leaf->GetType() == TREE) { m_nonTermAlignment[nonTermSinkToSourceIndex[leaf]] = j++; } } }
void ObjectFile::ReadFile(const byte *begin) { const COFF_IMAGE_FILE_HEADER *header = (const COFF_IMAGE_FILE_HEADER *)begin; int i; /* const COFF_IMAGE_SYMBOL *symtbl = (const COFF_IMAGE_SYMBOL *)(begin + header->PointerToSymbolTable); int nsym = header->NumberOfSymbols; const COFF_IMAGE_SYMBOL *symend = symtbl + nsym; const char *strtbl = (const char *)symend; symbols.Reserve(nsym); while(symtbl < symend) { String name; if(symtbl->N.Name.Short) name = MaxLenString(symtbl->N.ShortName, 8); else name = strtbl + symtbl->N.Name.Long; int atom = linkjob.Atomize(name); int naux = symtbl->NumberOfAuxSymbols; symbols.Add(atom, *symtbl++); while(--naux >= 0) symbols.Add(0, *symtbl++); } */ const COFF_IMAGE_SECTION_HEADER *sechdr = (const COFF_IMAGE_SECTION_HEADER *)(begin + sizeof(COFF_IMAGE_FILE_HEADER) + header->SizeOfOptionalHeader), *secptr; sections.SetCount(header->NumberOfSections + 1); Section& comdat = sections[0]; comdat.type = SEC_ANON_COMDAT; comdat.name_atom = comdat.sec_atom = linkjob.bss_atom; comdat.flags = COFF_IMAGE_SCN_CNT_UNINITIALIZED_DATA | COFF_IMAGE_SCN_ALIGN_16BYTES | COFF_IMAGE_SCN_MEM_READ | COFF_IMAGE_SCN_MEM_WRITE; comdat.comdat_packing = 0; for(i = 1, secptr = sechdr; i < sections.GetCount(); i++, secptr++) { Section& sec = sections[i]; sec.raw_size = secptr->SizeOfRawData; if(!(sec.size = secptr->Misc.VirtualSize)) sec.size = sec.raw_size; sec.offset = secptr->PointerToRawData; ASSERT(sec.offset >= 0); sec.flags = secptr->Characteristics; sec.comdat_packing = 0; sec.coff_reloc_offset = secptr->VirtualAddress; // sec.comdat_assoc = 0; String secn = MaxLenString(secptr->Name, sizeof(secptr->Name)); /* if(linkjob.merge_gcc_sections && secn[0] == '/' && IsDigit(secn[1])) { if(sec.flags & COFF_IMAGE_SCN_CNT_CODE) secn = ".text$" + secn; else if(sec.flags & COFF_IMAGE_SCN_CNT_INITIALIZED_DATA) secn = ".data$" + secn; else secn = ".bss$" + secn; } */ sec.name_atom = linkjob.Atomize(secn); secn = TrimClassName(secn); sec.sec_atom = linkjob.Atomize(secn); bool ctor_dtor_section = false; if(sec.sec_atom == linkjob.ctors_atom || sec.sec_atom == linkjob.dtors_atom) { sec.sec_atom = linkjob.data_atom; // sec.flags = (sec.flags & ~COFF_IMAGE_SCN_ALIGN_MASK) | COFF_IMAGE_SCN_ALIGN_4BYTES; has_ctors_dtors = ctor_dtor_section = true; } if(sec.sec_atom == linkjob.idata_atom) linkjob.idata_last = index; if(sec.name_atom == linkjob.idata_inull_atom) linkjob.idata_null_found = true; sec.type = (sec.sec_atom == linkjob.stab_atom ? SEC_STAB : sec.sec_atom == linkjob.stabstr_atom ? SEC_STABSTR : SEC_STD); if(sec.type == SEC_STAB) stab_index = i; else if(sec.type == SEC_STABSTR) stabstr_index = i; sec.autocollect = sec.type == SEC_STD && (sec.sec_atom == linkjob.crt_atom || ctor_dtor_section || sec.sec_atom == linkjob.idata_atom || sec.sec_atom == linkjob.rsrc_atom || !linkjob.autocollect_crt_only && (sec.flags & COFF_IMAGE_SCN_CNT_INITIALIZED_DATA)); if(sec.name_atom == linkjob.drectve_atom && (sec.flags & COFF_IMAGE_SCN_LNK_INFO)) { String directives = String(begin + secptr->PointerToRawData, secptr->SizeOfRawData); linkjob.ReadCommand(directives, false); } } if(stab_index >= 0 && stabstr_index >= 0) linkjob.has_stabs = true; coff_symbols.SetCount(header->NumberOfSymbols); const COFF_IMAGE_SYMBOL *symtbl = (const COFF_IMAGE_SYMBOL *)(begin + header->PointerToSymbolTable), *symptr = symtbl; const char *strtbl = (const char *)(symtbl + header->NumberOfSymbols); // int xxxatom = linkjob.Atomize("?AppMain@@YAXXZ"); for(i = 0; i < (int)header->NumberOfSymbols; i++, symptr++) { // if(symptr->SectionNumber > 0 && linkjob.NameAtom(*symptr, strtbl) == xxxatom) // __asm int 3; // RLOG(NFormat("%30<s SEC %04d VAL %08x %s", linkjob[linkjob.NameAtom(*symptr, strtbl)], // symptr->SectionNumber, (int)symptr->Value, file)); if(symptr->SectionNumber < 0) coff_symbols[i] = Symbol(symptr->SectionNumber, symptr->Value); else if(symptr->StorageClass == COFF_IMAGE_SYM_CLASS_STATIC && symptr->SectionNumber != 0 && symptr->Value == 0 && symptr->NumberOfAuxSymbols >= 1) // && linkjob.Atomize(TrimClassName(COFFSymbolName(*symptr, strtbl))) == sections[(int)symptr->SectionNumber].name_atom) { // section aux symbol LinkJob::Symbol lsym; lsym.obj_sec.object = index; lsym.obj_sec.section = symptr->SectionNumber; lsym.value = 0; lsym.type = LinkJob::COFF_IMAGE_SYM_TYPE_SECTION; Section& sec = sections[(int)symptr->SectionNumber]; if(sec.name_atom != linkjob.ctors_atom && sec.name_atom != linkjob.dtors_atom) { String secn = COFFSymbolName(*symptr, strtbl); sec.name_atom = linkjob.Atomize(secn); secn = TrimClassName(secn); sec.sec_atom = linkjob.Atomize(secn); } linkjob.AddGlobal(sec.name_atom, lsym); const COFF_IMAGE_AUX_SYMBOL *aux = (const COFF_IMAGE_AUX_SYMBOL *)(symptr + 1); if(sec.flags & COFF_IMAGE_SCN_LNK_COMDAT) { sec.comdat_packing = aux->Section.Selection; comdat_assoc.Add(aux->Section.Number, symptr->SectionNumber); // sec.comdat_assoc = aux->Section.Number; if(sec.comdat_packing == COFF_IMAGE_COMDAT_SELECT_EXACT_MATCH) { secptr = sechdr + (symptr->SectionNumber); sec.section_data.Reserve(secptr->SizeOfRawData + secptr->NumberOfRelocations * sizeof(COFF_IMAGE_RELOCATION)); CatN(sec.section_data, secptr->SizeOfRawData, begin + secptr->PointerToRawData); const COFF_IMAGE_RELOCATION *relptr = (const COFF_IMAGE_RELOCATION *)(begin + secptr->PointerToRelocations); const COFF_IMAGE_RELOCATION *relend = relptr + secptr->NumberOfRelocations; while(relptr < relend) { COFF_IMAGE_RELOCATION r = *relptr++; r.SymbolTableIndex = linkjob.NameAtom(symtbl[r.SymbolTableIndex], strtbl); CatN(sec.section_data, sizeof(COFF_IMAGE_RELOCATION), &r); } } } coff_symbols[i] = Symbol(lsym.obj_sec.section, 0); } else if((symptr->StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL || symptr->StorageClass == COFF_IMAGE_SYM_CLASS_STATIC) && (symptr->SectionNumber != 0 || symptr->Value != 0)) { bool glo = (symptr->StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL); LinkJob::Symbol lsym; lsym.obj_sec.object = index; lsym.obj_sec.section = symptr->SectionNumber; lsym.value = symptr->Value; lsym.type = symptr->Type; lsym.external = glo; int atom = linkjob.NameAtom(*symptr, strtbl); linkjob.AddGlobal(atom, lsym); coff_symbols[i] = Symbol(glo ? ~atom : lsym.obj_sec.section, lsym.value); } else if(symptr->StorageClass == COFF_IMAGE_SYM_CLASS_WEAK_EXTERNAL && symptr->NumberOfAuxSymbols >= 1) { int refsym = symptr[1].N.Name.Short; int sym = linkjob.NameAtom(*symptr, strtbl); linkjob.AddWeakExternal(sym, linkjob.NameAtom(symtbl[refsym], strtbl)); coff_symbols[i] = Symbol(~sym, symptr->Value); } else if(symptr->StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL) coff_symbols[i] = Symbol(~linkjob.NameAtom(*symptr, strtbl), 0); else if(symptr->SectionNumber > 0) coff_symbols[i] = Symbol(symptr->SectionNumber, symptr->Value); i += symptr->NumberOfAuxSymbols; symptr += symptr->NumberOfAuxSymbols; } for(i = 1, secptr = sechdr; i < sections.GetCount(); i++, secptr++) { Section& sec = sections[i]; sec.ref_sec_index = ref_sections.GetCount(); sec.ref_ext_index = ref_externals.GetCount(); if(sec.type == SEC_STD) { sec.coff_reloc.SetCount(secptr->NumberOfRelocations); memcpy(sec.coff_reloc.Begin(), (const COFF_IMAGE_RELOCATION *)(begin + secptr->PointerToRelocations), secptr->NumberOfRelocations * sizeof(COFF_IMAGE_RELOCATION)); const COFF_IMAGE_RELOCATION *reloc = sec.coff_reloc.Begin(); Index<int> ref_sec, ref_ext; for(int nreloc = secptr->NumberOfRelocations; --nreloc >= 0; reloc++) { const COFF_IMAGE_SYMBOL& sym = symtbl[reloc->SymbolTableIndex]; if(sym.SectionNumber > 0 && sym.StorageClass != COFF_IMAGE_SYM_CLASS_EXTERNAL) ref_sec.FindAdd(sym.SectionNumber); if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_STATIC && sym.SectionNumber > 0 && sym.Value == 0 && sym.NumberOfAuxSymbols >= 1 && !(sections[sym.SectionNumber].flags & COFF_IMAGE_SCN_LNK_COMDAT)) {} // no-op for section externals else if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL || sym.StorageClass == COFF_IMAGE_SYM_CLASS_WEAK_EXTERNAL || sym.StorageClass == COFF_IMAGE_SYM_CLASS_STATIC) { int atom = linkjob.NameAtom(sym, strtbl); if(sym.SectionNumber == 0) linkjob.AddExternal(atom, ObjSec(index, i)); ref_ext.FindAdd(atom); } /* { LinkJob::Symbol symbol; symbol.object = index; symbol.value = sym.Value; symbol.type = sym.Type; symbol.section = sym.SectionNumber; ref_ext.FindAdd(linkjob.AddGlobal(linkjob.NameAtom(sym, strtbl), symbol)); } */ } ref_sections.AppendPick(ref_sec.PickKeys()); ref_externals.AppendPick(ref_ext.PickKeys()); } /* else if(sec.type == SEC_STAB && stabstr_index >= 0) { ASSERT(sizeof(STAB_INFO) == 12); int count = sec.size / sizeof(STAB_INFO); stabs.SetCount(count); const byte *p = begin + sec.offset; #ifdef CPU_LE // && CPU_32BIT memcpy(stabs.Begin(), p, count * sizeof(STAB_INFO)); #else for(STAB_INFO *sp = stabs.Begin(), *se = stabs.End(); sp < se; sp++, p += 12) { sp->strdx = PeekIL(p + STAB_STRDXOFF); sp->type = p[STAB_TYPEOFF]; sp->other = p[STAB_OTHEROFF]; sp->desc = PeekIW(p[STAB_DESCOFF]); sp->value = PeekIL(p[STAB_VALUEOFF]); } #endif stab_ref.SetCount(count, 0); for(int nreloc = secptr->NumberOfRelocations; --nreloc >= 0; reloc++) { int entry = reloc->VirtualAddress / sizeof(STAB_INFO); if(entry < 0 || entry >= count) continue; const COFF_IMAGE_SYMBOL& sym = symtbl[reloc->SymbolTableIndex]; if(sym.SectionNumber) stab_ref[entry] = ~sym.SectionNumber; else if(sym.StorageClass == COFF_IMAGE_SYM_CLASS_EXTERNAL || sym.StorageClass == COFF_IMAGE_SYM_CLASS_STATIC) stab_ref[entry] = linkjob.NameAtom(sym, strtbl); } if(linkjob.dump_flags & LinkJob::DUMP_STABS) { const Section& strsec = sections[stabstr_index]; puts(NFormat("%s: %d stabs, .stab = %d bytes, .stabstr = %d bytes", ToString(), count, sec.size, strsec.size)); const byte *str = begin + strsec.offset; for(int i = 0; i < stabs.GetCount(); i++) { const STAB_INFO& stab = stabs[i]; String desc; desc << NFormat("[%d]: offset %08x, type %02x, desc %04x, value %08x, reloc %08x", i, stab.strdx, stab.type, stab.desc, stab.value, stab_ref[i]); puts(desc); if(stab.strdx) puts((const char *)(str + stab.strdx)); } } } */ } ref_sections.Shrink(); ref_externals.Shrink(); }
bool Parser::Func() { if (!("function" == lex)) { std::cout << "Function did not start with keyword 'function'\n"; return false; } else { L.getTokLex(tok,lex); } std::string func_name; if (!("identifier" == tok)) { std::cout << "Invalid identifier in parameter list of function\n"; return false; } else { // ident(); func_name = lex; L.getTokLex(tok,lex); } if (!("(" == lex)) { std::cout << "Function parameters missing opening parenthesis\n"; return false; } else { L.getTokLex(tok,lex); } if (!OptParamList()) return false; if (!(")" == lex)) { std::cout << "Function parameters missing closing parenthesis\n"; return false; } else { L.getTokLex(tok,lex); } if (!(":" == lex)) { std::cout << "Function missing colon\n"; return false; } else { L.getTokLex(tok,lex); } if (!Type()) return false; for (int i=0; i < funcs.size(); i++) { if (lex == funcs[i].id) { std::cout << "Error: function '" << lex << "' declared more than once.\n"; return false; } } funcs.push_back(Symbol(f_curr_addr, func_name, curr_type)); ++f_curr_addr; if (!(";" == lex)) { std::cout << "Function type not followed by semicolon\n"; return false; } else { L.getTokLex(tok,lex); } // +++++++++++++++++++++ // If functions actually implemented in working compiler, revise this // to a functionDeclList, or note symbol scope. if (!OptDeclList()) return false; if (!("begin" == lex)) { std::cout << "Function body did not start with keyword 'begin'\n"; return false; } else { L.getTokLex(tok,lex); } // +++++++++++++++++++++ // If functions actually implemented in working compiler, revise this // so that the function address jumps to these statements, // and add a return at function end. if (!OptStmtList()) return false; if (!("end" == lex)) { std::cout << "Function body did not end with keyword 'end'\n"; return false; } else { L.getTokLex(tok,lex); } // std::cout << "Func => function ident (OptParamList):Type; OptDeclList begin OptStmtList end\n"; return true; }
LoopStmt::LoopStmt(statement &body) : body(body) { cond = symb_expr(Symbol("true")); is_tail_cond = false; }
static QList<Symbol> tokenize(const DFA &dfa, const QString &input, Config *cfg, bool *ok = 0) { QList<Symbol> symbols; Symbol lastSymbol; int state = 0; int lastAcceptingState = -1; QString lastAcceptingLexem; int lastAcceptingPos = -1; for (int i = 0; i < input.length(); ++i) { QChar ch = input.at(i); QChar chForInput = ch; if (cfg->caseSensitivity == Qt::CaseInsensitive) chForInput = chForInput.toLower(); int next = dfa.at(state).transitions.value(chForInput.unicode()); if (cfg->debug) qDebug() << "input" << input.at(i) << "leads to state" << next; if (next) { lastSymbol.lexem.append(input.at(i)); lastSymbol.token = dfa.at(next).symbol; if (!lastSymbol.token.isEmpty()) { lastAcceptingState = next; lastAcceptingLexem = lastSymbol.lexem; lastAcceptingPos = i; } state = next; } else { if (lastAcceptingState != -1) { if (cfg->debug) qDebug() << "adding" << dfa.at(lastAcceptingState).symbol << "and backtracking to" << lastAcceptingPos; Symbol s; s.token = dfa.at(lastAcceptingState).symbol; s.lexem = lastAcceptingLexem; symbols << s; lastSymbol = Symbol(); state = 0; i = lastAcceptingPos; lastAcceptingPos = -1; lastAcceptingState = -1; continue; } if (state == 0 || lastSymbol.token.isEmpty()) { if (cfg->debug) qDebug() << "invalid input"; if (ok) *ok = false; return symbols; } if (cfg->debug) qDebug() << "appending symbol with token" << lastSymbol.token; symbols << lastSymbol; lastSymbol = Symbol(); state = 0; lastAcceptingState = -1; --i; } } if (!lastSymbol.token.isEmpty()) { if (cfg->debug) qDebug() << "appending (last) symbol with token" << lastSymbol.token; symbols << lastSymbol; } else if (lastAcceptingState != -1) { if (cfg->debug) qDebug() << "appending last accepting state with token" << dfa.at(lastAcceptingState).symbol; Symbol s; s.lexem = lastAcceptingLexem; s.token = dfa.at(lastAcceptingState).symbol; symbols << s; } if (ok) *ok = true; return symbols; }
int runMoc(int _argc, char **_argv) { bool autoInclude = true; Preprocessor pp; Moc moc; pp.macros["Q_MOC_RUN"]; pp.macros["__cplusplus"]; QByteArray filename; QByteArray output; FILE *in = 0; FILE *out = 0; bool ignoreConflictingOptions = false; QVector<QByteArray> argv; argv.resize(_argc - 1); for (int n = 1; n < _argc; ++n) argv[n - 1] = _argv[n]; int argc = argv.count(); for (int n = 0; n < argv.count(); ++n) { if (argv.at(n).startsWith('@')) { QByteArray optionsFile = argv.at(n); optionsFile.remove(0, 1); if (optionsFile.isEmpty()) error("The @ option requires an input file"); QFile f(QString::fromLatin1(optionsFile.constData())); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) error("Cannot open options file specified with @"); argv.remove(n); while (!f.atEnd()) { QByteArray line = f.readLine().trimmed(); if (!line.isEmpty()) argv.insert(n++, line); } } } // report Qt usage for commercial customers with a "metered license" (currently experimental) #if QT_EDITION != QT_EDITION_OPENSOURCE #ifdef QT_CONFIGURE_BINARIES_PATH const char *binariesPath = QT_CONFIGURE_BINARIES_PATH; QString reporterPath = QString::fromLocal8Bit(binariesPath) + QDir::separator() + QLatin1String("qtusagereporter"); #if defined(Q_OS_WIN) reporterPath += QLatin1String(".exe"); #endif if (QFile::exists(reporterPath)) system(qPrintable(reporterPath + QLatin1String(" moc"))); #endif #endif argc = argv.count(); for (int n = 0; n < argc; ++n) { QByteArray arg(argv[n]); if (arg[0] != '-') { if (filename.isEmpty()) { filename = arg; continue; } error("Too many input files specified"); } QByteArray opt = arg.mid(1); bool more = (opt.size() > 1); switch (opt[0]) { case 'o': // output redirection if (!more) { if (!(n < argc-1)) error("Missing output file name"); output = argv[++n]; } else output = opt.mid(1); break; case 'E': // only preprocessor pp.preprocessOnly = true; break; case 'i': // no #include statement if (more) error(); moc.noInclude = true; autoInclude = false; break; case 'f': // produce #include statement if (ignoreConflictingOptions) break; moc.noInclude = false; autoInclude = false; if (opt[1]) // -fsomething.h moc.includeFiles.append(opt.mid(1)); break; case 'p': // include file path if (ignoreConflictingOptions) break; if (!more) { if (!(n < argc-1)) error("Missing path name for the -p option."); moc.includePath = argv[++n]; } else { moc.includePath = opt.mid(1); } break; case 'I': // produce #include statement if (!more) { if (!(n < argc-1)) error("Missing path name for the -I option."); pp.includes += Preprocessor::IncludePath(argv[++n]); } else { pp.includes += Preprocessor::IncludePath(opt.mid(1)); } break; case 'F': // minimalistic framework support for the mac if (!more) { if (!(n < argc-1)) error("Missing path name for the -F option."); Preprocessor::IncludePath p(argv[++n]); p.isFrameworkPath = true; pp.includes += p; } else { Preprocessor::IncludePath p(opt.mid(1)); p.isFrameworkPath = true; pp.includes += p; } break; case 'D': // define macro { QByteArray name; QByteArray value("1"); if (!more) { if (n < argc-1) name = argv[++n]; } else name = opt.mid(1); int eq = name.indexOf('='); if (eq >= 0) { value = name.mid(eq + 1); name = name.left(eq); } if (name.isEmpty()) error("Missing macro name"); Macro macro; macro.symbols += Symbol(0, PP_IDENTIFIER, value); pp.macros.insert(name, macro); } break; case 'U': { QByteArray macro; if (!more) { if (n < argc-1) macro = argv[++n]; } else macro = opt.mid(1); if (macro.isEmpty()) error("Missing macro name"); pp.macros.remove(macro); } break; case 'v': // version number if (more && opt != "version") error(); fprintf(stderr, "Qt Meta Object Compiler version %d (Qt %s)\n", mocOutputRevision, QT_VERSION_STR); return 1; case 'n': // don't display warnings if (ignoreConflictingOptions) break; if (opt != "nw") error(); moc.displayWarnings = false; break; case 'h': // help if (more && opt != "help") error(); else error(0); // 0 means usage only break; case '-': if (more && arg == "--ignore-option-clashes") { // -- ignore all following moc specific options that conflict // with for example gcc, like -pthread conflicting with moc's // -p option. ignoreConflictingOptions = true; break; } // fall through default: error(); } } if (autoInclude) { int ppos = filename.lastIndexOf('.'); moc.noInclude = (ppos >= 0 && tolower(filename[ppos + 1]) != 'h' && tolower(filename[ppos + 1]) != QDir::separator().toLatin1() ); } if (moc.includeFiles.isEmpty()) { if (moc.includePath.isEmpty()) { if (filename.size()) { if (output.size()) moc.includeFiles.append(combinePath(filename, output)); else moc.includeFiles.append(filename); } } else { moc.includeFiles.append(combinePath(filename, filename)); } } if (filename.isEmpty()) { filename = "standard input"; in = stdin; } else { #if defined(_MSC_VER) && _MSC_VER >= 1400 if (fopen_s(&in, filename.data(), "rb")) { #else in = fopen(filename.data(), "rb"); if (!in) { #endif fprintf(stderr, "moc: %s: No such file\n", (const char*)filename); return 1; } moc.filename = filename; } moc.currentFilenames.push(filename); // 1. preprocess moc.symbols = pp.preprocessed(moc.filename, in); fclose(in); if (!pp.preprocessOnly) { // 2. parse moc.parse(); } // 3. and output meta object code if (output.size()) { // output file specified #if defined(_MSC_VER) && _MSC_VER >= 1400 if (fopen_s(&out, output.data(), "w")) #else out = fopen(output.data(), "w"); // create output file if (!out) #endif { fprintf(stderr, "moc: Cannot create %s\n", (const char*)output); return 1; } } else { // use stdout out = stdout; } if (pp.preprocessOnly) { fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData()); } else { if (moc.classList.isEmpty()) moc.warning("No relevant classes found. No output generated."); else moc.generate(out); } if (output.size()) fclose(out); return 0; } QT_END_NAMESPACE int main(int _argc, char **_argv) { return QT_PREPEND_NAMESPACE(runMoc)(_argc, _argv); }
inline Symbol Symbol::LoadJSON(const std::string &json_str) { op_map(); SymbolHandle handle; CHECK_EQ(MXSymbolCreateFromJSON(json_str.c_str(), &(handle)), 0); return Symbol(handle); }
inline Symbol Symbol::GetInternals() const { SymbolHandle handle; CHECK_EQ(MXSymbolGetInternals(GetHandle(), &handle), 0); return Symbol(handle); }
MeshGenerator::MeshGenerator() { add(Symbol('F').action(forward_draw)); add(Symbol('G').action(forward_draw)); add(Symbol('g').action(forward_radius)); add(Symbol('T').action(tropism)); add(Symbol('f').action(forward)); add(Symbol('+').action(turn_left)); add(Symbol('-').action(turn_right)); add(Symbol('&').action(pitch_down)); add(Symbol('^').action(pitch_up)); add(Symbol('\\').action(roll_left)); add(Symbol('/').action(roll_right)); add(Symbol('|').action(turn_around)); add(Symbol('!').action(decrease_diameter)); add(Symbol('@').action(decrease_length)); add(Symbol('#').action(increase_length)); add(Symbol('\'').action(next_color)); add(Symbol('`').action(previous_color)); add(Symbol('"').action(next_color_series)); add(Symbol('[').startsGroup()); add(Symbol(']').endsGroup()); add(Symbol('{').startsGroup().action(begin_polygon)); add(Symbol('}').endsGroup().action(end_polygon)); }
Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std::string outputNameIn, bool only_parseIn) { only_parse = only_parseIn; //constructor outputName = outputNameIn; if (!only_parse) { if (mkdir(("./" + outputName).c_str(), 0755)) { //std::cerr << "\n\n =====IMPORTER===== \n\n" << std::endl; //std::cerr << "Could not make directory " << outputName << std::endl; } } parser = parserIn; this->includePaths = includePaths; ASTTransformer = new ASTTransformation(this); removeSymbols.push_back(Symbol("$NULL$", true)); removeSymbols.push_back(Symbol("WS", false)); removeSymbols.push_back(Symbol("\\(", true)); removeSymbols.push_back(Symbol("\\)", true)); removeSymbols.push_back(Symbol("var", true)); removeSymbols.push_back(Symbol("fun", true)); removeSymbols.push_back(Symbol(";", true)); removeSymbols.push_back(Symbol("line_end", false)); removeSymbols.push_back(Symbol("{", true)); removeSymbols.push_back(Symbol("}", true)); removeSymbols.push_back(Symbol("(", true)); removeSymbols.push_back(Symbol(")", true)); //removeSymbols.push_back(Symbol("import", true)); removeSymbols.push_back(Symbol("if", true)); removeSymbols.push_back(Symbol("while", true)); removeSymbols.push_back(Symbol("__if_comp__", true)); //removeSymbols.push_back(Symbol("simple_passthrough", true)); removeSymbols.push_back(Symbol("comp_simple_passthrough", true)); removeSymbols.push_back(Symbol("def_nonterm", false)); removeSymbols.push_back(Symbol("obj_nonterm", false)); removeSymbols.push_back(Symbol("adt_nonterm", false)); removeSymbols.push_back(Symbol("template", true)); removeSymbols.push_back(Symbol("\\|", true)); //removeSymbols.push_back(Symbol("match", true)); collapseSymbols.push_back(Symbol("case_statement_list", false)); collapseSymbols.push_back(Symbol("opt_param_assign_list", false)); collapseSymbols.push_back(Symbol("param_assign_list", false)); collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false)); collapseSymbols.push_back(Symbol("opt_parameter_list", false)); collapseSymbols.push_back(Symbol("identifier_list", false)); collapseSymbols.push_back(Symbol("adt_option_list", false)); collapseSymbols.push_back(Symbol("statement_list", false)); collapseSymbols.push_back(Symbol("parameter_list", false)); collapseSymbols.push_back(Symbol("typed_parameter_list", false)); collapseSymbols.push_back(Symbol("unorderd_list_part", false)); collapseSymbols.push_back(Symbol("if_comp_pred", false)); collapseSymbols.push_back(Symbol("declaration_block", false)); collapseSymbols.push_back(Symbol("type_list", false)); collapseSymbols.push_back(Symbol("opt_type_list", false)); collapseSymbols.push_back(Symbol("template_param_list", false)); collapseSymbols.push_back(Symbol("trait_list", false)); collapseSymbols.push_back(Symbol("dec_type", false)); //collapseSymbols.push_back(Symbol("pre_reffed", false)); }
Symbol Player::symbol () { return Symbol(Black,White,"@"); }
//========================================================================================================== // Create a DFA from an NFA using the Subset-Construction algorithm //========================================================================================================== void DFA::nfa_to_dfa(NFA& nfa) { vector<set<int>> epsilon_closures; // Epsilon closures per NFA state //------------------------------------------------------------------------------------------------------ // Calculate epsilon-closures for each state in the NFA //------------------------------------------------------------------------------------------------------ for(int i = 0; i < nfa.get_num_states(); ++i) { epsilon_closures.push_back(calc_epsilon_closure(i, nfa)); } // Map between DFA state, and a set of NFA states it was constructed from (the index in the vector is the DFA state) vector<set<int>> nfa_states; nfa_states.push_back(epsilon_closures[0]); // Initial, starting state table.push_back(vector<int>(NUM_SYMBOLS, -1)); // Adding the start state //------------------------------------------------------------------------------------------------------ // As long as there are new states in the DFA, calcuate the transitions for them, while creating new // states if needed //------------------------------------------------------------------------------------------------------ for(int i = 0; i < table.size(); ++i) { for(int sym = 0; sym < NUM_SYMBOLS; ++sym) { // For each possible symbol //---------------------------------------------------------------------------------------------- // Get the set of reachable NFA states from the current DFA state for the current symbol //---------------------------------------------------------------------------------------------- set<int> reachable_set = nfa.get_rechable_set(nfa_states[i], Symbol(sym)); for(auto& s: reachable_set) { // Add the epsilon-closure reachable_set.insert(epsilon_closures[s].begin(), epsilon_closures[s].end()); } if(reachable_set.empty()) continue; //---------------------------------------------------------------------------------------------- // Check if this set already exists as a DFA state //---------------------------------------------------------------------------------------------- int state = table.size(); for(int j = 0; j < nfa_states.size(); ++j) { if(reachable_set == nfa_states[j]) { state = j; break; } } table[i][sym] = state; // Add this transition if(state == table.size()) { // New state nfa_states.push_back(reachable_set); table.push_back(vector<int>(NUM_SYMBOLS, -1)); } } // for each symbol } // for each new state //------------------------------------------------------------------------------------------------------ // Mark a state as accepting if any of the NFA states corresponding to it are accepting //------------------------------------------------------------------------------------------------------ accepting.resize(get_num_states(), -1); for(int i = 0; i < nfa_states.size(); ++i) { for(auto s: nfa_states[i]) { if(nfa.accepting[s] >= 0) { if(accepting[i] >= 0) throw string("DFA state contain accepting NFA states with different production rules"); accepting[i] = nfa.accepting[s]; break; } } } } // nfa_to_dfa()
Enum::Enum(string s) { symbols.push_back(Symbol(s)); }
/** * Captures the current stack and updates stack tracking information. * optionally stores a user data pointer that the tracker will take ownership of and delete upon reset * you must allocate the memory with FMemory::Malloc() */ void FStackTracker::CaptureStackTrace(int32 EntriesToIgnore, void* UserData, int32 StackLen, bool bLookupStringsForAliasRemoval) { // Avoid re-rentrancy as the code uses TArray/TMap. if( !bAvoidCapturing && bIsEnabled ) { // Scoped true/ false. bAvoidCapturing = true; // Capture callstack and create CRC. int32 Size = (MAX_BACKTRACE_DEPTH + EntriesToIgnore) * sizeof(uint64); uint64* FullBackTrace = static_cast<uint64*>(FMemory_Alloca(Size)); FMemory::Memzero(FullBackTrace, Size); FPlatformStackWalk::CaptureStackBackTrace( FullBackTrace, MAX_BACKTRACE_DEPTH + EntriesToIgnore ); CA_ASSUME(FullBackTrace); // Skip first NUM_ENTRIES_TO_SKIP entries as they are inside this code uint64* BackTrace = &FullBackTrace[EntriesToIgnore]; if (StackLen < MAX_BACKTRACE_DEPTH) { FMemory::Memzero(BackTrace + StackLen, sizeof(uint64) * (MAX_BACKTRACE_DEPTH - StackLen)); } if (bLookupStringsForAliasRemoval) { for (int32 Index = 0; Index < StackLen; Index++) { if (BackTrace[Index]) { uint64* Existing = AliasMap.Find(BackTrace[Index]); if (Existing) { BackTrace[Index] = *Existing; } else { ANSICHAR AddressInformation[512]; AddressInformation[0] = 0; FPlatformStackWalk::ProgramCounterToHumanReadableString( 1, BackTrace[Index], AddressInformation, ARRAY_COUNT(AddressInformation)-1 ); FString Symbol(AddressInformation); int32 Spot = Symbol.Find(TEXT(" - ")); if (Spot != INDEX_NONE) { Symbol = Symbol.RightChop(Spot + 3); } Existing = StringAliasMap.Find(Symbol); if (Existing) { AliasMap.Add(BackTrace[Index], *Existing); BackTrace[Index] = *Existing; } else { AliasMap.Add(BackTrace[Index], BackTrace[Index]); StringAliasMap.Add(Symbol, BackTrace[Index]); } } } } } uint32 CRC = FCrc::MemCrc_DEPRECATED( BackTrace, MAX_BACKTRACE_DEPTH * sizeof(uint64) ); // Use index if found int32* IndexPtr = CRCToCallStackIndexMap.Find( CRC ); if( IndexPtr ) { // Increase stack count for existing callstack. CallStacks[*IndexPtr].StackCount++; if (UpdateFn) { UpdateFn(CallStacks[*IndexPtr], UserData); } //We can delete this since the user gives ownership at the beginning of this call //and had a chance to update their data inside the above callback if (UserData) { FMemory::Free(UserData); } } // Encountered new call stack, add to array and set index mapping. else { // Add to array and set mapping for future use. int32 Index = CallStacks.AddUninitialized(); CRCToCallStackIndexMap.Add( CRC, Index ); // Fill in callstack and count. FCallStack& CallStack = CallStacks[Index]; FMemory::Memcpy( CallStack.Addresses, BackTrace, sizeof(uint64) * MAX_BACKTRACE_DEPTH ); CallStack.StackCount = 1; CallStack.UserData = UserData; } // We're done capturing. bAvoidCapturing = false; } }
inline Symbol Symbol::Copy() const { SymbolHandle handle; CHECK_EQ(MXSymbolCopy(GetHandle(), &handle), 0); return Symbol(handle); }
static _finline void cyset(Type_ &function, const char *name, const mach_header_xx *mach) { function = reinterpret_cast<Type_>(Symbol(mach, name)); }
inline Symbol Symbol::Variable(const std::string &name) { return Symbol(name); }
symbol_t readSym(){ char *s, tch; symtype_t i; while(isBlank())nextchar(); if(isAlpha()){ s = ccstring(); s = ccstrcat(s,ch); nextchar(); while(isAlpha() || isDigital()){ s = ccstrcat(s,ch); nextchar(); } for(i = CONST; i<=RETURN; i ++) if(ccstrcmp(s,keywords[i-1])==0){ return Symbol(i, 0); } return Symbol(ID, (int)s); }else if(isDigital()){ return readNumLit(0); }else if(ch=='\''){ nextchar(); if(isAlpha() || isDigital() || ch=='+' || ch=='-' || ch=='*' || ch=='/'){ tch = ch; nextchar(); if(ch=='\''){ nextchar(); return Symbol(CHARLIT, (int)tch); } } msg(ERR, "a wrong char literal",lineno+1); }else if(ch=='\"'){ nextchar(); s = ccstring(); while(ch!='\"' && ch!=EOF){ s = ccstrcat(s, ch); nextchar(); } if(ch!=EOF){ nextchar(); return Symbol(STRLIT, (int)s); } msg(ERR, "a wrong string literal",lineno+1); }else if(ch=='+'){ nextchar(); //if(isDigital()) // return readNumLit(0); //else return Symbol(PLUS, 0); }else if(ch=='-'){ nextchar(); //if(isDigital()) // return readNumLit(1); //else return Symbol(MINUS, 0); }else if(ch=='*'){ nextchar(); return Symbol(MULTI, 0); }else if(ch=='/'){ nextchar(); return Symbol(DIVIDE, 0); }else if(ch=='<'){ nextchar(); if(ch=='='){ nextchar(); return Symbol(LEQU, 0); }else return Symbol(LESS, 0); }else if(ch=='>'){ nextchar(); if(ch=='='){ nextchar(); return Symbol(GEQU, 0); }else return Symbol(GREATER, 0); }else if(ch=='!'){ nextchar(); if(ch=='='){ nextchar(); return Symbol(UNEQU, 0); } msg(ERR, "unexpected char \'!\'",lineno+1); }else if(ch=='='){ nextchar(); if(ch=='='){ nextchar(); return Symbol(EQU, 0); }else return Symbol(ASN, 0); }else if(ch=='('){ nextchar(); return Symbol(LPAREN, 0); }else if(ch==')'){ nextchar(); return Symbol(RPAREN, 0); }else if(ch=='{'){ nextchar(); return Symbol(LBRACE, 0); }else if(ch=='}'){ nextchar(); return Symbol(RBRACE, 0); }else if(ch==';'){ nextchar(); return Symbol(SEMIC, 0); }else if(ch==':'){ nextchar(); return Symbol(COLON, 0); }else if(ch==','){ nextchar(); return Symbol(COMMA, 0); }else if(ch==EOF){ return Symbol(SEOF, 0); } msg(ERR, "unknown lexer error",lineno+1); return 0; }
inline Symbol Symbol::operator[](int index) { SymbolHandle out; MXSymbolGetOutput(GetHandle(), index, &out); return Symbol(out); }
obj eval(obj exp){ ev: assert(!! exp); obj rr,lt, rt; switch (exp->type) { case tInd: return doInd(eval(ult(exp)), ul(eval(urt(exp)))); case LIST: return List2v(evalList(ul(exp))); case tArray: return map_obj(eval, exp); case tAnd: return prod_eval(ul(exp), mult); case MULT: return prod_eval(ul(exp), mult); case ARITH: return prod_eval(ul(exp), add); case POW: return prod_eval(ul(exp), power); case DIVIDE: return prod_eval(ul(exp), divide); case tRef: return retain(uref(exp)); case tSymbol: if( macromode) { if(obj rr = search_assoc(car(macro_env), exp)){ macromode = false; // macro lexical scope should be pushed to the stack here rr = exec(rr); macromode = true; return rr; } } return eval_symbol(exp); case tMinus: lt = eval(uref(exp)); rr = uMinus(lt); // releasing if(rr) {release(lt); return rr;} static obj symumn = Symbol("-"); rr = udef_op0(symumn, lt); if(rr) {release(lt); return rr;} error("uMinus: not defined to that type"); case tReturn: if(! uref(exp)) return encap(tSigRet, nil); return encap(tSigRet, eval(uref(exp))); case tBreak: return retain(exp); case CONDITION: return evalCond(exp); case tOp: if(type(ult(exp)) ==tSymbol) { lt = search_assoc(curr_interp->types, ult(exp)); if(lt) return encap((ValueType)vrInt(lt), eval(urt(exp)));} lt = eval(ult(exp)); push(lt); switch(lt->type){ case tCont: assert(0); case tSpecial: rr = ufn(lt)(urt(exp)); break; case tSyntaxLam: rr = macro_exec(lt, urt(exp)); break; case tInternalFn: case tClosure: rt = eval(urt(exp)); rr = eval_function(lt, rt); break; default: rt = eval(urt(exp)); rr = call_fn(mult, lt, rt); release(rt); } release(pop(&is)); return rr; case tClosure: assert(0); case tCurry: return eval_curry(exp, em0(exp)); /* obj vars = Assoc(); bind_vars(&vars, em0(exp), em2(exp)); rr = eval_curry(exp, vars); release(vars); return rr; */ case tArrow: // return enclose(exp); /* if(macromode){ if(obj rr = search_assoc(car(macro_env), exp)){ } } */ return render(tClosure, list3(retain(em0(exp)), retain(em1(exp)), retain(env))); case tDefine: return func_def(em0(exp), em1(exp), em2(exp)); case tSyntaxDef: let(lfind_var(em0(exp)), render(tSyntaxLam, list3(retain(em1(exp)), retain(em2(exp)), nil))); return nil; case tExec: return exec(exp); case tAssign: lt = car(exp); if(type(lt)==tOp){ return func_def(ult(lt), urt(lt), cdr(exp)); } else if(type(lt)==tMinus){ static obj symumn = Symbol("-"); return func_def(symumn, uref(lt), cdr(exp)); } else return do_assign(lt, eval(cdr(exp))); case tIf: rr = eval(em0(exp)); if (type(rr) != INT) error("if: Boolean Expected"); if (vrInt(rr)) { rr = em1(exp); } else { rr = em2(exp); } return eval(rr); case tWhile: for(;;) { rr = eval(car(exp)); if (type(rr) != INT) error("while: Boolean expected"); if(!vrInt(rr)) break; rr = exec(cdr(exp)); if(rr && type(rr)==tSigRet) return rr; if(rr && type(rr)==tBreak) {release(rr); break;} if(rr) release(rr); } return nil; default: return retain(exp); } }
inline Symbol Symbol::Load(const std::string &file_name) { op_map(); SymbolHandle handle; CHECK_EQ(MXSymbolCreateFromFile(file_name.c_str(), &(handle)), 0); return Symbol(handle); }
ListExpr map_stream_result_type( ListExpr args, Tuple**, OP* ) { return list_ostream() << Symbol("tuple") << OP::type( args ); }
void Semantic::traverse(Stmt * cur) { if (cur->v == Stmt::LIST_T) { pushScope(); traverse(cur->list); popScope(); } else if (cur->v == Stmt::IF_T || cur->v == Stmt::WHILE_T) { if (cur->v == Stmt::WHILE_T) loops.push(cur); Type t = expType(cur->exp); traverse(cur->exp); if (t.v == Type::INT_T || t.v == Type::CHAR_T) { //warning pushScope(); traverse(cur->left); popScope(); } else if (t.v == Type::BOOL_T) { pushScope(); traverse(cur->left); popScope(); } else error("Condition must be of type bool"); if (cur->v == Stmt::WHILE_T) loops.pop(); } else if (cur->v == Stmt::FOR_T) { loops.push(cur); pushScope(); traverse(cur->left); Type t = expType(cur->exp); traverse(cur->exp); if (t.v == Type::INT_T || t.v == Type::CHAR_T) { //warning pushScope(); traverse(cur->stmt); popScope(); } else if (t.v == Type::BOOL_T) { pushScope(); traverse(cur->stmt); popScope(); } else error("Condition must be of type bool"); if (hasDecl(cur->right)) error("For loop-end statement must not include declarations"); traverse(cur->right); popScope(); loops.pop(); } else if (cur->v == Stmt::RETURN_T) { //check current function return type and compare it with this if (!sameType(expType(cur->exp), *getSym(curF).defn->type)) error("return expression type differs from function " + curF + " signature"); if (cur->exp != NULL) traverse(cur->exp); } else if (cur->v == Stmt::ASSERT_T) { //check argument type to be of bool if (!sameType(expType(cur->exp), Type(Type::BOOL_T))) error("assert expression type must be bool"); traverse(cur->exp); } else if (cur->v == Stmt::ERROR_T) { //call error function with argment string if (!sameType(expType(cur->exp), Type(Type::STRING_T))) error("error argument must be of type string"); traverse(cur->exp); } else if (cur->v == Stmt::ASSIGN_T) { //check if lhs and rhs same type, ensure rhs and lhs is not a struct Type l = lvalType(cur->lval), r = expType(cur->exp); traverse(cur->exp); if (cur->op == "=") { if (!sameType(l, r)) error("lval and expression have different types"); } else if (cur->op == ">>=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from right shift must be of type int or char"); if (!sameType(r, Type(Type::INT_T))) error("shift ammount must be of type int"); } else if (cur->op == "<<=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from left shift must be of type int or char"); if (!sameType(r, Type(Type::INT_T))) error("shift ammount must be of type int"); } else if (cur->op == "+=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from add assign must be of type int or char"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)))) error("expression from add assign must be of type int or char"); } else if (cur->op == "-=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from sub assign must be of type int or char"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)))) error("expression from sub assign must be of type int or char"); } else if (cur->op == "*=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from mul assign must be of type int or char"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)))) error("expression from mul assign must be of type int or char"); } else if (cur->op == "/=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from div assign must be of type int or char"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)))) error("expression from div assign must be of type int or char"); } else if (cur->op == "%=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from mod assign must be of type int or char"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)))) error("expression from mod assign must be of type int or char"); } else if (cur->op == "&=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)) || sameType(l, Type(Type::BOOL_T)))) error("lval from and assign must be of type int or char or bool"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)) || sameType(r, Type(Type::BOOL_T)))) error("expression from and assign must be of type int or char or bool"); } else if (cur->op == "^=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)) || sameType(l, Type(Type::BOOL_T)))) error("lval from xor assign must be of type int or char or bool"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)) || sameType(r, Type(Type::BOOL_T)))) error("expression from xor assign must be of type int or char or bool"); } else if (cur->op == "|=") { if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)) || sameType(l, Type(Type::BOOL_T)))) error("lval from or assign must be of type int or char or bool"); if (!(sameType(r, Type(Type::INT_T)) || sameType(r, Type(Type::CHAR_T)) || sameType(r, Type(Type::BOOL_T)))) error("expression from or assign must be of type int or char or bool"); } } else if (cur->v == Stmt::INC_T) { //check if lhs is int or char Type l = lvalType(cur->lval); if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from increment must be of type int or char"); } else if (cur->v == Stmt::DEC_T) { //check if lhs is int or char Type l = lvalType(cur->lval); if (!(sameType(l, Type(Type::INT_T)) || sameType(l, Type(Type::CHAR_T)))) error("lval from decrement must be of type int or char"); } else if (cur->v == Stmt::EXP_T) { traverse(cur->exp); } else if (cur->v == Stmt::DECL_T) { //declaring a variable newSym(vid.back(), Symbol(cur->arg->ID, cur->arg->type)); } else if (cur->v == Stmt::DECLI_T) { //declaring and assigning a variable newSym(vid.back(), Symbol(cur->arg->ID, cur->arg->type)); } else if (cur->v == Stmt::BREAK_T) { //check most recent loop if (loops.empty()) error("break statement does not have a loop"); } else if (cur->v == Stmt::CONT_T) { if (loops.empty()) error("continue statement does not have a loop"); } }