00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "tree.h"
00025 #include <cassert>
00026 #include <cstdlib>
00027
00028 namespace Aseba
00029 {
00032
00034 PreLinkBytecode::PreLinkBytecode()
00035 {
00036 events[ASEBA_EVENT_INIT] = BytecodeVector();
00037 current = &events[ASEBA_EVENT_INIT];
00038 };
00039
00042 void PreLinkBytecode::fixup(const Compiler::SubroutineTable &subroutineTable)
00043 {
00044
00045 for (EventsBytecode::iterator it = events.begin(); it != events.end();)
00046 {
00047 EventsBytecode::iterator curIt = it;
00048 ++it;
00049 size_t bytecodeSize = curIt->second.size();
00050 if (bytecodeSize == 0)
00051 {
00052 events.erase(curIt);
00053 }
00054 }
00055
00056
00057 for (EventsBytecode::iterator it = events.begin(); it != events.end(); ++it)
00058 {
00059 BytecodeVector& bytecode = it->second;
00060 bytecode.push_back(BytecodeElement(AsebaBytecodeFromId(ASEBA_BYTECODE_STOP), bytecode.lastLine));
00061 }
00062 for (SubroutinesBytecode::iterator it = subroutines.begin(); it != subroutines.end(); ++it)
00063 {
00064 BytecodeVector& bytecode = it->second;
00065 if (bytecode.size())
00066 bytecode.push_back(BytecodeElement(AsebaBytecodeFromId(ASEBA_BYTECODE_SUB_RET), bytecode.lastLine));
00067 else
00068 bytecode.push_back(BytecodeElement(AsebaBytecodeFromId(ASEBA_BYTECODE_SUB_RET), subroutineTable[it->first].line));
00069 }
00070 }
00071
00072
00073 unsigned Node::getStackDepth() const
00074 {
00075 unsigned stackDepth = 0;
00076 for (size_t i = 0; i < children.size(); i++)
00077 stackDepth = std::max(stackDepth, children[i]->getStackDepth());
00078 return stackDepth;
00079 }
00080
00081
00082 void BlockNode::emit(PreLinkBytecode& bytecodes) const
00083 {
00084 for (size_t i = 0; i < children.size(); i++)
00085 children[i]->emit(bytecodes);
00086 }
00087
00088 void ProgramNode::emit(PreLinkBytecode& bytecodes) const
00089 {
00090 BlockNode::emit(bytecodes);
00091
00092
00093 BytecodeVector* currentBytecode = &bytecodes.events[ASEBA_EVENT_INIT];
00094 unsigned maxStackDepth = 0;
00095 for (size_t i = 0; i < children.size(); i++)
00096 {
00097 EventDeclNode* eventDecl = dynamic_cast<EventDeclNode*>(children[i]);
00098 SubDeclNode* subDecl = dynamic_cast<SubDeclNode*>(children[i]);
00099 if (eventDecl || subDecl)
00100 {
00101 currentBytecode->maxStackDepth = maxStackDepth;
00102 maxStackDepth = 0;
00103
00104 if (eventDecl)
00105 currentBytecode = &bytecodes.events[eventDecl->eventId];
00106 else
00107 currentBytecode = &bytecodes.subroutines[subDecl->subroutineId];
00108 }
00109 else
00110 maxStackDepth = std::max(maxStackDepth, children[i]->getStackDepth());
00111 }
00112 currentBytecode->maxStackDepth = maxStackDepth;
00113 }
00114
00115
00116 void AssignmentNode::emit(PreLinkBytecode& bytecodes) const
00117 {
00118 children[1]->emit(bytecodes);
00119 children[0]->emit(bytecodes);
00120 }
00121
00122
00123 void IfWhenNode::emit(PreLinkBytecode& bytecodes) const
00124 {
00125 abort();
00126 }
00127
00128
00129 void FoldedIfWhenNode::emit(PreLinkBytecode& bytecodes) const
00130 {
00131 unsigned short bytecode;
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 BytecodeVector ble;
00146 BytecodeVector bre;
00147 BytecodeVector btb;
00148 BytecodeVector bfb;
00149
00150
00151 BytecodeVector* currentBytecode = bytecodes.current;
00152
00153
00154 bytecodes.current = &ble;
00155 children[0]->emit(bytecodes);
00156
00157 bytecodes.current = &bre;
00158 children[1]->emit(bytecodes);
00159
00160 bytecodes.current = &btb;
00161 children[2]->emit(bytecodes);
00162
00163 bytecodes.current = &bfb;
00164 if (children.size() > 3)
00165 children[3]->emit(bytecodes);
00166
00167
00168 bytecodes.current = currentBytecode;
00169
00170
00171 std::copy(ble.begin(), ble.end(), std::back_inserter(*bytecodes.current));
00172
00173 std::copy(bre.begin(), bre.end(), std::back_inserter(*bytecodes.current));
00174
00175 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_CONDITIONAL_BRANCH);
00176 bytecode |= op;
00177 bytecode |= edgeSensitive ? (1 << ASEBA_IF_IS_WHEN_BIT) : 0;
00178 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00179
00180 if (children.size() == 4)
00181 bytecodes.current->push_back(BytecodeElement(2 + btb.size() + 1, sourcePos.row));
00182 else
00183 bytecodes.current->push_back(BytecodeElement(2 + btb.size(), sourcePos.row));
00184
00185
00186 std::copy(btb.begin(), btb.end(), std::back_inserter(*bytecodes.current));
00187
00188 if (children.size() == 4)
00189 {
00190 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_JUMP) | (bfb.size() + 1);
00191 unsigned short jumpLine;
00192 if (btb.size())
00193 jumpLine = (btb.end()-1)->line;
00194 else
00195 jumpLine = sourcePos.row;
00196 bytecodes.current->push_back(BytecodeElement(bytecode , jumpLine));
00197
00198 std::copy(bfb.begin(), bfb.end(), std::back_inserter(*bytecodes.current));
00199 }
00200
00201 bytecodes.current->lastLine = endLine;
00202 }
00203
00204 unsigned FoldedIfWhenNode::getStackDepth() const
00205 {
00206 unsigned stackDepth = children[0]->getStackDepth() + children[1]->getStackDepth();
00207 stackDepth = std::max(stackDepth, children[2]->getStackDepth());
00208 if (children.size() == 4)
00209 stackDepth = std::max(stackDepth, children[3]->getStackDepth());
00210 return stackDepth;
00211 }
00212
00213
00214 void WhileNode::emit(PreLinkBytecode& bytecodes) const
00215 {
00216 abort();
00217 }
00218
00219
00220 void FoldedWhileNode::emit(PreLinkBytecode& bytecodes) const
00221 {
00222 unsigned short bytecode;
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 BytecodeVector ble;
00236 BytecodeVector bre;
00237 BytecodeVector bb;
00238
00239
00240 BytecodeVector* currentBytecode = bytecodes.current;
00241
00242
00243 bytecodes.current = &ble;
00244 children[0]->emit(bytecodes);
00245
00246 bytecodes.current = &bre;
00247 children[1]->emit(bytecodes);
00248
00249 bytecodes.current = &bb;
00250 children[2]->emit(bytecodes);
00251
00252
00253 bytecodes.current = currentBytecode;
00254
00255
00256 std::copy(ble.begin(), ble.end(), std::back_inserter(*bytecodes.current));
00257
00258 std::copy(bre.begin(), bre.end(), std::back_inserter(*bytecodes.current));
00259
00260 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_CONDITIONAL_BRANCH) | op;
00261 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00262 bytecodes.current->push_back(BytecodeElement(2 + bb.size() + 1, sourcePos.row));
00263
00264 std::copy(bb.begin(), bb.end(), std::back_inserter(*bytecodes.current));
00265
00266 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_JUMP);
00267 bytecode |= ((unsigned)(-(int)(ble.size() + bre.size() + bb.size() + 2))) & 0x0fff;
00268 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00269 }
00270
00271 unsigned FoldedWhileNode::getStackDepth() const
00272 {
00273 unsigned stackDepth = children[0]->getStackDepth() + children[1]->getStackDepth();
00274 stackDepth = std::max(stackDepth, children[2]->getStackDepth());
00275 return stackDepth;
00276 }
00277
00278
00279 void EventDeclNode::emit(PreLinkBytecode& bytecodes) const
00280 {
00281
00282 assert(bytecodes.events.find(eventId) == bytecodes.events.end());
00283
00284
00285 bytecodes.events[eventId] = BytecodeVector();
00286 bytecodes.current = &bytecodes.events[eventId];
00287 }
00288
00289
00290 void EmitNode::emit(PreLinkBytecode& bytecodes) const
00291 {
00292 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_EMIT) | eventId;
00293 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00294 bytecodes.current->push_back(BytecodeElement(arrayAddr, sourcePos.row));
00295 bytecodes.current->push_back(BytecodeElement(arraySize, sourcePos.row));
00296 }
00297
00298
00299 void SubDeclNode::emit(PreLinkBytecode& bytecodes) const
00300 {
00301
00302 assert(bytecodes.subroutines.find(subroutineId) == bytecodes.subroutines.end());
00303
00304
00305 bytecodes.subroutines[subroutineId] = BytecodeVector();
00306 bytecodes.current = &bytecodes.subroutines[subroutineId];
00307 }
00308
00309
00310 void CallSubNode::emit(PreLinkBytecode& bytecodes) const
00311 {
00312 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_SUB_CALL);
00313 bytecode |= subroutineId;
00314 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00315 }
00316
00317
00318 void BinaryArithmeticNode::emit(PreLinkBytecode& bytecodes) const
00319 {
00320 children[0]->emit(bytecodes);
00321 children[1]->emit(bytecodes);
00322 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_BINARY_ARITHMETIC) | op;
00323 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00324 }
00325
00326 unsigned BinaryArithmeticNode::getStackDepth() const
00327 {
00328 return children[0]->getStackDepth() + children[1]->getStackDepth();
00329 }
00330
00331
00332 void UnaryArithmeticNode::emit(PreLinkBytecode& bytecodes) const
00333 {
00334 children[0]->emit(bytecodes);
00335 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_UNARY_ARITHMETIC) | op;
00336 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00337 }
00338
00339
00340 void ImmediateNode::emit(PreLinkBytecode& bytecodes) const
00341 {
00342 unsigned short bytecode;
00343
00344 if ((abs(value) >> 11) == 0)
00345 {
00346 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_SMALL_IMMEDIATE);
00347 bytecode |= ((unsigned)value) & 0x0fff;
00348 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00349 }
00350 else
00351 {
00352 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_LARGE_IMMEDIATE);
00353 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00354 bytecodes.current->push_back(BytecodeElement(value, sourcePos.row));
00355 }
00356 }
00357
00358 unsigned ImmediateNode::getStackDepth() const
00359 {
00360 return 1;
00361 }
00362
00363
00364 void LoadNode::emit(PreLinkBytecode& bytecodes) const
00365 {
00366 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_LOAD) | varAddr;
00367 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00368 }
00369
00370 unsigned LoadNode::getStackDepth() const
00371 {
00372 return 1;
00373 }
00374
00375
00376 void StoreNode::emit(PreLinkBytecode& bytecodes) const
00377 {
00378 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_STORE) | varAddr;
00379 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00380 }
00381
00382
00383 void ArrayReadNode::emit(PreLinkBytecode& bytecodes) const
00384 {
00385
00386 ImmediateNode* immediateChild = dynamic_cast<ImmediateNode*>(children[0]);
00387 assert(immediateChild == 0);
00388
00389 children[0]->emit(bytecodes);
00390
00391 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_LOAD_INDIRECT) | arrayAddr;
00392 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00393 bytecodes.current->push_back(BytecodeElement(arraySize, sourcePos.row));
00394 }
00395
00396
00397 void ArrayWriteNode::emit(PreLinkBytecode& bytecodes) const
00398 {
00399
00400 ImmediateNode* immediateChild = dynamic_cast<ImmediateNode*>(children[0]);
00401 assert(immediateChild == 0);
00402
00403 children[0]->emit(bytecodes);
00404
00405 unsigned short bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_STORE_INDIRECT) | arrayAddr;
00406 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00407 bytecodes.current->push_back(BytecodeElement(arraySize, sourcePos.row));
00408 }
00409
00410
00411 void CallNode::emit(PreLinkBytecode& bytecodes) const
00412 {
00413 unsigned short bytecode;
00414
00415
00416 for (size_t i = 0; i < children.size(); i++)
00417 children[i]->emit(bytecodes);
00418
00419
00420 int i = (int)argumentsAddr.size() - 1;
00421 while (i >= 0)
00422 {
00423 if ((abs(argumentsAddr[i]) >> 11) == 0)
00424 {
00425 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_SMALL_IMMEDIATE);
00426 bytecode |= ((unsigned)argumentsAddr[i]) & 0x0fff;
00427 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00428 }
00429 else
00430 {
00431 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_LARGE_IMMEDIATE);
00432 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00433 bytecodes.current->push_back(BytecodeElement(argumentsAddr[i], sourcePos.row));
00434 }
00435 i--;
00436 }
00437
00438
00439 bytecode = AsebaBytecodeFromId(ASEBA_BYTECODE_NATIVE_CALL) | funcId;
00440 bytecodes.current->push_back(BytecodeElement(bytecode, sourcePos.row));
00441 }
00442
00443 unsigned CallNode::getStackDepth() const
00444 {
00445 size_t stackDepth = Node::getStackDepth();
00446
00447
00448 stackDepth = std::max(stackDepth, argumentsAddr.size());
00449
00450 return stackDepth;
00451 }
00452
00453
00456 };