// Preprocess input containing functions // // localExterns is a map of the form, eg, // // { x: { foo: 0, bar: 1, baz: 2 }, y: { qux: 0, foo: 1 } ... } // // localExternSigs is a map of the form, eg, // // { x : { foo: iii, bar: iis, baz: ia }, y: { qux: i, foo: as } ... } // // Signifying that x.foo = 0, x.baz = 2, y.foo = 1, etc // and that x.foo has three integers as arguments, x.bar has two // integers and a variable-length string, and baz has an integer // and an array // // globalExterns is a one-level map, eg from above // // { foo: 1, bar: 1, baz: 2, qux: 0 } // // globalExternSigs is a one-level map, eg from above // // { foo: as, bar: iis, baz: ia, qux: i} // // Note that globalExterns and globalExternSigs may be ambiguous // Also, a null signature implies an infinite tail of integers preprocessResult preprocessInit(Node inp) { Metadata m = inp.metadata; if (inp.val != "seq") inp = astnode("seq", inp, m); std::vector<Node> empty = std::vector<Node>(); Node init = astnode("seq", empty, m); Node shared = astnode("seq", empty, m); std::vector<Node> any; std::vector<Node> functions; preprocessAux out = preprocessAux(); out.localExterns["self"] = std::map<std::string, int>(); int functionCount = 0; int storageDataCount = 0; for (unsigned i = 0; i < inp.args.size(); i++) { Node obj = inp.args[i]; // Functions if (obj.val == "def") { if (obj.args.size() == 0) err("Empty def", m); std::string funName = obj.args[0].val; // Init, shared and any are special functions if (funName == "init" || funName == "shared" || funName == "any") { if (obj.args[0].args.size()) err(funName+" cannot have arguments", m); } if (funName == "init") init = obj.args[1]; else if (funName == "shared") shared = obj.args[1]; else if (funName == "any") any.push_back(obj.args[1]); else { // Other functions functions.push_back(convFunction(obj, functionCount)); out.localExterns["self"][obj.args[0].val] = functionCount; out.localExternSigs["self"][obj.args[0].val] = getSignature(obj.args[0].args); functionCount++; } } // Extern declarations else if (obj.val == "extern") { std::string externName = obj.args[0].val; Node al = obj.args[1]; if (!out.localExterns.count(externName)) out.localExterns[externName] = std::map<std::string, int>(); for (unsigned i = 0; i < al.args.size(); i++) { if (al.args[i].val == ":") { std::string v = al.args[i].args[0].val; std::string sig = al.args[i].args[1].val; out.globalExterns[v] = i; out.globalExternSigs[v] = sig; out.localExterns[externName][v] = i; out.localExternSigs[externName][v] = sig; } else { std::string v = al.args[i].val; out.globalExterns[v] = i; out.globalExternSigs[v] = ""; out.localExterns[externName][v] = i; out.localExternSigs[externName][v] = ""; } } } // Custom macros else if (obj.val == "macro" || (obj.val == "fun" && obj.args[0].val == "macro")) { // Rules for valid macros: // // There are only four categories of valid macros: // // 1. a macro where the outer function is something // which is NOT an existing valid function/extern/datum // 2. a macro of the form set(c(x), d) where c must NOT // be an existing valid function/extern/datum // 3. something of the form access(c(x)), where c must NOT // be an existing valid function/extern/datum // 4. something of the form set(access(c(x)), d) where c must // NOT be an existing valid function/extern/datum // 5. something of the form with(c(x), d, e) where c must // NOT be an existing valid function/extern/datum bool valid = false; Node pattern; Node substitution; int priority; // Priority not set: default zero if (obj.val == "macro") { pattern = obj.args[0]; substitution = obj.args[1]; priority = 0; } // Specified priority else { pattern = obj.args[1]; substitution = obj.args[2]; if (obj.args[0].args.size()) priority = dtu(obj.args[0].args[0].val); else priority = 0; } if (opcode(pattern.val) < 0 && !isValidFunctionName(pattern.val)) valid = true; if (pattern.val == "set" && opcode(pattern.args[0].val) < 0 && !isValidFunctionName(pattern.args[0].val)) valid = true; if (pattern.val == "access" && opcode(pattern.args[0].val) < 0 && !isValidFunctionName(pattern.args[0].val)) if (pattern.val == "set" && pattern.args[0].val == "access" && opcode(pattern.args[0].args[0].val) < 0 && !isValidFunctionName(pattern.args[0].args[0].val)) valid = true; if (pattern.val == "with" && opcode(pattern.args[0].val) < 0 && !isValidFunctionName(pattern.args[0].val)) valid = true; if (valid) { if (!out.customMacros.count(priority)) out.customMacros[priority] = rewriteRuleSet(); out.customMacros[priority].addRule (rewriteRule(pattern, substitution)); } else warn("Macro does not fit valid template: "+printSimple(pattern), m); } // Variable types else if (obj.val == "type") { std::string typeName = obj.args[0].val; std::vector<Node> vars = obj.args[1].args; for (unsigned i = 0; i < vars.size(); i++) out.types[vars[i].val] = typeName; } // Storage variables/structures else if (obj.val == "data") { out.storageVars = getStorageVars(out.storageVars, obj.args[0], "", storageDataCount); storageDataCount += 1; } else any.push_back(obj); } // Set up top-level AST structure std::vector<Node> main; if (shared.args.size()) main.push_back(shared); if (init.args.size()) main.push_back(init); std::vector<Node> code; if (shared.args.size()) code.push_back(shared); for (unsigned i = 0; i < any.size(); i++) code.push_back(any[i]); for (unsigned i = 0; i < functions.size(); i++) code.push_back(functions[i]); Node codeNode; if (functions.size() > 0) { codeNode = astnode("with", token("__funid", m), astnode("byte", token("0", m), astnode("calldataload", token("0", m), m), m), astnode("seq", code, m), m); } else codeNode = astnode("seq", code, m); main.push_back(astnode("~return", token("0", m), astnode("lll", codeNode, token("0", m), m), m)); Node result; if (main.size() == 1) result = main[0]; else result = astnode("seq", main, inp.metadata); return preprocessResult(result, out); }
void modCalcEquinox::processLines( QTextStream &istream ) { // we open the output file // QTextStream istream(&fIn); QString outputFileName; outputFileName = OutputLineEditBatch->text(); QFile fOut( outputFileName ); fOut.open(IO_WriteOnly); QTextStream ostream(&fOut); QString line; QString space = " "; int yearB; int i = 0; long double jdsp = 0., jdsu = 0., jdau = 0., jdwin = 0., jdsp1 = 0.; KStarsData *kd = (KStarsData*) parent()->parent()->parent(); KSSun *Sun = new KSSun(kd); while ( ! istream.eof() ) { line = istream.readLine(); line.stripWhiteSpace(); //Go through the line, looking for parameters QStringList fields = QStringList::split( " ", line ); i = 0; // Read year and write in ostream if corresponds if(yearCheckBatch->isChecked() ) { yearB = fields[i].toInt(); i++; } else yearB = yearEditBatch->text().toInt(); if ( allRadioBatch->isChecked() ) ostream << yearB << space; else if(yearCheckBatch->isChecked() ) ostream << yearB << space; jdsp = Sun->springEquinox(yearB); jdsu = Sun->summerSolstice(yearB); jdau = Sun->autumnEquinox(yearB); jdwin = Sun->winterSolstice(yearB); jdsp1 = Sun->springEquinox(yearB+1); KStarsDateTime dts( jdsp ); KStarsDateTime dtu( jdsu ); KStarsDateTime dta( jdau ); KStarsDateTime dtw( jdwin ); ostream << dts.toString(Qt::ISODate) << space << (float)(jdsu - jdsp) << space << dtu.toString(Qt::ISODate) << space << (float)(jdau - jdsu) << space << dta.toString(Qt::ISODate) << space << (float)(jdwin - jdau) << space << dtw.toString(Qt::ISODate) << space << (float)(jdsp1 - jdwin) << endl; } fOut.close(); }