wstring Compiler::CodeGenerator::visitActionSound(const Block* block) { static const int noteTable[5] = { 262, 311, 370, 440, 524 }; static const int durationTable[3] = {-1, 8, 15}; useSound = true; wstring text; const wstring indString(indentText()); text += indString; text += L"call math.copy(notes, ["; for (unsigned i = 0; i<block->valuesCount(); ++i) { const unsigned note(block->getValue(i) & 0xff); text += toWstring(noteTable[note]); if (i+1 != block->valuesCount()) text += L", "; } text += L"])\n"; text += indString; // durations text += L"call math.copy(durations, ["; for (unsigned i = 0; i<block->valuesCount(); ++i) { const unsigned duration((block->getValue(i)>>8) & 0xff); text += toWstring(durationTable[duration]); if (i+1 != block->valuesCount()) text += L", "; } text += L"])\n"; text += indString; text += L"call sound.freq(notes[0], durations[0])\n"; text += indString; text += L"note_index = 1\n"; return text; }
wstring Compiler::CodeGenerator::visitActionTopColor(const Block* block) { wstring text; const wstring indString(indentText()); text += indString; text += L"call leds.top("; text += toWstring(block->getValue(0)); text += L","; text += toWstring(block->getValue(1)); text += L","; text += toWstring(block->getValue(2)); text += L")\n"; return text; }
wstring Compiler::CodeGenerator::visitActionMove(const Block* block) { wstring text; const wstring indString(indentText()); text += indString; text += L"motor.left.target = "; text += toWstring(block->getValue(0)); text += L"\n"; text += indString; text += L"motor.right.target = "; text += toWstring(block->getValue(1)); text += L"\n"; return text; }
wstring Compiler::CodeGenerator::visitActionSetState(const Block* block) { wstring text; const wstring indString(indentText()); for(unsigned i=0; i<block->valuesCount(); ++i) { switch (block->getValue(i)) { case 1: text += indString + L"new_state[" + toWstring(i) + L"] = 1\n"; break; case 2: text += indString + L"new_state[" + toWstring(i) + L"] = 0\n"; break; default: break; // do nothing } } return text; }
std::string SystemLocaleToUtf8(const Utf8String& str) { std::locale const oloc = std::locale (""); std::wstring out; std::wstring wideStr; toWstring (str, oloc, wideStr); return WstringToUtf8(wideStr); }
wstring Compiler::CodeGenerator::visitActionTimer(const Block* block) { wstring text; const wstring indString(indentText()); text += indString; text += L"timer.period[0] = "+ toWstring(block->getValue(0)) + L"\n"; return text; }
//! Test, use computed angle wstring Compiler::CodeGenerator::visitEventAcc(const Block* block) { int testValue(0); if (block->getValue(0) == AccEventBlock::MODE_PITCH) testValue = block->getValue(1); else if (block->getValue(0) == AccEventBlock::MODE_ROLL) testValue = -block->getValue(1); else abort(); const int middleValue(testValue * 16384 / AccEventBlock::resolution); const int lowBound(middleValue - 8192 / AccEventBlock::resolution); const int highBound(middleValue + 8192 / AccEventBlock::resolution); wstring text; if (testValue != -AccEventBlock::resolution) text += L"angle > " + toWstring(lowBound); if (!text.empty() && (testValue != AccEventBlock::resolution)) text += L" and "; if (testValue != AccEventBlock::resolution) text += L"angle < " + toWstring(highBound); return text; }
wstring Compiler::CodeGenerator::visitEventProxGround(const Block* block) { wstring text; bool first(true); const unsigned slidersIndex(block->valuesCount()-2); for(unsigned i=0; i<slidersIndex; ++i) { if (block->getValue(i) == 1) { text += (first ? L"": L" and "); text += L"prox.ground.delta["; text += toWstring(i); text += L"] > " + toWstring(block->getValue(slidersIndex+1)); first = false; } else if (block->getValue(i) == 2) { text += (first ? L"": L" and "); text += L"prox.ground.delta["; text += toWstring(i); text += L"] < " + toWstring(block->getValue(slidersIndex)); first = false; } else if (block->getValue(i) == 3) { text += (first ? L"": L" and "); text += L"prox.ground.delta["; text += toWstring(i); text += L"] > " + toWstring(block->getValue(slidersIndex)); text += L" and prox.ground.delta["; text += toWstring(i); text += L"] < " + toWstring(block->getValue(slidersIndex+1)); first = false; } } return text; }
/*static */PkyStringW StringConvert::FromEUC(char const* psztxt, size_t count){ return toWstring(CP_EUC, psztxt, count); }
/*static */PkyStringW StringConvert::toWstring(char const* psztxt, size_t count) { return toWstring(CP_ACP, psztxt, count); }
std::wstring getVisualLine(const std::string&instring) { return toWstring(instring.c_str()); }
void Compiler::CodeGenerator::visitEventAndStateFilter(const Block* block, const Block* stateFilterBlock, unsigned currentBlock) { // generate event code wstring text; // if block generates a test if (block->isAnyValueSet()) { // pre-test code if (block->getName() == "acc") { text += visitEventAccPre(block); } // test code text += L"\twhen "; if (block->getName() == "button") { text += visitEventArrowButtons(block); } else if (block->getName() == "prox") { text += visitEventProx(block); } else if (block->getName() == "proxground") { text += visitEventProxGround(block); } else if (block->getName() == "acc") { text += visitEventAcc(block); } else { // internal compiler error abort(); } text += L" do\n"; inWhenBlock = true; } // if state filter does generate a test if (stateFilterBlock && stateFilterBlock->isAnyValueSet()) { if (inWhenBlock) text += L"\t"; text += L"\tif "; bool first(true); for (unsigned i=0; i<stateFilterBlock->valuesCount(); ++i) { switch (stateFilterBlock->getValue(i)) { case 1: if (!first) text += L" and "; text += L"state[" + toWstring(i) + L"] == 1"; first = false; break; case 2: if (!first) text += L" and "; text += L"state[" + toWstring(i) + L"] == 0"; first = false; break; default: break; } } text += L" then\n"; inIfBlock = true; } generatedCode[currentBlock] = text; }
wstring Compiler::CodeGenerator::visitActionSound(const Block* block) { static const int noteTable[6] = { 262, 311, 370, 440, 524, 0 }; static const int durationTable[3] = {-1, 7, 14}; // find last non-silent note unsigned noteCount(block->valuesCount()); assert(noteCount > 0); while ((noteCount > 0) && ((block->getValue(noteCount-1) & 0xff) == 5)) --noteCount; // if there is no note, return if (noteCount == 0) return indentText() + L"# zero notes in sound block\n"; // generate code for notes wstring notesCopyText; wstring durationsCopyText; unsigned accumulatedDuration(0); unsigned activeNoteCount(0); for (unsigned i = 0; i<noteCount; ++i) { const unsigned note(block->getValue(i) & 0xff); const unsigned duration((block->getValue(i)>>8) & 0xff); if (note == 5 && i+1 < noteCount && (block->getValue(i+1) & 0xff) == 5) { // next note is silence, skip accumulatedDuration += durationTable[duration]; } else { notesCopyText += toWstring(noteTable[note]); if (i+1 != noteCount) notesCopyText += L", "; durationsCopyText += toWstring(durationTable[duration]+accumulatedDuration); if (i+1 != noteCount) durationsCopyText += L", "; ++activeNoteCount; accumulatedDuration = 0; } } // enable sound useSound = true; // prepare target string wstring text; const wstring indString(indentText()); // notes text += indString; text += L"call math.copy(notes[0:"; text += toWstring(activeNoteCount-1); text += L"], ["; text += notesCopyText; text += L"])\n"; // durations text += indString; text += L"call math.copy(durations[0:"; text += toWstring(activeNoteCount-1); text += L"], ["; text += durationsCopyText; text += L"])\n"; // write variables text += indString; text += L"note_index = 1\n"; text += indString; text += L"note_count = " + toWstring(activeNoteCount) + L"\n"; // start playing text += indString; text += L"call sound.freq(notes[0], durations[0])\n"; return text; }