Example #1
0
void ECodesAssembler :: readMessage(TokenInfo& token, int& verbId, IdentifierString& subject, int& paramCount)
{
   verbId = mapVerb(token.value);
   if (verbId == 0) {
      if (token.check("dispatch")) {
         verbId = DISPATCH_MESSAGE_ID;
      }
      else verbId = EVAL_MESSAGE_ID;
   }

   token.read();
   while (token.value[0] == '&') {
      subject.append(token.value);

      token.read();
      subject.append(token.value);
      token.read();
      if (token.value[0] == '$') {
         subject.append(token.value);
         token.read();
      }
   }
   if (token.value[0] == '[') {
      paramCount = token.readInteger(constants);
   }
   else token.raiseErr("Invalid operand (%d)");

   token.read("]", "Invalid operand (%d)");
}
Example #2
0
void printReference(IdentifierString& command, _Module* module, size_t reference)
{
   bool literalConstant = false;
   const wchar16_t* referenceName = NULL;
   int mask = reference & mskAnyRef;
   if (mask == mskInt32Ref) {
      referenceName = _integer;
      literalConstant = true;
   }
   //else if (mask == mskInt64Ref) {
   //   referenceName = _long;
   //   literalConstant = true;
   //}
   //else if (mask == mskLiteralRef) {
   //   referenceName = _literal;
   //   literalConstant = true;
   //}
   //else if (mask == mskRealRef) {
   //   referenceName = _real;
   //   literalConstant = true;
   //}
   else referenceName = module->resolveReference(reference & ~mskAnyRef);

   if (emptystr(referenceName)) {
      command.append(_T("unknown"));
   }
   else {
      command.append(referenceName);
      if (literalConstant) {
         command.append(_T("("));
         command.append(module->resolveConstant(reference & ~mskAnyRef));
         command.append(_T(")"));
      }
   }
}
Example #3
0
inline void appendHex32(IdentifierString& command, unsigned int hex)
{
   unsigned int len = hex / 0x10 + 1;
   while (len < 8) {
      command.append(_T('0'));
      len++;
   }

   command.appendHex(hex);
}
Example #4
0
void printMessage(IdentifierString& command, _Module* module, size_t reference)
{
   size_t signRef = 0;
   int verb = 0;
   int paramCount = 0;
   decodeMessage(reference, signRef, verb, paramCount);

   if (verb == SEND_MESSAGE_ID) {
      command.append(_T("resend"));
   }
   else if (verb == DISPATCH_MESSAGE_ID) {
      command.append(_T("dispatch"));
   }
   else if (verb == NEWOBJECT_MESSAGE_ID) {
      command.append(_T("new[0]"));
   }
   else {
      const wchar16_t* verbName = retrieveKey(_verbs.start(), verb, (const wchar16_t*)NULL);
      command.append(verbName);
   }

   if (signRef != 0) {
      const wchar16_t* subjectName = module->resolveSubject(signRef);
      command.append(_T('&'));
      command.append(subjectName);
   }

   if (paramCount > 0) {
      command.append('[');
      command.appendInt(paramCount);
      command.append(']');
   }
}
Example #5
0
ref_t ECodesAssembler :: compileRMessageArg(TokenInfo& token, _Module* binary)
{
   IdentifierString message;
   IdentifierString subject;

   int paramCount = 0;
   int verbId = 0;
   
   readMessage(token, verbId, subject, paramCount);

   // reserve place for param counter
   message.append('0');

   // if it is not a verb - by default it is EVAL message
   if (verbId == 0) {
      message.append('#');
      message.append(EVAL_MESSAGE_ID + 0x20);
      message.append('&');
      message.append(verbId);
   }
   else {
      message.append('#');
      message.append(verbId + 0x20);
   }

   message.append(subject);

   message[0] = message[0] + paramCount;

   return binary->mapReference(message) | mskMessage;
}
Example #6
0
void listClassMethods(_Module* module, ident_t className, int pageSize, bool fullInfo, bool withConstructors)
{
   className = trim(className);

   // find class VMT
   _Memory* vmt = findClassVMT(module, className);
   if (vmt == NULL) {
      printLine("Class not found:", className);

      return;
   }

   // list methods
   MemoryReader vmtReader(vmt);
   // read tape record size
   size_t size = vmtReader.getDWord();

   // read VMT info
   ClassHeader header;
   vmtReader.read((void*)&header, sizeof(ClassHeader));

   int row = 0;

   if (fullInfo) {
      if (header.parentRef) {
         printLine("@parent ", module->resolveReference(header.parentRef));
         row++;
      }         

      listFlags(header.flags, row, pageSize);
      listFields(module, className, row, pageSize);
   }

   //if (header.classRef != 0 && withConstructors) {
   //   listConstructorMethods(module, className, header.classRef);
   //}

   VMTEntry        entry;

   size -= sizeof(ClassHeader);
   IdentifierString temp;
   while (size > 0) {
      vmtReader.read((void*)&entry, sizeof(VMTEntry));

      // print the method name
      temp.copy(className);
      temp.append('.');
      printMessage(temp, module, entry.message);
      printLine("@method ", temp);

      nextRow(row, pageSize);

      size -= sizeof(VMTEntry);
   }
}
Example #7
0
void printReference(IdentifierString& command, _Module* module, size_t reference)
{
   bool literalConstant = false;
   bool charConstant = false;
   ident_t referenceName = NULL;
   int mask = reference & mskAnyRef;
   if (mask == mskInt32Ref) {
      referenceName = _integer;
      literalConstant = true;
   }
   else if (mask == mskInt64Ref) {
      referenceName = _long;
      literalConstant = true;
   }
   else if (mask == mskLiteralRef) {
      referenceName = _literal;
      literalConstant = true;
   }
   else if (mask == mskWideLiteralRef) {
      referenceName = _wide;
      literalConstant = true;
   }
   else if (mask == mskRealRef) {
      referenceName = _real;
      literalConstant = true;
   }
   else if (mask == mskCharRef) {
      referenceName = _char;
      charConstant = true;
   }
   else if (reference == 0) {
      referenceName = "nil";
   }
   else if (reference == -1) {
      referenceName = "undefined";
   }
   else referenceName = module->resolveReference(reference & ~mskAnyRef);

   if (emptystr(referenceName)) {
      command.append("unknown");
   }
   else {
      command.append(referenceName);
      if (literalConstant) {
         command.append("(");
         command.append(module->resolveConstant(reference & ~mskAnyRef));
         command.append(")");
      }
      else if (charConstant) {
         const char* ch = module->resolveConstant(reference & ~mskAnyRef);

         IdentifierString num;
         num.appendInt(ch[0]);
         command.append("(");
         command.append(num);
         command.append(")");

      }
   }
}
Example #8
0
void VMTapeParser :: writeSubject(TapeWriter& writer, ident_t message)
{
   IdentifierString reference;
   reference.append('0');
   reference.append('#');
   reference.append(0x20);
   reference.append('&');
   reference.append(message);

   writer.writeCommand(PUSHG_TAPE_MESSAGE_ID, reference);
}
Example #9
0
void runSession(_Module* module)
{
   char              buffer[MAX_LINE];
   IdentifierString  line;
   int               pageSize = 30;
   while (true) {
      wprintf(_T("\n>"));

      // !! fgets is used instead of fgetws, because there is strange bug in fgetws implementation
      fgets(buffer, MAX_LINE, stdin);
      line.copy(buffer, strlen(buffer));

      while (!emptystr(line) && line[getlength(line) - 1]=='\r' || line[getlength(line) - 1]=='\n')
         line[getlength(line) - 1] = 0;

      while (!emptystr(line) && line[getlength(line) - 1]==' ')
         line[getlength(line) - 1] = 0;

      // execute command
      if (line[0]=='-') {
         switch(line[1]) {
            case 'q':
               return;
            case 'h':
               printHelp();
               break;
            case 'm':
               printMethod(module, line + 2, pageSize);
               break;
            //case 'c':
            //   printConstructor(module, line + 2, pageSize);
            //   break;
            case 's':
               printSymbol(module, line + 2, pageSize);
               break;
            case 'l':
               if (line[2]=='m') {
                  listClassMethods(module, line + 3, pageSize);
               }
               //else if (line[2]=='r') {
               //   listClassRoles(module, line + 3, pageSize);
               //}
               else listClasses(module, pageSize);
               break;
            case 'o':
               setOutputMode(line + 2);
               break;
            default:
               printHelp();
         }
      }
      else printHelp();
   }
}
Example #10
0
inline void findUninqueName(_Module* module, IdentifierString& name)
{
   size_t pos = getlength(name);
   int   index = 0;
   ref_t ref = 0;
   do {
      name[pos] = 0;
      name.appendHex(index++);

      ref = module->mapReference(name.c_str(), true);
   } while (ref != 0);
}
Example #11
0
ref_t ECodesAssembler::compileMessageArg(TokenInfo& token, _Module* binary)
{
   IdentifierString subject;
   int paramCount = 0;
   int verbId = 0;

   readMessage(token, verbId, subject, paramCount);

   if (subject.Length() > 0) {
      return encodeMessage(binary->mapSubject(subject + 1, false), verbId, paramCount);
   }
   else return encodeMessage(0, verbId, paramCount);
}
Example #12
0
bool VMTapeParser :: writeExtension(TapeWriter& writer, ident_t message, int command)
{
   IdentifierString reference;

   size_t dotPos = message.find('.');
   if (parseMessage(message + dotPos + 1, reference)) {
      reference.insert(message, 0, dotPos + 1);

      writer.writeCommand(command, reference);

      return true;
   }
   else return false;
}
Example #13
0
bool VMTapeParser :: parseMessage(ident_t message, IdentifierString& reference)
{
   int paramCounter = 0;
   size_t length = getlength(message);
   length = message.find('[');
   if (length != NOTFOUND_POS) {
      reference.copy(message + length + 1);
      if (reference[reference.Length() - 1] == ']') {
         reference.truncate(reference.Length() - 1);
         //if (emptystr(reference)) {
         //   paramCounter = OPEN_ARG_COUNT;
         //}
         /*else */paramCounter = reference.ident().toInt();

      }
      else return false;
   }
   else return false;

   reference.clear();
   reference.append('0' + (char)paramCounter);
   reference.append(message, length);

   return true;
}
Example #14
0
void ECodesAssembler :: compileMessage(TokenInfo& token, IdentifierString& message)
{
   IdentifierString subject;

   int paramCount = 0;
   int verbId = 0;

   readMessage(token, verbId, subject, paramCount);

   // reserve place for param counter
   message.append('0');

   // if it is not a verb - by default it is EVAL message
   if (verbId == 0) {
      message.append('#');
      message.append(EVAL_MESSAGE_ID + 0x20);
      message.append('&');
      message.append(verbId);
   }
   else {
      message.append('#');
      message.append(verbId + 0x20);
   }

   message.append(subject);

   message[0] = message[0] + paramCount;
}
Example #15
0
void listClassMethods(_Module* module, const wchar_t* className, int pageSize)
{
   className = trim(className);

   // find class VMT
   ReferenceNs reference(module->Name(), className);
   _Memory* vmt = findClassVMT(module, reference);
   if (vmt == NULL) {
      wprintf(_T("Class %s not found\n"), (const wchar_t*)reference);

      return;
   }

   // list methods
   MemoryReader vmtReader(vmt);
   // read tape record size
   size_t size = vmtReader.getDWord();

   // read VMT header
   ClassHeader header;
   vmtReader.read((void*)&header, sizeof(ClassHeader));
   int vmtSize = vmtReader.getDWord();

   VMTEntry        entry;

   size -= sizeof(ClassHeader) + 4;
   IdentifierString temp;
   int row = 0;
   while (size > 0) {
      vmtReader.read((void*)&entry, sizeof(VMTEntry));

      // print the method name
      temp.copy(className);
      temp.append('.');
      printMessage(temp, module, entry.message);
      printLine(_T("@method "), temp);

      row++;
      if (row == pageSize) {
         wprintf(_T("Press any key to continue..."));
         fgetchar();
         wprintf(_T("\n"));

         row = 0;
      }

      size -= sizeof(VMTEntry);
   }
}
Example #16
0
void printLabel(IdentifierString& command, int labelPosition, List<int>& labels)
{
   int index = getLabelIndex(labelPosition, labels);
   if (index == -1) {
      index = labels.Count();

      labels.add(labelPosition);
   }

   command.append("Lab");
   if (index < 10) {
      command.append('0');
   }
   command.appendInt(index);
}
Example #17
0
void ECodesAssembler :: compileMCommand(ByteCode code, TokenInfo& token, MemoryWriter& writer, _Module* binary)
{
   ident_t word = token.read();
   if (token.terminal.state == dfaInteger || constants.exist(word)) {
      int m = 0;
      if(token.getInteger(m, constants)) {
         writeCommand(ByteCommand(code, m), writer);
      }
      else token.raiseErr("Invalid number (%d)\n");
   }
   else if (word.compare("subject")) {
      token.read(":", "Invalid operand (%d)");
      token.read();

      int paramCount = 0; // NOTE: paramCount might be not equal to stackCount (the actual stack size) in the case if variables are used for virtual methods
      int stackCount = 0;
      int verbId = mapVerb(token.value);
      if (verbId == 0) {
         verbId = EVAL_MESSAGE_ID;
      }

      IdentifierString subject;
      token.read();
      bool first = true;
      while(token.value[0] == '&') {
         if (first) {
            first = false;
         }
         else subject.append(token.value);

         token.read();
         subject.append(token.value);
         token.read();
      }
      if (token.value[0] == '[') {
         paramCount = token.readInteger(constants);
      }
      else token.raiseErr("Invalid operand (%d)");

      token.read("]", "Invalid operand (%d)");

      ref_t subj = binary->mapSubject(subject, false);

      writeCommand(ByteCommand(code, encodeMessage(subj, verbId, paramCount)), writer);
   }
   else throw AssemblerException("Invalid operand (%d)\n", token.terminal.row);
}
Example #18
0
inline void appendHex32(IdentifierString& command, unsigned int hex)
{
   unsigned int n = hex / 0x10;
   int len = 7;
   while (n > 0) {
      n = n / 0x10;

      len--;
   }

   while (len > 0) {
      command.append('0');
      len--;
   }

   command.appendHex(hex);
}
Example #19
0
void ECodesAssembler :: compileProcedure(TokenInfo& token, _Module* binary, bool inlineMode, bool aligned)
{
   LabelInfo info;

   token.read();

   IdentifierString method;
   method.copy(token.value);

   token.read();

   if (token.check(".")) {
      token.read();

      IdentifierString message;
      compileMessage(token, message);

      method.append('.');
      method.append(message);

      token.read();
   }

   ReferenceNs refName(binary->Name(), method);
   ref_t reference = binary->mapReference(refName) | mskCodeRef;

	if (binary->mapSection(reference, true)!=NULL) {
		throw AssemblerException("Procedure already exists (%d)\n", token.terminal.row);
	}

   _Memory* code = binary->mapSection(reference, false);
	MemoryWriter writer(code);
   writer.writeDWord(0);

	while (!token.check("end")) {
      compileCommand(token, writer, info, binary);
	}

   (*code)[0] = writer.Position() - 4;

}
Example #20
0
ref_t ModuleScope :: generateTemplate(ref_t reference, List<SNode>& parameters, ident_t ns, bool declarationMode)
{
   SyntaxTree templateTree;

   TemplateGenerator transformer(templateTree);
   SyntaxWriter writer(templateTree);
   writer.newNode(lxRoot);
   writer.newNode(lxNamespace, ns);

   ref_t generatedReference = 0;

   if (declarationMode) {
      generatedReference = transformer.declareTemplate(writer, *this, reference, parameters);
   }
   else {
      generatedReference = transformer.generateTemplate(writer, *this, reference, parameters, true, false);

      writer.closeNode();
      writer.closeNode();

      if (generatedReference) {
         IdentifierString path;
         path.copy("compiling ");
         path.append(resolveFullName(generatedReference));
         path.append(" template...");
         //writer.insertChild(0, lxSourcePath, path.c_str());

         try
         {
            compile(templateTree, path.c_str());
         }
         catch (_Exception&)
         {
            return 0;
         }
      }
   }

   return generatedReference;
}
Example #21
0
ref_t resolveMessageByIndex(_Module* module, ident_t className, int index)
{
   // find class VMT
   _Memory* vmt = findClassVMT(module, className);
   if (vmt == NULL) {
      return 0;
   }

   // list methods
   MemoryReader vmtReader(vmt);
   // read tape record size
   size_t size = vmtReader.getDWord();

   // read VMT header
   ClassHeader header;
   vmtReader.read((void*)&header, sizeof(ClassHeader));

   VMTEntry        entry;

   size -= sizeof(ClassHeader);
   IdentifierString temp;
   int row = 0;
   while (size > 0) {
      vmtReader.read((void*)&entry, sizeof(VMTEntry));

      index--;
      if (index == 0) {
         IdentifierString temp;
         printMessage(temp, module, entry.message);

         return resolveMessage(module, temp.c_str());
      }

      size -= sizeof(VMTEntry);
   }

   return 0;
}
Example #22
0
void parseMessageConstant(IdentifierString& message, ident_t reference)
{
   // message constant: nverb&signature

   int verbId = 0;
   int signatureId = 0;

   // read the param counter
   int count = reference[0] - '0';

   // skip the param counter
   reference+=1;

   int index = reference.find('&');
   //HOTFIX: for generic GET message we have to ignore ampresand
   if (reference[index + 1] == 0)
      index = -1;

   if (index != -1) {
      //HOTFIX: for GET message we have &&, so the second ampersand should be used
      if (reference[index + 1] == 0 || reference[index + 1] == '&')
         index++;

      IdentifierString verb(reference, index);
      ident_t signature = reference + index + 1;

      // if it is a predefined verb
      if (verb[0] == '#') {
         verbId = verb[1] - 0x20;
      }

      message.append(signature);
   }
   else {
      message.append(reference);
   }
}
Example #23
0
ref_t resolveMessage(_Module* module, const wchar16_t* method)
{
   int paramCount = 0;

   int subjIndex = StringHelper::find(method, '&', -1);
   int paramIndex = StringHelper::find(method, '[', -1);

   IdentifierString verbName;
   IdentifierString subjectName;

   if (subjIndex != -1) {
      verbName.copy(method, subjIndex);
      if (paramIndex != -1) {
         subjectName.copy(method + subjIndex + 1, paramIndex - subjIndex - 1);
      }
      else subjectName.copy(method + subjIndex + 1);
   }
   else if (paramIndex != -1) {
      verbName.copy(method, paramIndex);
   }
   else verbName.copy(method);

   if (paramIndex != -1) {
      IdentifierString countStr(method + paramIndex + 1, getlength(method) - paramIndex - 2);
      paramCount = StringHelper::strToInt(countStr);
   }

   ref_t verb = _verbs.get(verbName);
   if (verb == 0) {
      if (StringHelper::compare(verbName, _T("resend"))) {
         verb = SEND_MESSAGE_ID;
      }
      else if (StringHelper::compare(verbName, _T("dispatch"))) {
         verb = DISPATCH_MESSAGE_ID;
      }
      else {
         wprintf(_T("Unknown verb %s\n"), (const wchar16_t*)verbName);

         return 0;
      }
   }

   ref_t subject = emptystr(subjectName) ? 0 : module->mapSubject(subjectName, true);
   if (subject == 0 && !emptystr(subjectName)) {
      wprintf(_T("Unknown subject %s\n"), (const wchar16_t*)subjectName);

      return 0;
   }

   return encodeMessage(subject, verb, paramCount);
}
Example #24
0
void printMethod(_Module* module, ident_t methodReference, int pageSize)
{
   methodReference = trim(methodReference);

   int separator = methodReference.find('.');
   if (separator == -1) {
      printf("Invalid command");

      return;
   }

   IdentifierString className(methodReference, separator);

   ident_t methodName = methodReference + separator + 1;
   ref_t message = 0;

   // resolve method
   if (methodName[0] >= '0' && methodName[0] <= '9') {
      message = resolveMessageByIndex(module, className.ident(), methodName.toInt());
   }
   else message = resolveMessage(module, methodName);
   
   if (message == 0)
      return;

   // find class VMT
   _Memory* vmt = findClassVMT(module, className);
   _Memory* code = findClassCode(module, className);
   if (vmt == NULL || code == NULL) {
      printLine("Class not found: ", className);

      return;
   }

   // find method entry
   MemoryReader vmtReader(vmt);
   // read tape record size
   size_t size = vmtReader.getDWord();

   // read VMT header
   ClassHeader header;
   vmtReader.read((void*)&header, sizeof(ClassHeader));

   VMTEntry        entry;

   // read VMT while the entry not found
   size -= sizeof(ClassHeader);
   bool found = false;
   while (size > 0) {
      vmtReader.read((void*)&entry, sizeof(VMTEntry));

      if (entry.message == message) {
         found = true;

         IdentifierString temp;
         temp.copy(className);
         temp.append('.');
         printMessage(temp, module, entry.message);
         printLine("@method ", temp);

         printByteCodes(module, code, entry.address, 4, pageSize);
         print("@end\n");

         break;
      }

      size -= sizeof(VMTEntry);
   }
   if (!found) {
      printLine("Method not found:", methodName);
   }
}
Example #25
0
bool printCommand(_Module* module, MemoryReader& codeReader, int indent, List<int>& labels)
{
   // read bytecode + arguments
   int position = codeReader.Position();
   unsigned char code = codeReader.getByte();

   // ignore a breakpoint if required
   if (code == bcBreakpoint && _ignoreBreakpoints)
      return false;

   char opcode[0x30];
   ByteCodeCompiler::decode((ByteCode)code, opcode);

   IdentifierString command;
   while (indent > 0) {
      command.append(" ");

      indent--;
   }
   if (code < 0x10)
      command.append('0');

   command.appendHex((int)code);
   command.append(' ');

   int argument = 0;
   int argument2 = 0;
   if (code > MAX_DOUBLE_ECODE) {
      argument = codeReader.getDWord();
      argument2 = codeReader.getDWord();

      appendHex32(command, argument);
      command.append(' ');

      appendHex32(command, argument2);
      command.append(' ');
   }
   else if (code > MAX_SINGLE_ECODE) {
      argument = codeReader.getDWord();

      appendHex32(command, argument);
      command.append(' ');
   }

   size_t tabbing = code == bcNop ? 24 : 31;
   while (getlength(command) < tabbing) {
      command.append(' ');
   }

   switch(code)
   {
      case bcPushF:
      case bcSCopyF:
      case bcACopyF:
      case bcBCopyF:
         command.append(opcode);
         command.append(" fp:");
         command.appendInt(argument);
         break;
      case bcACopyS:
         command.append(opcode);
         command.append(" sp:");
         command.appendInt(argument);
         break;
      case bcJump:
      case bcHook:
      case bcIf:
      case bcIfB:
      case bcElse:
      case bcIfHeap:
      case bcNotLess:
//      case bcAddress:
         command.append(opcode);
         command.append(' ');
         printLabel(command, position + argument + 5, labels);
         break;
      case bcElseM:
      case bcIfM:
         command.append(opcode);
         command.append(' ');
         printMessage(command, module, argument);
         command.append(' ');
         printLabel(command, position + argument2 + 9, labels);
         break;
      case bcElseR:
      case bcIfR:
         command.append(opcode);
         command.append(' ');
         printReference(command, module, argument);
         command.append(' ');
         printLabel(command, position + argument2 + 9, labels);
         break;
      case bcIfN:
      case bcElseN:
      case bcLessN:
      case bcNotLessN:
      case bcGreaterN:
      case bcNotGreaterN:
         command.append(opcode);
         command.append(' ');
         command.appendHex(argument);
         command.append(' ');
         printLabel(command, position + argument2 + 9, labels);
         break;
      case bcNop:
         printLabel(command, position + argument, labels);
         command.append(':');
         command.append(' ');
         command.append(opcode);
         break;
      case bcPushR:
      case bcALoadR:
      case bcCallExtR:
      case bcCallR:
      case bcASaveR:
      case bcACopyR:
      case bcBCopyR:
         command.append(opcode);
         command.append(' ');
         printReference(command, module, argument);
         break;
      case bcReserve:
      case bcRestore:
      case bcPushN:
      case bcPopI:
      case bcOpen:
      case bcQuitN:
      case bcDCopy:
      case bcECopy:
      case bcAndN:
      case bcOrN:
      case bcInit:
      case bcNLoadI:
      case bcNSaveI:
      case bcMulN:
      case bcAddN:
         command.append(opcode);
         command.append(' ');
         command.appendHex(argument);
         break;
      case bcPushSI:
      case bcALoadSI:
      case bcASaveSI:
      case bcBLoadSI:
      case bcBSaveSI:
         command.append(opcode);
         command.append(" sp[");
         command.appendInt(argument);
         command.append(']');
         break;
      case bcBLoadFI:
      case bcPushFI:
      case bcALoadFI:
      case bcASaveFI:
      case bcDLoadFI:
         command.append(opcode);
         command.append(" fp[");
         command.appendInt(argument);
         command.append(']');
         break;
      case bcAJumpVI:
      case bcACallVI:
         command.append(opcode);
         command.append(" acc::vmt[");
         command.appendInt(argument);
         command.append(']');
         break;
      case bcPushAI:
      case bcALoadAI:
         command.append(opcode);
         command.append(" acc[");
         command.appendInt(argument);
         command.append(']');
         break;
      case bcASaveBI:
      case bcAXSaveBI:
      case bcALoadBI:
         command.append(opcode);
         command.append(" base[");
         command.appendInt(argument);
         command.append(']');
         break;
      case bcNew:
         command.append(opcode);
         command.append(' ');
         printReference(command, module, argument);
         command.append(", ");
         command.appendInt(argument2);
         break;
      case bcXCallRM:
      case bcXJumpRM:
      case bcXIndexRM:
      case bcXMTRedirect:
         command.append(opcode);
         command.append(' ');
         printReference(command, module, argument);
         command.append(", ");
         printMessage(command, module, argument2);
         break;
      case bcCopyM:
         command.append(opcode);
         command.append(' ');
         printMessage(command, module, argument);
         break;
      case bcSetVerb:
         command.append(opcode);
         command.append(' ');
         printMessage(command, module, encodeAction(argument));
         break;
      case bcSelectR:
      case bcXSelectR:
         command.append(opcode);
         command.append(' ');
         printReference(command, module, argument);
         command.append(", ");
         printReference(command, module, argument2);
         break;
      case bcNewN:
         command.append(opcode);
         command.append(' ');
         printReference(command, module, argument);
         command.append(", ");
         command.appendInt(argument2);
         break;
      case bcSaveFI:
      case bcAddFI:
      case bcSubFI:
         command.append(opcode);
         command.append(" fp[");
         command.appendInt(argument);
         command.append("], ");
         command.appendInt(argument2);
         break;
      default:
         command.append(opcode);
         break;
   }

   print(command);
   return true;
}
Example #26
0
void printCommand(_Module* module, MemoryReader& codeReader, int indent, List<int>& labels)
{
   // read bytecode + arguments
   int position = codeReader.Position();
   unsigned char code = codeReader.getByte();

   wchar16_t opcode[0x30];
   ByteCodeCompiler::decode((ByteCode)code, opcode);

   IdentifierString command;
   while (indent > 0) {
      command.append(_T(" "));

      indent--;
   }
   if (code < 0x10)
      command.append(_T('0'));

   command.appendHex((int)code);
   command.append(_T(' '));

   int argument = 0;
   int argument2 = 0;
   if (code >= 0xE0) {
      argument = codeReader.getDWord();
      argument2 = codeReader.getDWord();

      appendHex32(command, argument);
      command.append(_T(' '));

      appendHex32(command, argument2);
      command.append(_T(' '));
   }
   else if (code >= 0x20) {
      argument = codeReader.getDWord();

      appendHex32(command, argument);
      command.append(_T(' '));
   }

   int tabbing = code == bcNop ? 24 : 31;
   while (getlength(command) < tabbing) {
      command.append(_T(' '));
   }

   switch(code)
   {
      //case bcPushFPI:
      case bcXPushF:
      case bcSCopyF:
      case bcAXCopyF:
      //case bcAccCopyFPI:
         command.append(opcode);
         command.append(_T(" fp:"));
         command.appendHex(argument);
         break;
      case bcACopyS:
         command.append(opcode);
         command.append(_T(" sp:"));
         command.appendHex(argument);
         break;
      case bcAElse:
      case bcAThen:
      //case bcMccElseAcc:
      //case bcMccThenAcc:
      case bcJump:
      //case bcElseLocal:
         command.append(opcode);
         command.append(_T(' '));
         printLabel(command, position + argument + 5, labels);
         break;
      case bcMElse:
      case bcMThen:
         command.append(opcode);
         command.append(_T(' '));
         printMessage(command, module, argument);
         command.append(_T(' '));
         printLabel(command, position + argument2 + 9, labels);
         break;
      //case bcElseR:
      //case bcThenR:
      //   command.append(opcode);
      //   command.append(_T(' '));
      //   printReference(command, module, argument);
      //   command.append(_T(' '));
      //   printLabel(command, position + argument2 + 9, labels);
      //   break;
      case bcTestFlag:
      case bcElseFlag:
      ////case bcElseN:
      ////case bcThenN:
         command.append(opcode);
         command.append(_T(' '));
         command.appendHex(argument);
         command.append(_T(' '));
         printLabel(command, position + argument2 + 9, labels);
         break;
      //case bcMccElseAccI:
      //case bcMccThenAccI:
      //   command.append(opcode);
      //   command.append(_T(' acc['));
      //   command.appendHex(argument);
      //   command.append(_T('] '));
      //   printLabel(command, position + argument2 + 9, labels);
      //   break;
      case bcAElseR:
      case bcAThenR:
         command.append(opcode);
         command.append(_T(' '));
         printReference(command, module, argument);
         command.append(_T(' '));
         printLabel(command, position + argument2 + 9, labels);
         break;
         break;
      case bcAElseSI:
      case bcAThenSI:
      ////case bcMccElseSI:
      ////case bcMccThenSI:
      ////case bcMccVerbElseSI:
      ////case bcMccVerbThenSI:
         command.append(opcode);
         command.append(_T(" sp["));
         command.appendInt(argument);
         command.append(_T("] "));
         printLabel(command, position + argument2 + 9, labels);
         break;
      case bcNop:
         printLabel(command, position + argument, labels);
         command.append(_T(':'));
         command.append(_T(' '));
         command.append(opcode);
         break;
      case bcPushR:
      case bcALoadR:
      case bcCallExtR:
      case bcEvalR:
      //case bcCallR:
      ////case bcSendVMTR:
      case bcASaveR:
      case bcACopyR:
      case bcNBox:
      case bcBox:
      ////case bcAccTryR:
      ////case bcAccMergeR:
      ////case bcJumpR:
         command.append(opcode);
         command.append(_T(' '));
         printReference(command, module, argument);
         break;
      case bcReserve:
      case bcRestore:
      //case bcPushN:
      case bcPopI:
      case bcOpen:
      case bcQuitN:
      case bcDCopy:
      //case bcAccCreate:
      ////case bcAccTestFlagN:
      ////case bcAccCopyN:
      //case bcAccAddN:
      //case bcGetLen:
      ////case bcAccTryN:
      ////case bcSelfShiftI:
      ////case bcAccShiftI:
      ////case bcTryLock:
      ////case bcFreeLock:
      ////case bcSPTryLock:
      ////case bcAccFreeLock:
      //case bcJumpAccN:
         command.append(opcode);
         command.append(_T(' '));
         command.appendHex(argument);
         break;
      ////case bcAccInc:
      //case bcPushI:
      //   command.append(opcode);
      //   command.append(_T(' '));
      //   command.appendHex(argument);
      //   break;
      case bcPushSI:
      case bcALoadSI:
      case bcASaveSI:
      //case bcSwapSI:
      //case bcPopSI:
      case bcMLoadSI:
      //case bcAccSwapSI:
         command.append(opcode);
         command.append(_T(" sp["));
         command.appendInt(argument);
         command.append(_T(']'));
         break;
      //case bcAccGetSI:
      //   command.append(opcode);
      //   command.append(_T(" acc[sp["));
      //   command.appendInt(argument);
      //   command.append(_T("]]"));
      //   break;
      //case bcAccGetFI:
      //   command.append(opcode);
      //   command.append(_T(" acc[fp["));
      //   command.appendInt(argument);
      //   command.append(_T("]]"));
      //   break;
      case bcPushFI:
      case bcALoadFI:
      //case bcPopFI:
      //case bcIncFI:
      case bcASaveFI:
      case bcMLoadFI:
      case bcMSaveParams:
      //case bcXAccSaveFI:
      case bcDLoadFI:
      case bcDSaveFI:
         command.append(opcode);
         command.append(_T(" fp["));
         command.appendInt(argument);
         command.append(_T(']'));
         break;
      case bcACallVI:
         command.append(opcode);
         command.append(_T(" acc::vmt["));
         command.appendInt(argument);
         command.append(_T(']'));
         break;
      case bcPushAI:
      ////case bcPopAccI:
      case bcXPopAI:
      ////case bcPop2AccI:
      //case bcAccLoadAccI:
      case bcMLoadAI:
      //case bcMccAddAccI:
      case bcDSaveAI:
         command.append(opcode);
         command.append(_T(" acc["));
         command.appendInt(argument);
         command.append(_T(']'));
         break;
      //case bcPushSelfI:
      //case bcPopSelfI:
      case bcASaveBI:
      ////case bcAccLoadSelfI:
         command.append(opcode);
         command.append(_T(" self["));
         command.appendInt(argument);
         command.append(_T(']'));
         break;
      ////case bcIAccCopyN:
      ////   command.append(opcode);
      ////   command.append(_T(" acc["));
      ////   command.appendInt(argument);
      ////   command.append(_T("], "));
      ////   command.appendHex(argument2);
      ////   break;
      //case bcIAccCopyR:
      //   command.append(opcode);
      //   command.append(_T(" acc["));
      //   command.appendInt(argument);
      //   command.append(_T("], "));
      //   printReference(command, module, argument2);
      //   break;
      //case bcIAccFillR:
      //   command.append(opcode);
      //   command.append(_T(' '));
      //   command.appendInt(argument);
      //   command.append(_T(", "));
      //   printReference(command, module, argument2);
      //   break;
      //case bcCreate:
      //case bcCreateN:
      //case bcAccCreateN:
      //case bcAccBoxN:
      //   command.append(opcode);
      //   command.append(_T(' '));
      //   command.appendInt(argument);
      //   command.append(_T(", "));
      //   printReference(command, module, argument2);
      //   break;
      case bcXCallRM:
         command.append(opcode);
         command.append(_T(' '));
         printReference(command, module, argument);
         command.append(_T(", "));
         printMessage(command, module, argument2);
         break;
      //case bcRCallN:
      //   command.append(opcode);
      //   command.append(_T(' '));
      //   printReference(command, module, argument);
      //   command.append(_T(", "));
      //   command.appendInt(argument2);
      //   break;
      ////case bcAccCopyM:
      case bcMCopy:
      //case bcXMccCopyM:
      //case bcMccAddM:
         command.append(opcode);
         command.append(_T(' '));
         printMessage(command, module, argument);
         break;
      case bcSCallVI:
         command.append(opcode);
         command.append(_T(" sp["));
         command.appendInt(argument);
         command.append(_T("]::vmt["));
         command.appendInt(argument2);
         command.append(_T("]"));
         break;
      case bcNFunc:
      case bcLFunc:
      case bcRFunc:
      case bcWSFunc:
      case bcFunc:
         command.append(opcode);
         ByteCodeCompiler::decodeFunction((FunctionCode)argument, opcode);
         command.append(opcode);
         break;
      default:
         command.append(opcode);
         break;
   }

   print(command);
}
Example #27
0
ref_t resolveMessage(_Module* module, ident_t method)
{
   int paramCount = 0;
   ref_t actionRef = 0;
   ref_t flags = 0;

   if (method.startsWith("params#")) {
      flags |= VARIADIC_MESSAGE;

      method = method.c_str() + getlength("params#");
   }
   if (method.startsWith("prop#")) {
      flags |= PROPERTY_MESSAGE;

      method = method.c_str() + getlength("prop#");
   }
   if (method.startsWith("#invoke")) {
      flags |= SPECIAL_MESSAGE;
   }
   if (method.startsWith("#private&")) {
      flags |= STATIC_MESSAGE;

      method = method.c_str() + getlength("#private&");
   }
   if (method.compare("#init")) {
      flags |= SPECIAL_MESSAGE;
   }

   IdentifierString actionName;
   int paramIndex = method.find('[', -1);
   if (paramIndex != -1) {
      actionName.copy(method, paramIndex);

      IdentifierString countStr(method + paramIndex + 1, getlength(method) - paramIndex - 2);
      paramCount = countStr.ident().toInt();
   }
   else actionName.copy(method);

   //if (actionName.compare("dispatch")) {
   //   actionRef = DISPATCH_MESSAGE_ID;
   //}
   //else if (actionName.compare("#new")) {
   //   actionRef = NEWOBJECT_MESSAGE_ID;
   //}
   ///*else */if (actionName.compare("#init")) {
   //   actionRef = INIT_MESSAGE_ID;
   //}
   //else {
   //   if (method.find("set&") != NOTFOUND_POS) {
   //      actionName.cut(0, 4);
   //      flags = PROPSET_MESSAGE;
   //   }
   //   else if (method.startsWith("#cast<") && paramCount > 0) {
   //      flags = SPECIAL_MESSAGE;
   //   }
   ////   else if (actionName.compare("set")) {
   ////      flags = PROPSET_MESSAGE;
   ////   }

      ref_t signature = 0;
      size_t index = actionName.ident().find('<');
      if (index != NOTFOUND_POS) {
         ref_t references[ARG_COUNT];
         size_t end = actionName.ident().find('>');
         size_t len = 0;
         size_t i = index + 1;
         while (i < end) {
            size_t j = actionName.ident().find(i, ',', end);

            IdentifierString temp(actionName.c_str() + i, j-i);
            references[len++] = module->mapReference(temp, true);

            i = j + 1;
         }

         signature = module->mapSignature(references, len, true);

         actionName.truncate(index);
      }

      actionRef = module->mapAction(actionName, signature, true);
      if (actionRef == 0) {
         printLine("Unknown subject ", actionName);

         return 0;
      }
   //}

   return encodeMessage(actionRef, paramCount, flags);
}
Example #28
0
void runSession(_Module* module, int pageSize)
{
   char              buffer[MAX_LINE];
   IdentifierString  line;
   while (true) {
      printf("\n>");

      // !! fgets is used instead of fgetws, because there is strange bug in fgetws implementation
      fgets(buffer, MAX_LINE, stdin);
      line.copy(buffer, strlen(buffer));

      while (!emptystr(line) && line[getlength(line) - 1]=='\r' || line[getlength(line) - 1]=='\n')
         line[getlength(line) - 1] = 0;

      while (!emptystr(line) && line[getlength(line) - 1]==' ')
         line[getlength(line) - 1] = 0;

      // execute command
      if (line[0]=='?') {
         if (line[1]==0) {
            listClasses(module, pageSize);
         }
         else printHelp();
      }
      else if (line[0]=='-') {
         switch(line[1]) {
            case 'q':
               return;
            case 'h':
               printHelp();
               break;
            case 'l':
               printAPI(module, pageSize);
               break;
            case 'b':
               _ignoreBreakpoints = !_ignoreBreakpoints;
               break;
            //case 'c':
            //   printConstructor(module, line + 2, pageSize);
            //   break;
            case 'o':
            {
               Path path(line + 2);
               setOutputMode(path.c_str());
               break;
            }
            default:
               printHelp();
         }
      }
      else if (line[0] == '#') {
         printSymbol(module, line + 1, pageSize);
      }
      else {
         if (line.ident().find('.') != NOTFOUND_POS) {
            printMethod(module, line, pageSize);
         }
         else listClassMethods(module, line, pageSize, true, false);
      }      
   }
}
Example #29
0
int main(int argc, char* argv[])
{
   printf("ELENA command line syntax generator %d.%d.%d (C)2005-2018 by Alexei Rakov\n", ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION, BUILD_NUMBER);
   if (argc < 2 || argc > 3) {
      printLine("sg <syntax_file> [-cp<codepage>]");
      return 0;
   }
   try {
      int encoding = DEFAULT_ENCODING;

      if (argc==3) {
         ident_t arg = argv[2];

         if (arg.compare("-cp", 3)) {
            encoding = arg.toInt(3);
         }
         else {
            printLine("sg <syntax_file> [-cp<codepage>]");
            return 0;
         }
      }

      Path path(argv[1]);
      TextFileReader   sourceFile(path.c_str(), encoding, true);
      if (!sourceFile.isOpened()) {
         printLine("file not found %s", path);
      }

      TextSourceReader source(4, &sourceFile);
      ParserTable      table;
      LineInfo         info(0, 0, 0);
      IdentifierString token;
      int              rule[20];
      int              rule_len = 0;
      bool             arrayCheck = false;

      table.registerSymbol(ParserTable::nsEps, "eps");

      while (true) {
         info = source.read(token, IDENTIFIER_LEN);

         if (info.state == dfaEOF) break;

         if (token.compare("__define")) {
            source.read(token, IDENTIFIER_LEN);

            char number[10];
            source.read(number, 10);

            registerSymbol(table, token, ident_t(number).toInt());
         }
         else if (token.compare("->") && !arrayCheck) {
            if (rule_len > 2) {
               table.registerRule(rule[0], rule + 1, rule_len - 2);

               rule[0] = rule[rule_len - 1];
               rule_len = 1;
            }
            arrayCheck = true;
         }
         else if (token.compare("|") && rule_len != 1) {
            arrayCheck = false;
            table.registerRule(rule[0], rule + 1, rule_len - 1);

            rule_len = 1;
         }
         else {
            arrayCheck = false;
            rule[rule_len++] = registerSymbol(table, token, last_id + 1);
            if (token.compare("|"))
               source.read(token, IDENTIFIER_LEN);
         }
      }
      table.registerRule(rule[0], rule + 1, rule_len - 1);

      printLine("generating...\n");

      int ambigous = table.generate();
      if (ambigous) {
         printLine("error:ambigous rule %s\n", table.retrieveSymbol(ambigous));
         return -1;
      }

      printLine("saving...\n");

      path.changeExtension("dat");

      FileWriter file(path.c_str(), feRaw, false);
      table.save(&file);
   }
   catch(_ELENA_::InvalidChar& e) {
      printLine("(%d:%d): Invalid char %c\n", e.row, e.column, (char)e.ch);
   }
   return 0;
}