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