/** ** GM: SKILL <unit> <skill> <tage> ** requires: permission-key "gmskil" **/ static void gm_skill(const void *tnext, struct unit *u, struct order *ord) { unit *to = findunit(getid()); skill_t skill = findskill(getstrtoken(), u->faction->locale); int num = getint(); if (to == NULL || rplane(to->region) != rplane(u->region)) { /* unknown or in another plane */ ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); } else if (skill == NOSKILL || skill == SK_MAGIC || skill == SK_ALCHEMY) { /* unknown or not enough */ mistake(u, ord, "unknown skill, or skill cannot be raised."); } else if (num < 0 || num > 30) { /* sanity check failed */ mistake(u, ord, "invalid value."); } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmskil"))) { mistake(u, ord, "permission denied."); } else { set_level(to, skill, num); } } }
/** ** GM: TELL <unit> <string> ** requires: permission-key "gmmsgr" **/ static void gm_messageunit(const void *tnext, struct unit *u, struct order *ord) { const struct plane *p = rplane(u->region); unit *target = findunit(getid()); const char *msg = getstrtoken(); region *r; if (target == NULL) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); return; } r = target->region; if (r == NULL || p != rplane(r)) { mistake(u, ord, "region is in another plane."); } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmmsgu"))) { mistake(u, ord, "permission denied."); } else { add_message(&target->faction->msgs, msg_message("regionmessage", "region sender string", r, u, msg)); } } }
/** ** GM: TAKE <unit> <int> <itemtype> ** requires: permission-key "gmtake" **/ static void gm_take(const void *tnext, struct unit *u, struct order *ord) { unit *to = findunit(getid()); int num = getint(); const item_type *itype = finditemtype(getstrtoken(), u->faction->locale); if (to == NULL || rplane(to->region) != rplane(u->region)) { /* unknown or in another plane */ ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); } else if (itype == NULL || i_get(to->items, itype) == 0) { /* unknown or not enough */ mistake(u, ord, "invalid item or item not found."); } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmtake"))) { mistake(u, ord, "permission denied."); } else { int i = i_get(to->items, itype); if (i < num) num = i; if (num) { i_change(&to->items, itype, -num); i_change(&u->items, itype, num); } } } }
static void gm_messagefaction(const void *tnext, struct unit *gm, struct order *ord) { int n = getid(); faction *f = findfaction(n); const char *msg = getstrtoken(); plane *p = rplane(gm->region); attrib *permissions = a_find(gm->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmmsgr"))) { mistake(gm, ord, "permission denied."); return; } if (f != NULL) { region *r; for (r = regions; r; r = r->next) if (rplane(r) == p) { unit *u; for (u = r->units; u; u = u->next) if (u->faction == f) { add_message(&f->msgs, msg_message("msg_event", "string", msg)); return; } } } mistake(gm, ord, "cannot send messages to this faction."); }
/** ** GM: KILL FACTION <id> <string> ** requires: permission-key "gmmsgr" **/ static void gm_killfaction(const void *tnext, struct unit *u, struct order *ord) { int n = getid(); faction *f = findfaction(n); const char *msg = getstrtoken(); plane *p = rplane(u->region); attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmkill"))) { mistake(u, ord, "permission denied."); return; } if (f != NULL) { region *r; for (r = regions; r; r = r->next) if (rplane(r) == p) { unit *target; for (target = r->units; target; target = target->next) { if (target->faction == f) { scale_number(target, 0); ADDMSG(&target->faction->msgs, msg_message("killedbygm", "region unit string", r, target, msg)); return; } } } } mistake(u, ord, "cannot remove a unit from this faction."); }
/** ** GM: TELL PLANE <string> ** requires: permission-key "gmmsgr" **/ static void gm_messageplane(const void *tnext, struct unit *gm, struct order *ord) { const struct plane *p = rplane(gm->region); const char *zmsg = getstrtoken(); if (p == NULL) { mistake(gm, ord, "In diese Ebene kann keine Nachricht gesandt werden."); } else { /* checking permissions */ attrib *permissions = a_find(gm->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmmsgr"))) { mistake(gm, ord, "permission denied."); } else { message *msg = msg_message("msg_event", "string", zmsg); faction *f; region *r; for (f = factions; f; f = f->next) { freset(f, FFL_SELECT); } for (r = regions; r; r = r->next) { unit *u; if (rplane(r) != p) continue; for (u = r->units; u; u = u->next) if (!fval(u->faction, FFL_SELECT)) { f = u->faction; fset(f, FFL_SELECT); add_message(&f->msgs, msg); } } msg_release(msg); } } }
/** ** GM: TELEPORT <unit> <x> <y> ** requires: permission-key "gmtele" **/ static void gm_teleport(const void *tnext, struct unit *u, struct order *ord) { const struct plane *p = rplane(u->region); unit *to = findunit(getid()); int x = rel_to_abs(p, u->faction, getint(), 0); int y = rel_to_abs(p, u->faction, getint(), 1); region *r = findregion(x, y); if (r == NULL || p != rplane(r)) { mistake(u, ord, "region is in another plane."); } else if (to == NULL) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", "")); } else if (rplane(to->region) != rplane(r) && !ucontact(to, u)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_no_contact", "target", to)); } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmtele"))) { mistake(u, ord, "permission denied."); } else move_unit(to, r, NULL); } }
bool GameLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { if (LOCAL_CONTEXT->firstRun()) { //第一次启动,点击取消帮助画面层 this->removeHelpLayer(); return false; } if (running) { disable(); CCSprite *lastItem = items[0]; long itemnum = (long) lastItem->getUserData(); //CCDirector::sharedDirector()->replaceScene(FinishLayer::scene()); CCSize winsize = CCDirector::sharedDirector()->getWinSize(); CCPoint location = pTouch->getLocation(); if (location.x < winsize.width / 2) { LOCAL_CONTEXT->playEffect("left.mp3"); //瓶子 6-10 if (itemnum >= 6) { correct(-0.32); } else { mistake(-0.32); } } else { LOCAL_CONTEXT->playEffect("right.mp3"); //罐子 1-5 if (itemnum <= 5) { correct(0.32); } else { mistake(0.32); } } } return false; }
static void gm_create(const void *tnext, struct unit *u, struct order *ord) { int i; attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (permissions) permissions = (attrib *) permissions->data.v; if (!permissions) return; i = getint(); if (i > 0) { const char *iname = getstrtoken(); const item_type *itype = finditemtype(iname, u->faction->locale); if (itype == NULL) { mistake(u, ord, "unknown item."); } else { attrib *a = a_find(permissions, &at_gmcreate); while (a && a->type == &at_gmcreate && a->data.v != (void *)itype) a = a->next; if (a) i_change(&u->items, itype, i); else mistake(u, ord, "your faction cannot create this item."); } } }
void b_order( game *aGame, player *P, strlist **s ) { group *g; /* pointer to named group */ group *g2; /* pointer to new group */ int i; /* int value for number of ships */ char *ns; /* char value for number of ships */ DBUG_ENTER( "b_order" ); /* find the named group */ g = findgroup( P, getstr( 0 ) ); if ( !g ) { mistake( P, INFO, *s, "Group not recognized." ); DBUG_VOID_RETURN; } /* check to see if we're detaching from a fleet */ ns = getstr( 0 ); if ( noCaseStrncmp( ns, "fleet", 5 ) == 0 ) { if ( !epsilon( g->dist, 0.0, 0.0001 ) ) { mistake( P, WARNING, *s, "Fleet is in hyperspace." ); DBUG_VOID_RETURN; } g->thefleet = 0; DBUG_VOID_RETURN; } /* are there enough ships to detach? */ i = atoi( ns ); if ( i > g->ships ) { /* FS Dec 1998 */ mistake( P, INFO, *s, "Not enough ships in group." ); DBUG_VOID_RETURN; } /* this was an odd problem */ if ( i < 0 ) { /* KDW July 1999 */ mistake( P, WARNING, *s, "Can't have negative number of ships." ); DBUG_VOID_RETURN; } /* create a new group for what's being broken off and add it to * the list of groups the player owns */ g2 = allocStruct( group ); *g2 = *g; g2->ships = i; g->ships -= i; g2->thefleet = 0; g2->next = NULL; numberGroup( P, g2 ); g2->name = ( char * ) malloc( 8 ); sprintf( g2->name, "%d", g2->number ); addList( &P->groups, g2 ); DBUG_VOID_RETURN; }
void p_order( game *aGame, player *P, strlist **s ) { char *ns; planet *p; shiptype *t; DBUG_ENTER( "p_order" ); p = findPlanet( aGame, getstr( 0 ) ); if ( !p ) { mistake( P, ERROR, *s, "Planet not recognized." ); DBUG_VOID_RETURN; } if ( p->owner != P ) { mistake( P, ERROR, *s, "Planet not owned by you." ); DBUG_VOID_RETURN; } ns = getstr( 0 ); if ( !noCaseStrcmp( ns, "cap" ) ) { setproduction( aGame, p, PR_CAP ); DBUG_VOID_RETURN; } if ( !noCaseStrcmp( ns, "mat" ) ) { setproduction( aGame, p, PR_MAT ); DBUG_VOID_RETURN; } if ( !noCaseStrcmp( ns, "drive" ) ) { setproduction( aGame, p, PR_DRIVE ); DBUG_VOID_RETURN; } if ( !noCaseStrcmp( ns, "weapons" ) ) { setproduction( aGame, p, PR_WEAPONS ); DBUG_VOID_RETURN; } if ( !noCaseStrcmp( ns, "shields" ) ) { setproduction( aGame, p, PR_SHIELDS ); DBUG_VOID_RETURN; } if ( !noCaseStrcmp( ns, "cargo" ) ) { setproduction( aGame, p, PR_CARGO ); DBUG_VOID_RETURN; } t = findElement( shiptype, P->shiptypes, ns ); if ( !t ) { mistake( P, ERROR, *s, "Production type \"%s\" not recognized.", ns ); DBUG_VOID_RETURN; } if ( p->producing != PR_SHIP || p->producingshiptype != t ) { setproduction( aGame, p, PR_SHIP ); p->producingshiptype = t; } DBUG_VOID_RETURN; }
void x_order( game *aGame, player *P, strlist **s ) { group *g; group *g2; int i; int j; DBUG_ENTER( "x_order" ); g = findgroup( P, getstr( 0 ) ); if ( !g ) { mistake( P, ERROR, *s, "Group not recognized." ); DBUG_VOID_RETURN; } if ( g->dist > 0.0 ) { mistake( P, ERROR, *s, "Group is in hyperspace." ); DBUG_VOID_RETURN; } if ( g->loadtype == CG_COL && g->where->owner && g->where->owner != P ) { mistake( P, ERROR, *s, "Can't unload colonists onto an alien planet." ); DBUG_VOID_RETURN; } i = g->ships; if ( ( j = atoi( getstr( 0 ) ) ) != 0 ) { i = j; if ( i > g->ships ) { mistake( P, ERROR, *s, "Not enough ships, all available used." ); i = g->ships; } if ( i <= 0 ) { /* KDW July 1999 */ mistake( P, ERROR, *s, "You must specify more than 0 ships, all available used." ); i = g->ships; } if ( i != g->ships ) { g2 = allocStruct( group ); *g2 = *g; g2->next = NULL; numberGroup( P, g2 ); g2->name = ( char * ) malloc( 8 ); sprintf( g2->name, "%d", g2->number ); addList( &P->groups, g2 ); g->ships -= i; g2->ships = i; g = g2; } } unloadgroup( g, P, g->load ); g->where->mat += shipmass( g ) * g->ships; g->ships = 0; DBUG_VOID_RETURN; }
void Recaptcha::http_done(const boost::system::error_code& e, const Http::Message& response) { if (e) { mistake(tr("wc.captcha.Internal_error")); } else if (boost::starts_with(response.body(), "true")) { solve(); } else if (boost::contains(response.body(), "incorrect-captcha-sol")) { mistake(tr("wc.captcha.Wrong_response")); } else { mistake(tr("wc.captcha.Internal_error")); } updates_poster(WServer::instance(), wApp); }
/** ** GM: TERRAFORM <x> <y> <terrain> ** requires: permission-key "gmterf" **/ static void gm_terraform(const void *tnext, struct unit *u, struct order *ord) { const struct plane *p = rplane(u->region); int x = rel_to_abs(p, u->faction, getint(), 0); int y = rel_to_abs(p, u->faction, getint(), 1); const char *c = getstrtoken(); variant token; void **tokens = get_translations(u->faction->locale, UT_TERRAINS); region *r; pnormalize(&x, &y, p); r = findregion(x, y); if (r == NULL || p != rplane(r)) { mistake(u, ord, "region is in another plane."); return; } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmterf"))) return; } if (findtoken(*tokens, c, &token) != E_TOK_NOMATCH) { const terrain_type *terrain = (const terrain_type *)token.v; terraform_region(r, terrain); } }
QString Expression::stripBrackets( QString expression ) { bool stripping = true; int bracketLevel = 0; int i = 0; expression = expression.trimmed(); while(stripping) { if( expression.at(i) == '(' ) bracketLevel++; else if( expression.at(i) == ')' ) { if( i == int(expression.length() - 1) && bracketLevel == 1) { expression = expression.mid(1,expression.length() - 2).trimmed(); } bracketLevel--; } if( i == int(expression.length() - 1) && bracketLevel > 0 ) { mistake( Microbe::MismatchedBrackets, expression ); // Stray brackets might cause the expressionession parser some problems, // so we just avoid parsing anything altogether expression = ""; stripping = false; } i++; if( bracketLevel == 0 ) stripping = false; } return expression; }
/** ** GM: GATE <id> <x> <y> ** requires: permission-key "gmgate" **/ static void gm_gate(const void *tnext, struct unit * u, struct order *ord) { const struct plane *pl = rplane(u->region); int id = getid(); int x = rel_to_abs(pl, u->faction, getint(), 0); int y = rel_to_abs(pl, u->faction, getint(), 1); building *b = findbuilding(id); region *r; pnormalize(&x, &y, pl); r = findregion(x, y); if (b == NULL || r == NULL || pl != rplane(b->region) || pl != rplane(r)) { mistake(u, ord, "the unit cannot transform this building."); return; } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (permissions && has_permission(permissions, atoi36("gmgate"))) { remove_triggers(&b->attribs, "timer", &tt_gate); remove_triggers(&b->attribs, "create", &tt_unguard); if (r != b->region) { add_trigger(&b->attribs, "timer", trigger_gate(b, r)); add_trigger(&b->attribs, "create", trigger_unguard(b)); fset(b, BLD_UNGUARDED); } } } }
////////////////////////////////////////////////// // void AC_Add(Deque deque, AC_itemPtr item) // deque - deque of data // item - package of three address code //////////////////// // adds package of three address code to deque ////////////////////////////////////////////////// void AC_Add(Deque deque, AC_itemPtr item) { #if DEBUG printf("Adding AC_item %d to deque %d\n",item, deque); #endif if(deque != NULL) D_PushBack(deque, item); else mistake(ERR_INTERN,"Problem with adding AC_item to deqeu\n"); }
/** ** GM: TELL REGION <x> <y> <string> ** requires: permission-key "gmmsgr" **/ static void gm_messageregion(const void *tnext, struct unit *u, struct order *ord) { const struct plane *p = rplane(u->region); int x = rel_to_abs(p, u->faction, getint(), 0); int y = rel_to_abs(p, u->faction, getint(), 1); const char *msg = getstrtoken(); region *r = findregion(x, y); if (r == NULL || p != rplane(r)) { mistake(u, ord, "region is in another plane."); } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmmsgr"))) { mistake(u, ord, "permission denied."); } else { add_message(&r->msgs, msg_message("msg_event", "string", msg)); } } }
/** ** GM: KILL UNIT <id> <string> ** requires: permission-key "gmkill" **/ static void gm_killunit(const void *tnext, struct unit *u, struct order *ord) { const struct plane *p = rplane(u->region); unit *target = findunit(getid()); const char *msg = getstrtoken(); region *r = target->region; if (r == NULL || p != rplane(r)) { mistake(u, ord, "region is in another plane."); } else { /* checking permissions */ attrib *permissions = a_find(u->faction->attribs, &at_permissions); if (!permissions || !has_permission(permissions, atoi36("gmkill"))) { mistake(u, ord, "permission denied."); } else { scale_number(target, 0); ADDMSG(&target->faction->msgs, msg_message("killedbygm", "region unit string", r, target, msg)); } } }
void q_order( game *aGame, player *P, strlist **s ) { DBUG_ENTER( "q_order" ); if ( findElement( player, aGame->players, getstr( 0 ) ) != P ) { mistake( P, ERROR, *s, "Race identification not given." ); DBUG_VOID_RETURN; } P->flags |= F_DEAD; DBUG_VOID_RETURN; }
void SerialHandler::read() { if(!serial->canReadLine()) { return; } QByteArray data = serial->readLine(); QString dataStr = QString(data); dataStr = dataStr.remove('\r'); dataStr = dataStr.remove('\n'); QTime time; int hitCount; QString status; try { QStringList params = dataStr.split(';'); if(params.length() == 3) { time = QTime::fromString(params[0],"mm:ss.zzz"); hitCount = params[1].toInt(); status = params[2]; } } catch(...) { // ToDo: Error-Handling } if(status == "Time") { //emit timeChanged(time); } else if(status == "Start") { emit started(time); } else if(status == "Reset") { emit reset(); } else if(status == "Mistake") { emit mistake(time, hitCount); } else if(status == "Stop") { emit stopped(time, hitCount); } }
void Recaptcha::check_impl() { std::string challenge = value_text(challenge_field_).toUTF8(); std::string response = value_text(response_field_).toUTF8(); const std::string& remoteip = wApp->environment().clientAddress(); Http::Message m; m.setHeader("Content-Type", "application/x-www-form-urlencoded"); m.addBodyText("privatekey=" + private_key_ + "&"); m.addBodyText("remoteip=" + remoteip + "&"); m.addBodyText("challenge=" + urlencode(challenge) + "&"); m.addBodyText("response=" + urlencode(response) + "&"); #ifdef WT_WITH_SSL std::string schema = "https"; #else std::string schema = "http"; #endif if (!http_->post(schema + "://www.google.com/recaptcha/api/verify", m)) { mistake(tr("wc.captcha.Internal_error")); } }
Trainer::Trainer(int minLevel, int maxLevel, QString sourceLanguage, QString targetLanguage, QList<Translation> wordList, TextToSpeech &tts, PhoneticsManager &phoneticsManager, QWidget *parent) : QDialog(parent) , ui(new Ui::Trainer) , tts(tts) , sourceLanguage(sourceLanguage) , targetLanguage(targetLanguage) , trainingManager(minLevel, maxLevel, sourceLanguage, targetLanguage, phoneticsManager) { ui->setupUi(this); connect(&trainingManager, SIGNAL(statusChanged(TrainingStatus)), SLOT(updateStatus(TrainingStatus))); connect(&trainingManager, SIGNAL(mistake()), SLOT(madeMistake())); connect(&trainingManager, SIGNAL(finished(TrainingStatus)), SLOT(trainingFinished(TrainingStatus))); connect(&trainingManager, SIGNAL(nextQuestion()), SLOT(gotNextQuestion())); connect(&tts, SIGNAL(synthesisReady(QString,QString)), SLOT(enableListen())); connect(&tts, SIGNAL(synthesisSuccess()), SLOT(enableListen())); QSettings settings; ui->reverseMode->setChecked(settings.value("reverseMode").value<bool>()); trainingManager.loadWords(wordList); QStringList const dirs = QStringList() << ":/wordlists" << "./wordlists"; foreach (QString const &dir, dirs) trainingManager.loadWords(QDir(dir)); foreach (QString const &dir, dirs) trainingManager.loadHints(QDir(dir)); trainingManager.start(); }
void e_order( game *aGame, player *P, strlist **s ) { shiptype *t; /* type to be eliminated */ fleetname *fl; /* fleet to be eliminated */ group *g; /* group containing the ship */ planet *p; /* planet ship/fleet is orbiting */ char *ns; /* retrieving parameters */ DBUG_ENTER( "e_order" ); /* see if this is a fleet or ship type */ ns = getstr( 0 ); t = findElement( shiptype, P->shiptypes, ns ); fl = findElement( fleetname, P->fleetnames, ns ); /* neither? must be a typo */ if ( !t && !fl ) { mistake( P, ERROR, *s, "Ship or fleet type not recognized." ); DBUG_VOID_RETURN; } /* if it's a fleet . . . */ if ( fl ) { /* can't be in hyperspace */ for ( g = P->groups; g; g = g->next ) { if ( ( g->thefleet == fl ) && ( epsilon( g->dist, 0.0, 0.0001 ) ) ) { mistake( P, ERROR, *s, "Group is in hyperspace." ); DBUG_VOID_RETURN; } } /* find it, delete it */ for ( g = P->groups; g; g = g->next ) { if ( g->thefleet == fl ) g->thefleet = 0; } remList( &P->fleetnames, fl ); } else { /* it must be a group */ /* can't delete ship type if ships of that type still exist */ for ( g = P->groups; g; g = g->next ) { if ( g->type == t ) { mistake( P, ERROR, *s, "Some of these ships still exist." ); DBUG_VOID_RETURN; } } if ( g ) DBUG_VOID_RETURN; /* can't delete ship type if you're currently building them */ for ( p = aGame->planets; p; p = p->next ) { if ( p->producingshiptype == t ) { mistake( P, ERROR, *s, "Some of these ships are still being produced." ); DBUG_VOID_RETURN; } } if ( p ) DBUG_VOID_RETURN; /* ok, it's really orphaned, delete it */ remList( &P->shiptypes, t ); } DBUG_VOID_RETURN; }
void Expression::expressionValue( QString expr, BTreeBase */*tree*/, BTreeNode *node) { /* The "end of the line" for the expression parsing, the expression has been broken down into the fundamental elements of expr.value()=="to"|| variable, number, special etc... so we now just set value and type */ /* Alternatively we might have a function call e.g. somefunction(3,potatoes,hairstyle + 6) In which case we need to call back to parseExpr to process the arguments, saving them on the basic stack then making the function call. Of course we also need to mark the terminal node type as a function. */ expr = expr.trimmed(); // My intention is so that these error checks are ordered // so that e.g. for x = 3 it picks up the = rather than the spaces first. expr = mb->alias(expr); ExprType t = expressionType(expr); // See if it is a single qouted character, e.g. 'A' if( expr.left(1) == "\'" && expr.right(1) == "\'" ) { if( expr.length() == 3 ) // fall through to report as unknown variable if not of form 'x' { // If so, turn it into a number, and use the ASCII code as the value t = number; expr = QString::number(expr[1].toLatin1()); } } // Check for the most common mistake ever! if(expr.contains("=")) mistake( Microbe::InvalidEquals ); // Check for reserved keywords if(expr=="to"||expr=="step"||expr=="then") mistake( Microbe::ReservedKeyword, expr ); // Check for empty expressions, or expressions contating spaces // both indicating a Mistake. if(expr.isEmpty()) mistake( Microbe::ConsecutiveOperators ); else if(expr.contains(QRegExp("\\s")) && t!= extpin) mistake( Microbe::MissingOperator ); //***************modified isValidRegister is included ***********************// if( t == variable && !mb->isVariableKnown(expr) && !m_pic->isValidPort( expr ) && !m_pic->isValidTris( expr )&&!m_pic->isValidRegister( expr ) ) mistake( Microbe::UnknownVariable, expr ); //modification ends if ( mb->isVariableKnown(expr) && !mb->variable(expr).isReadable() ) mistake( Microbe::WriteOnlyVariable, expr ); node->setType(t); // Since we currently only implement 8 bit unsigned integers, we should disallow // anything outside the range [0-255]. if( t == number && !m_bSupressNumberTooBig && (expr.toInt() > 255) ) { mistake( Microbe::NumberTooBig ); } // if there was a pin, we need to decocde it. // For now and sacrificing syntax error checking // we just look for the word "is" then "high" or "low". if( t == extpin ) { bool NOT; int i = expr.indexOf("is"); if(i > 0) { NOT = expr.contains("low"); if(!expr.contains("high") && !expr.contains("low")) mistake( Microbe::HighLowExpected, expr ); expr = expr.left(i-1); } else NOT = false; node->setChildOp(NOT?notpin:pin); } else if ( t == keypad ) node->setChildOp( read_keypad ); node->setValue(expr); }
void Expression::compileConditional( const QString & expression, Code * ifCode, Code * elseCode ) { if( expression.contains(QRegExp("=>|=<|=!")) ) { mistake( Microbe::InvalidComparison, expression ); return; } if( expression.contains(QRegExp("[^=><!][=][^=]"))) { mistake( Microbe::InvalidEquals ); return; } // Make a tree to put the expression in. BTreeBase *tree = new BTreeBase(); BTreeNode *root = new BTreeNode(); // parse the expression into the tree buildTree(expression,tree,root,0); // Modify the tree so it is always at the top level of the form (kwoerpkwoep) == (qwopekqpowekp) if ( root->childOp() != equals && root->childOp() != notequals && root->childOp() != gt && root->childOp() != lt && root->childOp() != ge && root->childOp() != le && root->childOp() != pin && root->childOp() != notpin && root->childOp() != read_keypad ) { BTreeNode *newRoot = new BTreeNode(); BTreeNode *oneNode = new BTreeNode(); oneNode->setChildOp(noop); oneNode->setType(number); oneNode->setValue("1"); newRoot->setLeft(root); newRoot->setRight(oneNode); newRoot->setType(unset); newRoot->setChildOp(ge); tree->setRoot(newRoot); root = newRoot; } // compile the tree into assembly code tree->setRoot(root); tree->pruneTree(tree->root(),true); // We might have just a constant expression, in which case we can just always do if or else depending // on whether it is true or false. if( root->childOp() == noop ) { if( root->value().toInt() == 0 ) m_pic->mergeCode( elseCode ); else m_pic->mergeCode( ifCode ); return; } // traverse tree with argument conditionalRoot true // so that 3 == x gets integrated with code for if, repeat until etc... m_ifCode = ifCode; m_elseCode = elseCode; traverseTree(tree->root(),true); // Note deleting the tree deletes all nodes, so the root // doesn't need deleting separately. delete tree; }
void Expression::traverseTree( BTreeNode *root, bool conditionalRoot ) { Traverser t(root); t.start(); // special case: if we are starting at the root node then // we are dealing with something of the form variable = 6 // or variable = portb ///TODO reimplement assignments as two branched trees? if ( t.current() == root && !root->hasChildren() && t.current()->childOp() != pin && t.current()->childOp() != notpin && t.current()->childOp() != function && t.current()->childOp() != read_keypad ) { switch(root->type()) { case number: m_pic->assignNum(root->value()); break; case variable: m_pic->assignVar(root->value()); break; default: break; // Should never get here } // no need to traverse the tree as there is none. return; } t.setCurrent(root); if(t.current()->hasChildren()) { // Here we work out what needs evaulating, and in which order. // To minimize register usage, if only one branch needs traversing, // then that branch should be done first. bool evaluateLeft = t.current()->left()->needsEvaluating(); BTreeNode *evaluateFirst; BTreeNode *evaluateSecond; // If both need doing, then it really doesn't matter which we do // first (unless we are looking to do really complex optimizations... // Cases: // - Both need evaluating, // - or left needs doing first, // in both cases we evaluate left, then right. if( evaluateLeft ) { evaluateFirst = t.current()->left(); evaluateSecond = t.current()->right(); } // Otherwise it is best to evaluate right first for reasons given above. else { evaluateFirst = t.current()->right(); evaluateSecond = t.current()->left(); } QString dest1 = mb->dest(); mb->incDest(); QString dest2 = mb->dest(); mb->decDest(); bool evaluated = false; if( evaluateFirst->hasChildren() ) { traverseTree(evaluateFirst); evaluated = true; } else if( isUnaryOp(evaluateFirst->childOp()) ) { doUnaryOp( evaluateFirst->childOp(), evaluateFirst ); evaluated = true; } if ( evaluated ) { // We need to save the result if we are going tro traverse the other // branch, or if we are performing a subtraction in which case the // value wanted in working is not the current value. // But as the optimizer will deal with unnecessary variables anyway, // always save to a register evaluateFirst->setReg( dest1 ); evaluateFirst->setType( variable ); m_pic->saveToReg( dest1 ); } evaluated = false; if( evaluateSecond->hasChildren() ) { mb->incDest(); mb->incDest(); traverseTree(evaluateSecond); evaluated = true; mb->decDest(); mb->decDest(); } else if( isUnaryOp(evaluateSecond->childOp()) ) { doUnaryOp( evaluateSecond->childOp(), evaluateSecond ); evaluated = true; } if ( evaluated ) { evaluateSecond->setReg( dest2 ); evaluateSecond->setType( variable ); m_pic->saveToReg( dest2 ); } } if(t.current()->childOp()==divbyzero) { mistake( Microbe::DivisionByZero ); } // If we are at the top level of something like 'if a == 3 then', then we are ready to put // in the if code, else the expression just evaluates to 0 or 1 if(conditionalRoot && t.current() == root) m_pic->setConditionalCode(m_ifCode, m_elseCode); // Handle operations // (functions are not actually supported) if(isUnaryOp(t.current()->childOp())) doUnaryOp( t.current()->childOp(), t.current() ); else doOp( t.current()->childOp(), t.current()->left(), t.current()->right() ); }