// MixerTest_DoMenuItem() // ----------------------------------------------------- // // void MixerTest_DoMenuItem(int menu, int subMenu) { BAEResult err; err = BAE_NO_ERROR; switch (menu) { case 1: err = DoScript(subMenu); break; case 2: err = DoFunction(subMenu); break; case 3: err = DoTest(subMenu); break; default: break; } if (err) { printf("\a! Error code: %s (%d)\n", BAEResultToStr(err), (int)err); } else { printf("OK.\n"); } }
int Do(lua::Handle L) { A1 p1; lua::CheckVarFromLua(L,&p1,1); DoFunction(L,obj,func,p1); return (int)1; }
int Do(lua::Handle L) { A1 p1; A2 p2; lua::CheckVarFromLua(L,&p1,1); lua::CheckVarFromLua(L,&p2,2); DoFunction(L,func02,p1,p2); return (int)1; }
int Do(lua::Handle L) { A1 p1; A2 p2; A3 p3; lua::CheckVarFromLua(L,&p1,1); lua::CheckVarFromLua(L,&p2,2); lua::CheckVarFromLua(L,&p3,3); DoFunction(L,obj,func,p1,p2,p3); return (int)1; }
void Declarations() { while(strchr("lctvpf", Look)) { switch(Look) { case 'l': Labels(); case 'c': Constants(); case 't': Types(); case 'v': Variables(); case 'p': DoProcedure(); case 'f': DoFunction(); } } }
int Do(lua::Handle L) { A1 p1; A2 p2; A3 p3; A4 p4; lua::CheckVarFromLua(L,&p1,1); lua::CheckVarFromLua(L,&p2,2); lua::CheckVarFromLua(L,&p3,3); lua::CheckVarFromLua(L,&p4,4); DoFunction(L,func04,p1,p2,p3,p4); return (int)1; }
void Declarations(){ int other = 0; while(!other){ switch(Look){ case 'l' : Labels(); break; case 'c' : Constants(); break; case 't' : Types(); break; case 'v' : Variables(); break; case 'p' : DoProcedure(); break; case 'f' : DoFunction(); break; default : other = 1; } } }
int Do(lua::Handle L) { A1 p1; A2 p2; A3 p3; A4 p4; A5 p5; A6 p6; lua::CheckVarFromLua(L,&p1,1); lua::CheckVarFromLua(L,&p2,2); lua::CheckVarFromLua(L,&p3,3); lua::CheckVarFromLua(L,&p4,4); lua::CheckVarFromLua(L,&p5,5); lua::CheckVarFromLua(L,&p6,6); DoFunction(L,obj,func,p1,p2,p3,p4,p5,p6); return (int)1; }
wxString wxStringFormatter::FindNextFunction(wxString input, int& Startpos, int& Endpos) { wxLogDebug("FindNextFunction: " + input); int functBegin; int blockOpen = input.find_first_of(DELIMS_F_OPEN); if(blockOpen == wxNOT_FOUND) { Startpos = wxNOT_FOUND; return ""; } int blockClose = input.find_first_of(m_funcDelims, blockOpen +1); while(!DELIMS_F_CLOSE.Contains(input.GetChar(blockClose)) && blockClose != wxNOT_FOUND) { if(DELIMS_F_OPEN.Contains(input.GetChar(blockClose))) { blockOpen = blockClose; blockClose = input.find_first_of(m_funcDelims, blockOpen +1); } } if(blockClose == wxNOT_FOUND) { Startpos = wxNOT_FOUND; return ""; } Endpos = blockClose + 1; //return input.SubString(blockOpen+1, blockClose-1); functBegin = input.find_last_of(DELIMS, blockOpen -1); functBegin++; wxString tmp = DoFunction(input.SubString(functBegin, blockOpen -1), input.SubString(blockOpen+1, blockClose-1)); if(m_concatDelims.Contains(input.GetChar(functBegin -1))) { functBegin--; } Startpos = functBegin; return tmp; }
/* XOPEntry() This is the entry point from the host application to the XOP for all messages after the INIT message. */ static void XOPEntry(void) { long result = 0; switch (GetXOPMessage()) { case FUNCTION: // Our external function being invoked ? result = DoFunction(); break; case FUNCADDRS: result = RegisterFunction(); break; case IDLE: srEnsureSrwInit(); break; } SetXOPResult(result); }
void ReadNewUser() { userFirstLine = 1; inputCount = 0; ClearUserVariables(); ResetTopicSystem(); // set his random seed bool hasUpperCharacters; unsigned int rand = (unsigned int) Hashit((unsigned char *) loginID,strlen(loginID),hasUpperCharacters); char word[MAX_WORD_SIZE]; randIndex = rand & 4095; sprintf(word,"%d",randIndex); SetUserVariable("$randindex",word ); strcpy(word,computerID); word[0] = toUppercaseData[(unsigned char)word[0]]; SetUserVariable("$bot",word ); SetUserVariable("$login",loginName); sprintf(readBuffer,"^%s",computerID); WORDP D = FindWord(readBuffer,0,LOWERCASE_LOOKUP); if (!D) { ReportBug("Cannot find bot %s\r\n",computerID); return; } int oldjump = jumpIndex; char* macroArgumentList = AllocateBuffer(); *macroArgumentList = 0; globalDepth = 2; unsigned int result; currentOutputBase = macroArgumentList; DoFunction(D->word,macroArgumentList,macroArgumentList,result); globalDepth = 0; jumpIndex = oldjump; // return to old error handler FreeBuffer(); }
// DoScript() // ----------------------------------------------------- // // static BAEResult DoScript(int subMenu) { BAEResult err; BAE_BOOL validerr; short tmpShort1, tmpShort2, tmpShort3; long tmpLong1, tmpLong2; char buffer[256]; BAE_BOOL tmpBool1; BAE_UNSIGNED_FIXED tmpUFixed1; short int midiVoices, pcmVoices; BAEQuality q; BAEAudioModifiers s; validerr = TRUE; err = BAE_NO_ERROR; s = BAE_NONE; switch (subMenu) { case SCRIPT_MIXER_OPEN_8_16_MONO: case SCRIPT_MIXER_OPEN_22_16_MONO: case SCRIPT_MIXER_OPEN_8_8_16_MONO: case SCRIPT_MIXER_OPEN_16_16_7_1_MONO: case SCRIPT_MIXER_OPEN_16_16_8_8_MONO: case SCRIPT_MIXER_OPEN_22_16_8_MONO: { switch (subMenu) { case SCRIPT_MIXER_OPEN_8_8_16_MONO: case SCRIPT_MIXER_OPEN_8_16_MONO: q = BAE_8K; break; case SCRIPT_MIXER_OPEN_22_16_8_MONO: q = BAE_22K; break; case SCRIPT_MIXER_OPEN_22_16_MONO: q = BAE_22K; break; case SCRIPT_MIXER_OPEN_16_16_7_1_MONO: case SCRIPT_MIXER_OPEN_16_16_8_8_MONO: q = BAE_16K; break; default: return BAE_PARAM_ERR; } switch (subMenu) { case SCRIPT_MIXER_OPEN_22_16_8_MONO: midiVoices = 8; pcmVoices = 0; break; case SCRIPT_MIXER_OPEN_8_16_MONO: case SCRIPT_MIXER_OPEN_22_16_MONO: case SCRIPT_MIXER_OPEN_16_16_7_1_MONO: midiVoices = 7; pcmVoices = 1; break; case SCRIPT_MIXER_OPEN_8_8_16_MONO: case SCRIPT_MIXER_OPEN_16_16_8_8_MONO: midiVoices = 8; pcmVoices = 0; break; default: return BAE_PARAM_ERR; } if (gMixer == NULL) { gMixer = BAEMixer_New(); } else { printf("Mixer already allocated\n"); validerr = FALSE; } err = BAEMixer_Open(gMixer, q, BAE_LINEAR_INTERPOLATION,BAE_USE_16 | s, midiVoices, pcmVoices, 7, TRUE); printf("\n"); } break; case SCRIPT_MIXER_CLOSE: DoFunction(FUNC_MIXER_DELETE); validerr = FALSE; break; case SCRIPT_MIXER_SET_DEFAULT_SMALL_BANK: { BAEBankToken token; err = BAEMixer_UnloadBanks(gMixer); // free all banks if (err) { printf("Error unloading banks (%d)\n", err); } err = BAEMixer_AddBankFromFile(gMixer, "npatches.hsb", &token); if (err == 0) { printf("token = %d\n", token); } } break; case SCRIPT_MIXER_SET_DEFAULT_BIG_BANK: { BAEBankToken token; err = BAEMixer_UnloadBanks(gMixer); // free all banks if (err) { printf("Error unloading banks (%d)\n", err); } err = BAEMixer_AddBankFromFile(gMixer, "patches.hsb", &token); if (err == 0) { printf("token = %d\n", token); } } break; case SCRIPT_MIXER_DISPLAY_CPU_LOAD: { int count; for (count = 0; count < 30; count++) { DoFunction(FUNC_MIXER_GETCPULOADINPERCENT); } } break; case SCRIPT_MIXER_DISPLAY_SAMPLE_FRAMES: { int count; for (count = 0; count < 30; count++) { DoFunction(FUNC_MIXER_GETAUDIOSAMPLEFRAME); } } break; case SCRIPT_MIXER_DISPLAY_REALTIME_STATUS: { int count; for (count = 0; count < 30; count++) { DoFunction(FUNC_MIXER_GETREALTIMESTATUS); } } break; case SCRIPT_MIXER_GET_DEVICE_INFO: { err = BAEMixer_GetMaxDeviceCount(gMixer, &tmpLong1); if (err) break; printf("Num devices = %d\n", tmpLong1); for (tmpLong2=0; tmpLong2<tmpLong1; tmpLong2++) { err = BAEMixer_GetDeviceName(gMixer, tmpLong2, buffer, 256); if (err) break; printf(" device %d: %s\n", tmpLong2, buffer); } err = BAEMixer_GetCurrentDevice(gMixer, NULL, &tmpLong1); if (err) break; printf("Current device: %d\n", tmpLong1); err = BAEMixer_Is16BitSupported(gMixer, &tmpBool1); if (err) break; printf(" 16-bit support? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_Is8BitSupported(gMixer, &tmpBool1); if (err) break; printf(" 8-bit support? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_GetAudioLatency(gMixer, (unsigned long *)&tmpLong1); if (err) break; printf(" Latency: %d milliseconds\n", tmpLong1); err = BAEMixer_GetMasterVolume(gMixer, &tmpUFixed1); if (err) break; printf(" Master volume: %g\n", FIXED_TO_FLOAT(tmpUFixed1)); err = BAEMixer_GetHardwareVolume(gMixer, &tmpUFixed1); if (err) break; printf(" Hardware volume: %g\n", FIXED_TO_FLOAT(tmpUFixed1)); err = BAEMixer_GetMasterSoundEffectsVolume(gMixer, &tmpUFixed1); if (err) break; printf(" Master Sfx volume: %g\n", FIXED_TO_FLOAT(tmpUFixed1)); } break; case SCRIPT_MIXER_GET_MIXER_INFO: { BAEQuality q; BAETerpMode t; err = BAEMixer_GetMixerVersion(gMixer, &tmpShort1, &tmpShort2, &tmpShort3); if (err) break; printf("\nBAEMixer v%d.%d.%d\n", tmpShort1, tmpShort2, tmpShort3); err = BAEMixer_IsOpen(gMixer, &tmpBool1); if (err) break; printf(" Is Open? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_GetQuality(gMixer, &q); if (err) break; printf(" Quality: %s\n", BAEQualityToStr(q)); err = BAEMixer_GetTerpMode(gMixer, &t); if (err) break; printf(" Terp mode: %s\n", BAETerpModeToStr(t)); err = BAEMixer_GetModifiers(gMixer, &tmpLong1); if (err) break; printf(" Modifiers: %x\n", tmpLong1); err = BAEMixer_GetMidiVoices(gMixer, &tmpShort1); if (err) break; printf(" Midi voices: %d\n", tmpShort1); err = BAEMixer_GetSoundVoices(gMixer, &tmpShort1); if (err) break; printf(" Sound voices: %d\n", tmpShort1); err = BAEMixer_GetMixLevel(gMixer, &tmpShort1); if (err) break; printf(" Mix level: %d\n", tmpShort1); err = BAEMixer_IsAudioEngaged(gMixer, &tmpBool1); if (err) break; printf(" Audio engaged? %s\n", (tmpBool1) ? "Yes" : "No"); err = BAEMixer_IsAudioActive(gMixer, &tmpBool1); if (err) break; printf(" Audio active? %s\n", (tmpBool1) ? "Yes" : "No"); } break; case SCRIPT_MIXER_GET_BANK_INFO: { tmpLong1 = GetLong(">>Bank token: "); err = BAEMixer_GetBankVersion(gMixer, (BAEBankToken)tmpLong1, &tmpShort1, &tmpShort2, &tmpShort3); if (err) break; printf("Bank version %d.%d.%d\n", tmpShort1, tmpShort2, tmpShort3); } break; default: break; } return err; }
bool Match(char* ptr, unsigned int depth, int startposition, char* kind, bool wildstart,unsigned int& gap,unsigned int& wildcardSelector, int &returnstart,int& returnend,bool &uppercasem,int& firstMatched,int& positionStart,int& positionEnd, bool reverse) {// always STARTS past initial opening thing ( [ { and ends with closing matching thing int startdepth = globalDepth; char word[MAX_WORD_SIZE]; char* orig = ptr; int statusBits = (*kind == '<') ? FREEMODE_BIT : 0; // turns off: not, quote, startedgap, freemode, gappassback,wildselectorpassback if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERTABLOG, "%s ",kind); // start on new indented line ChangeDepth(1,(char*)"Match"); bool matched; unsigned int startNest = functionNest; unsigned int result; int pendingMatch = -1; WORDP D; int hold; unsigned int oldtrace = trace; bool oldecho = echo; bool success = false; firstMatched = -1; // () should return spot it started (firstMatched) so caller has ability to bind any wild card before it if (wildstart) positionStart = INFINITE_MATCH; // INFINITE_MATCH means we are in initial startup, allows us to match ANYWHERE forward to start positionEnd = startposition; // we scan starting 1 after this int basicStart = startposition; // we must not match real stuff any earlier than here char* argumentText = NULL; // pushed original text from a function arg -- function arg never decodes to name another function arg, we would have expanded it instead bool uppercasematch = false; while (ALWAYS) // we have a list of things, either () or { } or [ ]. We check each item until one fails in () or one succeeds in [ ] or { } { int oldStart = positionStart; // allows us to restore if we fail, and confirm legality of position advance. int oldEnd = positionEnd; int id; char* nextTokenStart = SkipWhitespace(ptr); ptr = ReadCompiledWord(nextTokenStart,word); if (*word == '<' && word[1] == '<') ++nextTokenStart; // skip the 1st < of << form if (*word == '>' && word[1] == '>') ++nextTokenStart; // skip the 1st > of >> form nextTokenStart = SkipWhitespace(nextTokenStart+1); // ignore blanks after if token is a simple single thing like ! char c = *word; if (deeptrace) Log(STDUSERLOG,(char*)" token:%s ",word); switch(c) { // prefixs on tokens case '!': // NOT condition - not a stand-alone token, attached to another token ptr = nextTokenStart; statusBits |= NOT_BIT; if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERLOG,(char*)"!"); if (*ptr == '!') { ptr = SkipWhitespace(nextTokenStart+1); statusBits |= NOTNOT_BIT; if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERLOG,(char*)"!"); } continue; case '\'': // single quoted item if (!stricmp(word,(char*)"'s")) { matched = MatchTest(reverse,FindWord(word),(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,NULL,NULL, statusBits & QUOTE_BIT,uppercasematch,positionStart,positionEnd); if (!matched || !(wildcardSelector & WILDMEMORIZESPECIFIC)) uppercasematch = false; if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; break; } else { statusBits |= QUOTE_BIT; ptr = nextTokenStart; if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERLOG,(char*)"'"); continue; } case '_': // memorization coming - there can be up-to-two memorizations in progress: _* and _xxx OR simply names a memorized value like _8 // a wildcard id? if (IsDigit(word[1])) { matched = GetwildcardText(GetWildcardID(word),false)[0] != 0; // simple _2 means is it defined break; } ptr = nextTokenStart; // if we are going to memorize something AND we previously matched inside a phrase, we need to move to after... if ((positionStart - positionEnd) == 1 && !reverse) positionEnd = positionStart; // If currently matched a phrase, move to end. else if ((positionEnd - positionStart) == 1 && reverse) positionStart = positionEnd; // If currently matched a phrase, move to end. uppercasematch = false; // specifics are fixed values in length, gaps are unknown lengths if (ptr[0] != '*') wildcardSelector |= WILDMEMORIZESPECIFIC; // no wildcard else if (IsDigit(ptr[1])) wildcardSelector |= WILDMEMORIZESPECIFIC; // specific gap like *2 else if (ptr[1] == '~') wildcardSelector |= WILDMEMORIZEGAP; // variable gap like *~2 else if ( ptr[1] == '-') wildcardSelector |= WILDMEMORIZESPECIFIC; // backwards specific gap like *-4 else if (ptr[0] == '*' && IsAlphaUTF8(ptr[1])) wildcardSelector |= WILDMEMORIZESPECIFIC; // *dda* pattern else wildcardSelector |= WILDMEMORIZEGAP; // variable gap if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERLOG,(char*)"_"); continue; case '@': // factset ref if (word[1] == '_') // set positional reference @_20+ or @_0- { if (firstMatched < 0) firstMatched = NORETRY; // cannot retry this match locally // memorize gap to end based on direction...xxxx if (gap && !reverse) // close to end of sentence { positionStart = wordCount; // pretend to match at end of sentence int start = gap & 0x000000ff; int limit = (gap >> 8); gap = 0; // turn off if ((positionStart + 1 - start) > limit) // too long til end { matched = false; wildcardSelector &= -1 ^ WILDMEMORIZEGAP; break; } if (wildcardSelector & WILDMEMORIZEGAP) { SetWildCard(start,wordCount,true); // legal swallow of gap // request memorize wildcardSelector &= -1 ^ WILDMEMORIZEGAP; } } char* end = word+3; // skip @_2 if (IsDigit(*end)) ++end; // point to proper + or - ending unsigned int wild = wildcardPosition[GetWildcardID(word+1)]; if (*end == '+') { positionStart = WILDCARD_START(wild); positionEnd = WILDCARD_END(wild); reverse = false; } else if (*end == '-') { reverse = true; positionStart = WILDCARD_END(wild); positionEnd = WILDCARD_START(wild); } if (!positionEnd) break; oldEnd = positionEnd; // forced match ok oldStart = positionStart; if (trace & TRACE_PATTERN && CheckTopicTrace()) { if (positionStart <= 0 || positionStart > wordCount || positionEnd <= 0 || positionEnd > wordCount) Log(STDUSERLOG, "(index:%d)",positionEnd); else if (positionStart == positionEnd) Log(STDUSERLOG,(char*)"(word:%s index:%d)",wordStarts[positionEnd],positionEnd); else Log(STDUSERLOG,(char*)"(word:%s-%s index:%d-%d)",wordStarts[positionStart],wordStarts[positionEnd],positionStart,positionEnd); } matched = true; } else { int set = GetSetID(word); if (set == ILLEGAL_FACTSET) matched = false; else matched = FACTSET_COUNT(set) != 0; } break; case '<': // sentence start marker OR << >> set if (firstMatched < 0) firstMatched = NORETRY; // cannot retry this match if (word[1] == '<') goto DOUBLELEFT; // << else { ptr = nextTokenStart; if (gap && !reverse) // cannot memorize going forward to start of sentence { gap = 0; matched = false; wildcardSelector &= -1 ^ WILDMEMORIZEGAP; } else { // match can FORCE it to go to start from any direction positionStart = positionEnd = 0; // idiom < * and < _* handled under * matched = true; } } break; case '>': // sentence end marker if (word[1] == '>') goto DOUBLERIGHT; // >> closer, and reset to start of sentence wild again... ptr = nextTokenStart; if (gap && reverse) // cannot memorize going backward to end of sentence { gap = 0; matched = false; wildcardSelector &= -1 ^ WILDMEMORIZEGAP; } else if (gap || positionEnd == wordCount)// you can go to end from anywhere if you have a gap OR you are there { matched = true; positionStart = positionEnd = wordCount + 1; // pretend to match a word off end of sentence } else matched = false; break; case '*': // GAP - accept anything (perhaps with length restrictions) if (word[1] == '-') // backward gap, -1 is word before now -- BUG does not respect unmark system { int at = positionEnd - (word[2] - '0') - 1; // limited to 9 back if (at >= 0) // no earlier than pre sentence start { oldEnd = at; // set last match BEFORE our word positionStart = positionEnd = at + 1; // cover the word now matched = true; } else matched = false; } else if (IsDigit(word[1])) // fixed length gap { int at; int count = word[1] - '0'; // how many to swallow if (reverse) { int begin = positionStart -1; at = positionStart; // start here while (count-- && --at >= 1) // can we swallow this (not an ignored word) { if (unmarked[at]) { ++count; // ignore this word if (at == begin) --begin; // ignore this as starter } } if (at >= 1 ) // pretend match { positionEnd = begin ; // pretend match here - wildcard covers the gap positionStart = at; matched = true; } else matched = false; } else { at = positionEnd; // start here int begin = positionEnd + 1; while (count-- && ++at <= wordCount) // can we swallow this (not an ignored word) { if (unmarked[at]) { ++count; // ignore this word if (at == begin) ++begin; // ignore this as starter } } if (at <= wordCount ) // pretend match { positionStart = begin; // pretend match here - wildcard covers the gap positionEnd = at; matched = true; } else matched = false; } } else if (IsAlphaUTF8(word[1]) || word[1] == '*') matched = FindPartialInSentenceTest(word+1,(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,positionStart,reverse, positionStart,positionEnd); // wildword match like st*m* or *team* matches steamroller else // variable gap { if (word[1] == '~') gap = (word[2]-'0') << 8; // *~3 - limit 9 back else // I * meat { gap = 200 << 8; // 200 is a safe infinity if (positionStart == 0) positionStart = INFINITE_MATCH; // < * resets to allow match anywhere } gap |= (reverse) ? (positionStart - 1) : (positionEnd + 1); if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERLOG,(char*)"%s ",word); continue; } break; case '$': // is user variable defined { char* val = GetUserVariable(word); matched = *val ? true : false; } break; case '^': // function call, function argument or indirect function variable assign ref like ^$$tmp = null if (IsDigit(word[1]) || word[1] == '$' || word[1] == '_') // macro argument substitution or indirect function variable { argumentText = ptr; // transient substitution of text if (IsDigit(word[1])) ptr = callArgumentList[word[1]-'0'+fnVarBase]; // nine argument limit else if (word[1] == '$') ptr = GetUserVariable(word+1); // get value of variable and continue in place else ptr = wildcardCanonicalText[GetWildcardID(word+1)]; // ordinary wildcard substituted in place (bug)? if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERLOG,(char*)"%s=>",word); continue; } D = FindWord(word,0); // find the function if (!D || !(D->internalBits & FUNCTION_NAME)) matched = false; // shouldnt fail else if (D->x.codeIndex) // system function - execute it { char* old = currentOutputBase; char* oldrule = currentRuleOutputBase; currentRuleOutputBase = currentOutputBase = AllocateBuffer(); // start an independent buffer FunctionResult result; matching = true; ptr = DoFunction(word,ptr,currentOutputBase,result); matching = false; matched = !(result & ENDCODES); // allowed to do comparisons on answers from system functions but cannot have space before them, but not from user macros if (*ptr == '!' && ptr[1] == ' ' ){;} // simple not operator else if (ptr[1] == '<' || ptr[1] == '>'){;} // << and >> are not comparison operators in a pattern else if (IsComparison(*ptr) && *(ptr-1) != ' ' && (*ptr != '!' || ptr[1] == '=')) // ! w/o = is not a comparison { char op[10]; char* opptr = ptr; *op = *opptr; op[1] = 0; char* rhs = ++opptr; if (*opptr == '=') // was == or >= or <= or &= { op[1] = '='; op[2] = 0; ++rhs; } char copy[MAX_WORD_SIZE]; ptr = ReadCompiledWord(rhs,copy); rhs = copy; if (*rhs == '^') // local function argument or indirect ^$ var is LHS. copy across real argument { char* at = ""; if (rhs[1] == '$') at = GetUserVariable(rhs+1); else if (IsDigit(rhs[1])) at = callArgumentList[rhs[1]-'0'+fnVarBase]; at = SkipWhitespace(at); strcpy(rhs,at); } if (*op == '?' && opptr[0] != '~') { bool junk; matched = MatchTest(reverse,FindWord(currentOutputBase), (positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,NULL,NULL,false,junk, positionStart,positionEnd); if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; // first SOLID match } else { int id; char word1val[MAX_WORD_SIZE]; char word2val[MAX_WORD_SIZE]; result = HandleRelation(currentOutputBase,op,rhs,false,id,word1val,word2val); matched = (result & ENDCODES) ? 0 : 1; } } FreeBuffer(); currentOutputBase = old; currentRuleOutputBase = oldrule; } else // user function - execute it in pattern context as continuation of current code { if (functionNest >= MAX_PAREN_NEST) // fail, too deep nesting { matched = false; break; } // save old base data baseStack[functionNest] = callArgumentBase; argStack[functionNest] = callArgumentIndex; fnVarBaseStack[functionNest] = fnVarBase; if ((trace & TRACE_PATTERN || D->internalBits & MACRO_TRACE) && CheckTopicTrace()) Log(STDUSERLOG,(char*)"((char*)"); ptr += 2; // skip ( and space // read arguments while (*ptr && *ptr != ')' ) { char* arg = callArgumentList[callArgumentIndex++]; ptr = ReadArgument(ptr,arg); // gets the unevealed arg if ((trace & TRACE_PATTERN || D->internalBits & MACRO_TRACE) && CheckTopicTrace()) Log(STDUSERLOG,(char*)" %s, ",arg); } if ((trace & TRACE_PATTERN || D->internalBits & MACRO_TRACE) && CheckTopicTrace()) Log(STDUSERLOG,(char*)")\r\n"); fnVarBase = callArgumentBase = argStack[functionNest]; ptrStack[functionNest++] = ptr+2; // skip closing paren and space ptr = (char*) D->w.fndefinition + 1; // continue processing within the macro, skip argument count oldecho = echo; oldtrace = trace; if (D->internalBits & MACRO_TRACE && CheckTopicTrace()) { trace = (unsigned int)-1; echo = true; } if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERLOG,(char*)"%s=> ",word); continue; } break; case 0: // end of data (argument or function - never a real rule) if (argumentText) // return to normal from argument substitution { ptr = argumentText; argumentText = NULL; continue; } else if (functionNest > startNest) // function call end { if (trace & TRACE_PATTERN && CheckTopicTrace()) Log(STDUSERTABLOG,(char*)""); --functionNest; callArgumentIndex = argStack[functionNest]; // end of argument list (for next argument set) callArgumentBase = baseStack[functionNest]; // base of callArgumentList fnVarBase = fnVarBaseStack[functionNest]; ptr = ptrStack[functionNest]; // continue using prior code trace = oldtrace; echo = oldecho; continue; } else { ChangeDepth(-1,(char*)"Match"); globalDepth = startdepth; return false; // shouldn't happen } break; DOUBLELEFT: case '(': case '[': case '{': // nested condition (required or optional) (= consecutive [ = choice { = optional << all of // we make << also a depth token ptr = nextTokenStart; hold = wildcardIndex; { if (wildcardSelector & WILDMEMORIZESPECIFIC) { pendingMatch = wildcardIndex; // on match later, use this matchvar SetWildCard(1,1,true); // dummy match } int oldgap = gap; int returnStart = positionStart; int returnEnd = positionEnd; int rStart = positionStart; int rEnd = positionEnd; unsigned int oldselect = wildcardSelector; wildcardSelector = 0; bool uppercasemat = false; // nest inherits gaps leading to it. memorization requests withheld til he returns int whenmatched = 0; char* type = "["; if (*word == '(') type = "("; else if (*word == '{') type = "{"; else if (*word == '<') { type = "<<"; positionEnd = startposition; // allowed to pick up after here - oldStart/oldEnd synch automatically works positionStart = INFINITE_MATCH; rEnd = 0; rStart = INFINITE_MATCH; } matched = Match(ptr,depth+1,positionEnd,type, positionStart == INFINITE_MATCH,gap,wildcardSelector,returnStart, returnEnd,uppercasemat,whenmatched,positionStart,positionEnd,reverse); // subsection ok - it is allowed to set position vars, if ! get used, they dont matter because we fail wildcardSelector = oldselect; if (matched) { if (!(statusBits & NOT_BIT) && firstMatched < 0) firstMatched = whenmatched; positionStart = returnStart; if (positionStart == INFINITE_MATCH && returnStart > 0 && returnStart != INFINITE_MATCH) positionStart = returnEnd; positionEnd = returnEnd; if (*word == '<') // allows thereafter to be anywhere { positionStart = INFINITE_MATCH; oldEnd = oldStart = positionEnd = 0; } if (wildcardSelector) gap = oldgap; // to size a gap uppercasematch = uppercasemat; // The whole thing matched but if @_ was used, which way it ran and what to consider the resulting zone is completely confused. // So force a tolerable meaning so it acts like it is contiguous to caller. If we are memorizing it may be silly but its what we can do. if (*word == '(' && positionStart == NORETRY) { positionEnd = positionStart = (reverse) ? (oldStart - 1) : (oldEnd + 1) ; // claim we only moved 1 unit } else if (positionEnd) oldEnd = (reverse) ? (positionEnd + 1) : (positionEnd - 1); // nested checked continuity, so we allow match whatever it found - but not if never set it (match didnt have words) if (*word == '{') { gap = oldgap; // restore any pending gap we didnt plug (eg *~2 {xx yy zz} a ) } } else if (*word == '{') { gap = oldgap; // restore any pending gap we didnt plug (eg *~2 {xx yy zz} a ) } else // no match for ( or [ or << means we have to restore old positions regardless of what happened inside { // but we should check why the positions were not properly restored from the match call...BUG positionStart = rStart; positionEnd = rEnd; } } ptr = BalanceParen(ptr); // skip over the material including closer if (!matched) // failed, revert wildcard index - if ! was used, we will need this { if (*word == '{') { if (wildcardSelector & WILDMEMORIZESPECIFIC) // we need to memorize failure because optional cant fail { wildcardSelector ^= WILDMEMORIZESPECIFIC; SetWildCardGiven(0, wordCount,true,pendingMatch); } pendingMatch = -1; if (gap) continue; // if we are waiting to close a wildcard, ignore our failed existence entirely statusBits |= NOT_BIT; // we didnt match and pretend we didnt want to } else // failure of [ and ( and << { wildcardSelector = 0; wildcardIndex = hold; } pendingMatch = -1; } break; DOUBLERIGHT: case ')': case ']': case '}' : // end sequence/choice/optional ptr = nextTokenStart; matched = (*kind == '(' || *kind == '<'); // [] and {} must be failures if we are here while ( ) and << >> are success if (gap) // pending gap - [ foo fum * ] and { foo fot * } are pointless but [*3 *2] is not { if (depth != 0) // for simplicity don't end with a gap { gap = wildcardSelector = 0; matched = false; // force match failure } else positionStart = wordCount + 1; // at top level a close implies > ) } break; case '"': // double quoted string matched = FindPhrase(word,(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd, reverse, positionStart,positionEnd); if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; // first SOLID match break; case '%': // system variable if (!word[1]) // simple % { bool junk; matched = MatchTest(reverse,FindWord(word),(positionEnd < basicStart && firstMatched < 0) ? basicStart: positionEnd,NULL,NULL, statusBits & QUOTE_BIT,junk,positionStart,positionEnd); // possessive 's if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; // first SOLID match } else matched = SysVarExists(word); break; case '?': // question sentence? ptr = nextTokenStart; if (!word[1]) matched = (tokenFlags & QUESTIONMARK) ? true : false; else matched = false; break; case '=': // a comparison test - never quotes the left side. Right side could be quoted // format is: = 1-bytejumpcodeToComparator leftside comparator rightside if (!word[1]) // the simple = being present { bool junk; matched = MatchTest(reverse,FindWord(word),(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,NULL,NULL, statusBits & QUOTE_BIT,junk,positionStart,positionEnd); // possessive 's if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; // first SOLID match } // if left side is anything but a variable $ or _ or @, it must be found in sentence and that is what we compare against else { char lhsside[MAX_WORD_SIZE]; char* lhs = lhsside; char op[10]; char rhsside[MAX_WORD_SIZE]; char* rhs = rhsside; DecodeComparison(word, lhs, op, rhs); if (trace) sprintf(word,(char*)"%s%s%s",lhs,op,rhs); if (*lhs == '^') DecodeFNRef(lhs); // local function arg indirect ^$ var or _ as LHS if (*rhs == '^') DecodeFNRef(rhs);// local function argument or indirect ^$ var is LHS. copy across real argument bool quoted = false; if (*lhs == '\'') // left side is quoted { ++lhs; quoted = true; } if (*op == '?' && *rhs != '~') // NOT a ? into a set test - means does this thing exist in sentence { char* val = ""; if (*lhs == '$') val = GetUserVariable(lhs); else if (*lhs == '_') val = (quoted) ? wildcardOriginalText[GetWildcardID(lhs)] : wildcardCanonicalText[GetWildcardID(lhs)]; else if (*lhs == '^' && IsDigit(lhs[1])) val = callArgumentList[lhs[1]-'0'+fnVarBase]; // nine argument limit else if (*lhs == '%') val = SystemVariable(lhs,NULL); else val = lhs; // direct word if (*val == '"') // phrase requires dynamic matching { matched = FindPhrase(val,(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd, reverse, positionStart,positionEnd); if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; // first SOLID match if (trace) sprintf(word,(char*)"%s(%s)%s",lhs,val,op); break; } bool junk; matched = MatchTest(reverse,FindWord(val),(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,NULL,NULL, quoted,junk,positionStart,positionEnd); if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; // first SOLID match if (trace) sprintf(word,(char*)"%s(%s)%s",lhs,val,op); break; } result = *lhs; if (result == '%' || result == '$' || result == '_' || result == '@' || (*op == '?' && rhs)) // otherwise for words and concepts, look up in sentence and check relation there { if (result == '_' && quoted) --lhs; // include the quote char word1val[MAX_WORD_SIZE]; char word2val[MAX_WORD_SIZE]; FunctionResult answer = HandleRelation(lhs,op,rhs,false,id,word1val,word2val); matched = (answer & ENDCODES) ? 0 : 1; if (trace) { if (!stricmp(lhs,word1val)) *word1val = 0; // dont need redundant constants in trace if (!stricmp(rhs,word2val)) *word2val = 0; // dont need redundant constants in trace if (*word1val && *word2val) sprintf(word,(char*)"%s(%s)%s%s(%s)",lhs,word1val,op,rhs,word2val); else if (*word1val) sprintf(word,(char*)"%s(%s)%s%s",lhs,word1val,op,rhs); else if (*word2val) sprintf(word,(char*)"%s%s%s(%s)",lhs,op,rhs,word2val); else sprintf(word,(char*)"%s%s%s",lhs,op,rhs); } } else // find and test { bool junk; matched = MatchTest(reverse,FindWord(lhs),(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,op,rhs, quoted,junk,positionStart,positionEnd); // MUST match later if (!matched) break; } } break; case '\\': // escape to allow [ ] () < > ' { } ! as words and 's possessive And anything else for that matter { bool junk; matched = MatchTest(reverse,FindWord(word+1),(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,NULL,NULL, statusBits & QUOTE_BIT,junk,positionStart,positionEnd); if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; if (matched) {} else if (word[1] == '!' ) matched = (wordCount && (tokenFlags & EXCLAMATIONMARK)); // exclamatory sentence else if (word[1] == '?') matched = (tokenFlags & QUESTIONMARK) ? true : false; // question sentence break; } case '~': // current topic ~ and named topic if (word[1] == 0) // current topic { matched = IsCurrentTopic(currentTopicID); // clearly we are executing rules from it but is the current topic interesting break; } // drop thru for all other ~ default: // ordinary words, concept/topic, numbers, : and ~ and | and & accelerator matched = MatchTest(reverse,FindWord(word),(positionEnd < basicStart && firstMatched < 0) ? basicStart : positionEnd,NULL,NULL, statusBits & QUOTE_BIT,uppercasematch,positionStart,positionEnd); if (!matched || !(wildcardSelector & WILDMEMORIZESPECIFIC)) uppercasematch = false; if (!(statusBits & NOT_BIT) && matched && firstMatched < 0) firstMatched = positionStart; }