示例#1
0
void _parseFieldList (const char *str, StringPool &props, StringPool &columns)
{
   QS_DEF(Array<char>, prop);
   QS_DEF(Array<char>, column);
   BufferScanner scanner(str);

   props.clear();
   columns.clear();
   scanner.skipSpace();

   while (!scanner.isEOF())
   {
      scanner.readWord(prop, " ,");
      scanner.skipSpace();
      scanner.readWord(column, " ,");
      scanner.skipSpace();

      props.add(prop.ptr());
      columns.add(column.ptr());
      
      if (scanner.isEOF())
         break;
      
      if (scanner.readChar() != ',')
         throw BingoError("_parseFieldList(): comma expected");
      scanner.skipSpace();
   }
}
示例#2
0
TypeManager::TypeManager(StringPool &strings)
 : strings_(strings),
   voidType_(nullptr),
   implicitVoidType_(nullptr),
   uncheckedType_(nullptr),
   metaFunctionType_(nullptr),
   overloadedFunctionType_(nullptr),
   primitiveTypes_(),
   char_type_(nullptr),
   char_array_(nullptr),
   const_char_array_(nullptr),
   float_type_(nullptr),
   float3_array_(nullptr),
   const_float3_array_(nullptr)
{
  atom_String_ = strings.add("String");
  atom_Float_ = strings.add("Float");
  atom_any_ = strings.add("any");
  atom_Function_ = strings.add("Function");
  atom_bool_ = strings.add("bool");
}
示例#3
0
int VirtualMachine::runFile(ByteCodeFileReader& reader){
	int header = reader.readHeader();

	if(header != ('E' + 'D' + 'D' + 'I')){
		cout << "Not an EDDI compiled file" << endl;
		return 1;
	}

	StringPool pool;

	int strings = reader.readInt();

	cout << "String pool size = " << strings << endl;

	for(int i = 0; i < strings; i++){
		int index = reader.readInt();
		string value = reader.readLitteral();

		pool.add(index, value);
	}

	vector<Instruction> instructions;
	int current = 0;

	map<int, int> branches;

	while(reader.hasMore()){
		ByteCode bytecode = reader.readByteCode();

		if(bytecode == LABEL){
			int branche = reader.readInt();

			branches[branche] = current;
		} else {
			Instruction instruction;
			instruction.bytecode = bytecode;
	
			if(instruction.bytecode > LABEL && instruction.bytecode <= JUMP_IF_NOT){
				instruction.operand = reader.readInt();	
			}

			instructions.push_back(instruction);
			++current;
		}	
	}

	Stack stack;
	Variables variables;

	int programCounter = 0;

	while(true){
		Instruction instruction = instructions[programCounter];
		ByteCode bytecode = instruction.bytecode;
		
		programCounter++;

		switch(bytecode){
			case LDCS:
			case LDCI:
				stack.push(instruction.operand);

				break;
			case PRINTI:
				cout << stack.pop() << endl;

				break;
			case PRINTS:
				cout << pool.get(stack.pop()) << endl;

				break;
			case SSTORE:
			case ISTORE:{
				unsigned int variable = (unsigned int) instruction.operand;
				
				variables.assign(variable, stack.pop());
				
				break;
			}
			case SLOAD:
			case ILOAD:{
				unsigned int variable = (unsigned int) instruction.operand;

				stack.push(variables.get(variable));	
				
				break;
			}
			case IADD:{
				int rhs = stack.pop();
				int lhs = stack.pop();
				
				stack.push(lhs + rhs);
				
				break;
			}
			case ISUB:{
				int rhs = stack.pop();
				int lhs = stack.pop();
				
				stack.push(lhs - rhs);
				
				break;
			}
			case IMUL:{
				int rhs = stack.pop();
				int lhs = stack.pop();
				
				stack.push(lhs * rhs);
				
				break;
			}
			case IDIV:{
				int rhs = stack.pop();
				int lhs = stack.pop();
				
				stack.push(lhs / rhs);
				
				break;
			}
			case IMOD:{
				int rhs = stack.pop();
				int lhs = stack.pop();
				
				stack.push(lhs % rhs);
				
				break;
			}
			case SADD:{
				string rhs = pool.get(stack.pop());
				string lhs = pool.get(stack.pop());

				int index = pool.addNew(lhs + rhs);	

				stack.push(index);

				break;
			}
			case JUMP: {
				programCounter = branches[instruction.operand];
		
				break;
			} 
			case JUMP_IF: {
				int result = stack.pop();

				if(result == 1){
					programCounter = branches[instruction.operand];
				}
		
				break;
			} 
		 
			case JUMP_IF_NOT: {
				int result = stack.pop();

				if(result == 0){
					programCounter = branches[instruction.operand];
				}
		
				break;
			} 

			case EQUALS: {
				int rhs = stack.pop();
				int lhs = stack.pop();

				if(lhs == rhs){
					stack.push(1);
				} else {
					stack.push(0);
				}
		
				break;
			} 
			case NOT_EQUALS: {
				int rhs = stack.pop();
				int lhs = stack.pop();

				if(lhs != rhs){
					stack.push(1);
				} else {
					stack.push(0);
				}
		
				break;
			} 
			case GREATER_THAN: {
				int rhs = stack.pop();
				int lhs = stack.pop();

				if(lhs > rhs){
					stack.push(1);
				} else {
					stack.push(0);
				}
		
				break;
			} 
			case LESS_THAN: {
				int rhs = stack.pop();
				int lhs = stack.pop();

				if(lhs < rhs){
					stack.push(1);
				} else {
					stack.push(0);
				}
		
				break;
			} 
			case GREATER_THAN_EQUALS: {
				int rhs = stack.pop();
				int lhs = stack.pop();

				if(lhs >= rhs){
					stack.push(1);
				} else {
					stack.push(0);
				}
		
				break;
			} 
			case LESS_THAN_EQUALS: {
				int rhs = stack.pop();
				int lhs = stack.pop();

				if(lhs <= rhs){
					stack.push(1);
				} else {
					stack.push(0);
				}
		
				break;
			} 
			case END:
				return 0;
		}
	}

	return 1;
}
示例#4
0
static void append_debug_tables(SmxBuilder *builder, StringPool &pool, RefPtr<SmxNameTable> names, SymbolList &nativeList)
{
  // We use a separate name table for historical reasons that are no longer
  // necessary. In the future we should just alias this to ".names".
  RefPtr<SmxNameTable> dbgnames = new SmxNameTable(".dbg.strings");
  RefPtr<SmxDebugInfoSection> info = new SmxDebugInfoSection(".dbg.info");
  RefPtr<SmxDebugLineSection> lines = new SmxDebugLineSection(".dbg.lines");
  RefPtr<SmxDebugFileSection> files = new SmxDebugFileSection(".dbg.files");
  RefPtr<SmxDebugSymbolsSection> symbols = new SmxDebugSymbolsSection(".dbg.symbols");
  RefPtr<SmxDebugNativesSection> natives = new SmxDebugNativesSection(".dbg.natives");
  RefPtr<SmxTagSection> tags = new SmxTagSection(".tags");

  stringlist *dbgstrs = get_dbgstrings();

  // State for tracking which file we're on. We replicate the original AMXDBG
  // behavior here which excludes duplicate addresses.
  ucell prev_file_addr = 0;
  const char *prev_file_name = nullptr;

  // Add debug data.
  for (stringlist *iter = dbgstrs; iter; iter = iter->next) {
    if (iter->line[0] == '\0')
      continue;

    DebugString str(iter->line);
    switch (str.kind()) {
      case 'F':
      {
        ucell codeidx = str.parse();
        if (codeidx != prev_file_addr) {
          if (prev_file_name) {
            sp_fdbg_file_t &entry = files->add();
            entry.addr = prev_file_addr;
            entry.name = dbgnames->add(pool, prev_file_name);
          }
          prev_file_addr = codeidx;
        }
        prev_file_name = str.skipspaces();
        break;
      }

      case 'L':
      {
        sp_fdbg_line_t &entry = lines->add();
        entry.addr = str.parse();
        entry.line = str.parse();
        break;
      }

      case 'S':
      {
        sp_fdbg_symbol_t sym;
        sp_fdbg_arraydim_t dims[sDIMEN_MAX];

        sym.addr = str.parse();
        sym.tagid = str.parse();

        str.skipspaces();
        str.expect(':');
        char *name = str.skipspaces();
        char *nameend = str.skipto(' ');
        Atom *atom = pool.add(name, nameend - name);

        sym.codestart = str.parse();
        sym.codeend = str.parse();
        sym.ident = (char)str.parse();
        sym.vclass = (char)str.parse();
        sym.dimcount = 0;
        sym.name = dbgnames->add(atom);

        info->header().num_syms++;

        str.skipspaces();
        if (str.getc() == '[') {
          info->header().num_arrays++;
          for (char *ptr = str.skipspaces(); *ptr != ']'; ptr = str.skipspaces()) {
            dims[sym.dimcount].tagid = str.parse();
            str.skipspaces();
            str.expect(':');
            dims[sym.dimcount].size = str.parse();
            sym.dimcount++;
          }
        }

        symbols->add(&sym, sizeof(sym));
        symbols->add(dims, sizeof(dims[0]) * sym.dimcount);
        break;
      }
    }
  }

  // Add the last file.
  if (prev_file_name) {
    sp_fdbg_file_t &entry = files->add();
    entry.addr = prev_file_addr;
    entry.name = dbgnames->add(pool, prev_file_name);
  }

  // Build the tags table.
  for (constvalue *constptr = tagname_tab.next; constptr; constptr = constptr->next) {
    assert(strlen(constptr->name)>0);

    sp_file_tag_t &tag = tags->add();
    tag.tag_id = constptr->value;
    tag.name = names->add(pool, constptr->name);
  }

  // Finish up debug header statistics.
  info->header().num_files = files->count();
  info->header().num_lines = lines->count();

  // Write natives.
  sp_fdbg_ntvtab_t natives_header;
  natives_header.num_entries = nativeList.length();
  natives->add(&natives_header, sizeof(natives_header));

  for (size_t i = 0; i < nativeList.length(); i++) {
    symbol *sym = nativeList[i];

    sp_fdbg_native_t info;
    info.index = i;
    info.name = dbgnames->add(pool, sym->name);
    info.tagid = sym->tag;
    info.nargs = 0;
    for (arginfo *arg = sym->dim.arglist; arg->ident; arg++)
      info.nargs++;
    natives->add(&info, sizeof(info));

    for (arginfo *arg = sym->dim.arglist; arg->ident; arg++) {
      sp_fdbg_ntvarg_t argout;
      argout.ident = arg->ident;
      argout.tagid = arg->tag;
      argout.dimcount = arg->numdim;
      argout.name = dbgnames->add(pool, arg->name);
      natives->add(&argout, sizeof(argout));

      for (int j = 0; j < argout.dimcount; j++) {
        sp_fdbg_arraydim_t dim;
        dim.tagid = arg->idxtag[j];
        dim.size = arg->dim[j];
        natives->add(&dim, sizeof(dim));
      }
    }
  }

  // Add these in the same order SourceMod 1.6 added them.
  builder->add(files);
  builder->add(symbols);
  builder->add(lines);
  builder->add(natives);
  builder->add(dbgnames);
  builder->add(info);
  builder->add(tags);
}