Esempio n. 1
0
// Parsing nth argument (output = -1)
pair<string,ProtoType*> ProtoInterpreter::parse_argument(SE_List_iter* i, int n,
                                                         Signature* sig, bool anonymous_ok) {
  SExpr *a = i->get_next("argument");
  SExpr *b = (i->on_token("|")) ? i->get_next("argument") : NULL;
  string name=""; ProtoType* type=NULL;
  if(b) { // specified as name|type
    if(sexp_is_type(a))
      compile_error(a,"Parameter name cannot be a type");
    if(a->isSymbol()) name = dynamic_cast<SE_Symbol &>(*a).name;
    else compile_error(a,"Parameter name not a symbol: "+ce2s(a));
    type = sexp_to_type(b);
  } else { // determine name or type by parsing
    if(sexp_is_type(a)) {
      if(anonymous_ok) type = sexp_to_type(a);
      else compile_error(a,"Function parameters must be named: "+ce2s(a));
    }
    else if(a->isSymbol()) name = dynamic_cast<SE_Symbol &>(*a).name;
    else compile_error(a,"Parameter name not a symbol: "+ce2s(a));
  }
  // fall back to defaults where needed
  if(name=="") name = (n>=0) ? ("arg"+i2s(n)) : "value";
  if(type==NULL) type = new ProtoType();
  // record name in signature and return
  if(sig->names.count(name))
    compile_error(a,"Cannot bind '"+name+"': already bound");
  sig->names[name] = n;
  return make_pair(name,type);
}
Esempio n. 2
0
void SExpr::toStream(std::ostream& out, const SExpr& sexpr, OutputLanguage language, int indent) throw() {
  if( sexpr.isKeyword() && languageQuotesKeywords(language) ){
    out << quoteSymbol(sexpr.getValue());
  } else {
    toStreamRec(out, sexpr, language, indent);
  }
}
Esempio n. 3
0
SExpr* ProtoInterpreter::expand_macro(MacroOperator* m, SE_List* call) {
  Env m_env(this);
  // bind variables to SExprs
  if(!m->signature->legal_length(call->len()-1))
    return sexp_err(call,"Wrong number of arguments for macro "+m->name);
  int i=1; // start after macro name
  for(int j=0;j<m->signature->required_inputs.size();j++) {
    ProtoSymbol* var
      = &dynamic_cast<ProtoSymbol &>(*m->signature->required_inputs[j]);
    m_env.bind(var->value,(*call)[i++]);
  }
  for(int j=0;j<m->signature->optional_inputs.size() && i<call->len();j++) {
    ProtoSymbol* var
      = &dynamic_cast<ProtoSymbol &>(*m->signature->optional_inputs[j]);
    m_env.bind(var->value,(*call)[i++]);
  }
  if(m->signature->rest_input) { // sweep all else into rest argument
    ProtoSymbol* var
      = &dynamic_cast<ProtoSymbol &>(*m->signature->rest_input);
    SE_List *rest = new SE_List(); rest->inherit_attributes(m);
    for(; i<call->len(); ) { rest->add((*call)[i++]); }
    m_env.bind(var->value,rest);
  }
  // then substitute the pattern
  V3 << "Expand macro call:\n"; V3 << call->to_str() << endl;
  SExpr* expanded = macro_substitute(m->pattern,&m_env);
  V3 << "Macro expanded into:\n"; V3 << expanded->to_str() << endl;
  return expanded;
}
Esempio n. 4
0
CVC4::SExpr SmtEngine::getOption(const std::string& key) const
  throw(OptionException) {

  NodeManagerScope nms(d_nodeManager);

  Trace("smt") << "SMT getOption(" << key << ")" << endl;

  if(key.length() >= 18 &&
     key.compare(0, 18, "command-verbosity:") == 0) {
    map<string, Integer>::const_iterator i = d_commandVerbosity.find(key.c_str() + 18);
    if(i != d_commandVerbosity.end()) {
      return (*i).second;
    }
    i = d_commandVerbosity.find("*");
    if(i != d_commandVerbosity.end()) {
      return (*i).second;
    }
    return Integer(2);
  }

  if(Dump.isOn("benchmark")) {
    Dump("benchmark") << GetOptionCommand(key);
  }

  if(key == "command-verbosity") {
    vector<SExpr> result;
    SExpr defaultVerbosity;
    for(map<string, Integer>::const_iterator i = d_commandVerbosity.begin();
        i != d_commandVerbosity.end();
        ++i) {
      vector<SExpr> v;
      v.push_back((*i).first);
      v.push_back((*i).second);
      if((*i).first == "*") {
        // put the default at the end of the SExpr
        defaultVerbosity = v;
      } else {
        result.push_back(v);
      }
    }
    // put the default at the end of the SExpr
    if(!defaultVerbosity.isAtom()) {
      result.push_back(defaultVerbosity);
    } else {
      // ensure the default is always listed
      vector<SExpr> v;
      v.push_back("*");
      v.push_back(Integer(2));
      result.push_back(v);
    }
    return result;
  }

  ${smt_getoption_handlers}

#line 134 "${template}"

  throw UnrecognizedOptionException(key);
}
Esempio n. 5
0
bool Game::pollSource()
{
	if(m_sexprSource == 0)
	{
		return false;
	}

	if(m_sexprSource->sexprReady())
	{
		SExpr sexpr = m_sexprSource->getSExpr();
		
		if(sexpr.type() == NodeType::Unknown)
		{
			return false;
		}
		
		if(sexpr[0] == "status")
		{
			GameState* state = new GameState;
			state->fromSExpr(sexpr);

			pushState(state);
			return true;
		}

        //Ident message
        //("ident" (("0" "MuesAI" "Stephen Mues" "human") ("1" "MuesAI" "Stephen Mues" "zombie")) "0")
		if(sexpr[0] == "ident")
		{
			SExpr ident = sexpr.next().list();
            if(ident.list()[3] == "zombie")
            {
			    m_zombieName = ident.list()[2];
			    m_humanName = ident.next().list()[2];
            }
            else
            {
			    m_humanName = ident.list()[2];
			    m_zombieName = ident.next().list()[2];
            }
		}

		if(sexpr[0] == "notification")
		{
            if(sexpr[1] == Config::instance()->get("user") || atoi(Config::instance()->get("arenaMode").c_str()) > 0)
			{
				cout << "A game was joined by the same player that this visualizer is logged in as" << endl;
                if( atoi(Config::instance()->get("autoJoin").c_str()) > 0 || atoi(Config::instance()->get("arenaMode").c_str()) > 0)
				{
                    cout << "Stopping reader thread" << endl;
					m_nextGame = sexpr[2];
                    Engine::instance()->stopPolling();
					//throw "die";
				}
			}
		}
	}

	return false;
}
Esempio n. 6
0
void Printer::toStream(std::ostream& out, const SExpr& sexpr) const throw() {
  if(sexpr.isInteger()) {
    out << sexpr.getIntegerValue();
  } else if(sexpr.isRational()) {
    out << fixed << sexpr.getRationalValue().getDouble();
  } else if(sexpr.isKeyword()) {
    out << sexpr.getValue();
  } else if(sexpr.isString()) {
    string s = sexpr.getValue();
    // escape backslash and quote
    for(size_t i = 0; i < s.length(); ++i) {
      if(s[i] == '"') {
        s.replace(i, 1, "\\\"");
        ++i;
      } else if(s[i] == '\\') {
        s.replace(i, 1, "\\\\");
        ++i;
      }
    }
    out << "\"" << s << "\"";
  } else {
    out << '(';
    const vector<SExpr>& kids = sexpr.getChildren();
    bool first = true;
    for(vector<SExpr>::const_iterator i = kids.begin(); i != kids.end(); ++i) {
      if(first) {
        first = false;
      } else {
        out << ' ';
      }
      out << *i;
    }
    out << ')';
  }
}/* Printer::toStream(SExpr) */
Esempio n. 7
0
ProtoType* ProtoInterpreter::sexp_to_type(SExpr* s) {
  if(s->isSymbol()) {
    const string &name = dynamic_cast<SE_Symbol &>(*s).name;
    if(name=="any") { return new ProtoType();
    } else if(name=="local") { return new ProtoLocal();
    } else if(name=="tuple") { return new ProtoTuple();
    } else if(name=="symbol") { return new ProtoSymbol();
    } else if(name=="number") { return new ProtoNumber();
    } else if(name=="scalar") { return new ProtoScalar();
    } else if(name=="boolean") { return new ProtoBoolean();
    } else if(name=="vector") { return new ProtoVector();
    } else if(name=="lambda" || name=="fun") { return new ProtoLambda();
    } else if(name=="field") { return new ProtoField();
    } else { return type_err(s,"Unknown type "+s->to_str());
    }
  } else if(s->isList()) {
    SE_List* sl = &dynamic_cast<SE_List &>(*s);
    if(!sl->op()->isSymbol()) 
      return type_err(s,"Compound type must start with symbol: "+ce2s(s));
    const string &name = dynamic_cast<SE_Symbol &>(*sl->op()).name;
    if(name=="tuple" || name=="vector") {
      ProtoTuple* t;
      if(name=="tuple") t=new ProtoTuple(true); else t=new ProtoVector(true);
      for(int i=1;i<sl->len();i++) {
        SExpr* subex = (*sl)[i];
        if(subex->isSymbol()
           && dynamic_cast<SE_Symbol &>(*subex).name=="&rest") {
          t->bounded=false; continue;
        }
        ProtoType* sub = sexp_to_type(subex);
        if(name=="vector" && !sub->isA("ProtoScalar"))
          return type_err(sl,"Vectors must contain only scalars");
        t->types.push_back(sub);
      }
      return t;
    } else if(name=="lambda" || name=="fun") {
      if(sl->len()!=3) return type_err(s,"Bad lambda type: "+s->to_str());
      Signature* sig = sexp_to_sig((*sl)[1]);
      sig->output = sexp_to_type((*sl)[2]);
      return new ProtoLambda(new Operator(s,sig));
    } else if(name=="field") {
      if(sl->len()!=2) return type_err(s,"Bad field type: "+s->to_str());
      ProtoType* sub = sexp_to_type((*sl)[1]);
      if(sub->isA("ProtoField")) 
        return type_err(s,"Field type must have a local subtype");
      return new ProtoField(sub);
    } else {
      return type_err(s,"Unknown type "+s->to_str());
    }
  } else { // scalars specify ProtoScalar literals
    return new ProtoScalar(dynamic_cast<SE_Scalar &>(*s).value);
  }
}
Esempio n. 8
0
// Parse the extra arguments of a primitive into attributes
void parse_primitive_attributes(SE_List_iter* li,Primitive* p) {
  while(li->has_next()) {
    SExpr* v = li->get_next();
    if(!v->isKeyword()) {compile_error(v,v->to_str()+" not a keyword"); return;}
    const string &name = dynamic_cast<SE_Symbol &>(*v).name;
    if(p->attributes.count(name))
      compile_warn("Primitive "+p->name+" overriding duplicate '"
                   +name+"' attribute");
    if(li->has_next() && !li->peek_next()->isKeyword()) {
      p->attributes[name]=new SExprAttribute(li->get_next());
    } else {
      p->attributes[name]=new MarkerAttribute(true);
    }
  }
}
Esempio n. 9
0
// walks through, copying (and inheriting attributes)
SExpr* ProtoInterpreter::macro_substitute(SExpr* src, Env* e, SE_List* wrapper) {
  if(is_gensym(src)) { // substitute with a gensym for this instance
    SE_Symbol *groot = &dynamic_cast<SE_Symbol &>(*src);
    SExpr *gensym;
    CompilationElement *element = e->lookup(groot->name);
    if (element == 0) {
      gensym = make_gensym(groot->name);
      gensym->inherit_attributes(src);
      e->bind(groot->name, gensym);
    } else {
      gensym = &dynamic_cast<SExpr &>(*element);
    }
    return gensym;
  } else if(src->isList()) { // SE_List
    SE_List *srcl = &dynamic_cast<SE_List &>(*src);
    string opname
      = ((*srcl)[0]->isSymbol() ? dynamic_cast<SE_Symbol &>(*(*srcl)[0]).name
         : "");
    if(opname=="comma") {
      if(srcl->len()!=2 || !(*srcl)[1]->isSymbol())
        return sexp_err(src,"Bad comma form: "+src->to_str());
      SE_Symbol* sn = &dynamic_cast<SE_Symbol &>(*(*srcl)[1]);
      // insert source text
      return dynamic_cast<SExpr &>(*e->lookup(sn,"SExpr")).copy();
    } else if(opname=="comma-splice") {
      if(wrapper==NULL)
        return sexp_err(src,"Comma-splice "+(*srcl)[0]->to_str()+" w/o list");
      if(srcl->len()!=2 || !(*srcl)[1]->isSymbol())
        return sexp_err(src,"Bad comma form: "+src->to_str());
      SE_Symbol* sn = &dynamic_cast<SE_Symbol &>(*(*srcl)[1]);
      SE_List* value = &dynamic_cast<SE_List &>(*e->lookup(sn,"SE_List"));
      for(int i=0;i<value->len();i++) 
        wrapper->add((*value)[i]->copy());
      return NULL; // comma-splices return null
    } else { // otherwise, just substitute each child
      SE_List *l = new SE_List();
      SE_List *srcl = &dynamic_cast<SE_List &>(*src);
      for(int i=0;i<srcl->len();i++) {
        SExpr* sub = macro_substitute((*srcl)[i],e,l);
        if(sub!=NULL) l->add(sub); // comma-splices add selves and return null
      }
      return l;
    }
  } else { // symbol or scalar
    return src->copy();
  }
}
Esempio n. 10
0
File: sexpr.cpp Progetto: CVC4/CVC4
void SExpr::toStreamRec(std::ostream& out, const SExpr& sexpr,
                        OutputLanguage language, int indent) {
  StreamFormatScope scope(out);

  if (sexpr.isInteger()) {
    out << sexpr.getIntegerValue();
  } else if (sexpr.isRational()) {
    const double approximation = sexpr.getRationalValue().getDouble();
    out << std::fixed << approximation;
  } else if (sexpr.isKeyword()) {
    out << sexpr.getValue();
  } else if (sexpr.isString()) {
    std::string s = sexpr.getValue();
    // escape backslash and quote
    for (size_t i = 0; i < s.length(); ++i) {
      if (s[i] == '"') {
        s.replace(i, 1, "\\\"");
        ++i;
      } else if (s[i] == '\\') {
        s.replace(i, 1, "\\\\");
        ++i;
      }
    }
    out << "\"" << s << "\"";
  } else {
    const std::vector<SExpr>& kids = sexpr.getChildren();
    out << (indent > 0 && kids.size() > 1 ? "( " : "(");
    bool first = true;
    for (std::vector<SExpr>::const_iterator i = kids.begin(); i != kids.end();
         ++i) {
      if (first) {
        first = false;
      } else {
        if (indent > 0) {
          out << "\n" << std::string(indent, ' ');
        } else {
          out << ' ';
        }
      }
      toStreamRec(out, *i, language,
                  indent <= 0 || indent > 2 ? 0 : indent + 2);
    }
    if (indent > 0 && kids.size() > 1) {
      out << '\n';
      if (indent > 2) {
        out << std::string(indent - 2, ' ');
      }
    }
    out << ')';
  }
} /* toStreamRec() */
Esempio n. 11
0
 SExpr convertInvoke(const SExpr& invoke) {
     std::string resultString = "call " + currentModule_->exportedFunction(invoke[1].value())->name() + " ";
     for (std::size_t i = 2; i < invoke.children().size(); i++) {
         resultString += invoke[i].toString();
         resultString += " ";
     }
     SExpr result = SExprParser::parseString(resultString);
     return result;
 }
Esempio n. 12
0
 SExpr* SPrimScope::inlineEQ() {
   if (PrintInlining) lprintf("%*s*inlining _Eq\n", (void*)(depth-1), ""); 
   NodeGen* ng = theNodeGen;
   if (SICDebug) ng->comment("inlined _Eq");
   SExpr* arg = args->top();
   PReg* r  = receiver->preg();
   PReg* ar = arg->preg();
   ng->append(new ArithRRNode(SubCCArithOp, r, ar, ng->noPR));
   Node* test = ng->append(new BranchNode(EQBranchOp));
   Node* falseNode;
   test->append(falseNode = new AssignNode(falsePR(), resultPR));
   SExpr* e1 = new ConstantSExpr(Memory->falseObj, resultPR, falseNode);
   MergeNode* merge = new MergeNode("inlineEQ merge");
   falseNode->append(merge);
   Node* trueNode = new AssignNode(truePR(), resultPR);
   ng->current = test->append1(trueNode);
   SExpr* e2 = new ConstantSExpr(Memory->trueObj, resultPR, trueNode);
   ng->branch(merge);
   SExpr* res = e1->copyMergeWith(e2, resultPR, ng->current);
   return res;
 }
Esempio n. 13
0
File: sexpr.cpp Progetto: CVC4/CVC4
bool SExpr::operator==(const SExpr& s) const {
  if (d_sexprType == s.d_sexprType && d_integerValue == s.d_integerValue &&
      d_rationalValue == s.d_rationalValue &&
      d_stringValue == s.d_stringValue) {
    if (d_children == NULL && s.d_children == NULL) {
      return true;
    } else if (d_children != NULL && s.d_children != NULL) {
      return getChildren() == s.getChildren();
    }
  }
  return false;
}
Esempio n. 14
0
 lookupTarget* sicScopeLookupTarget::get_target_for_slot(slotDesc* s,
                                                         simpleLookup* L) {
   Unused(L);
   if (s->name == VMString[LEXICAL_PARENT]) {
     return new sicScopeLookupTarget(scope->parent());
   } else if (s->name == VMString[SELF]) {
     SExpr* t = scope->receiverExpr();
     if (t->isConstantSExpr()) {
       return (new objectLookupTarget(t->constant())) -> be_receiver();
     } else if (t->hasMap()) {
       return ( new mapLookupTarget(t->map())) -> be_receiver();
     } else {
       // don't know the receiver type
       return NULL;
     }
   } else if (! s->is_map_slot()) {
     return NULL;
   } else {
     return new objectLookupTarget(s->data);
   }
 }
Esempio n. 15
0
  SExpr* SPrimScope::inlineIntArithmetic() {
    ArithOpCode op = opcode_for_selector(_selector);
      
    bool intRcvr =
      receiver->hasMap() && receiver->map() == Memory->smi_map;
    SExpr* arg = args->nth(0);
    bool intArg = arg->hasMap() && arg->map() == Memory->smi_map;
    if ( intArg
    &&   arg->isConstantSExpr()
    &&   intRcvr
    &&   arg->constant() == as_smiOop(0)
    &&   can_fold_rcvr_op_zero_to_zero(op)) {
      if (PrintInlining)
        lprintf("%*s*constant-folding %s: 0\n", (void*)(depth-1), "", ArithOpName[op]);
      return receiver;
    }
    if (PrintInlining) lprintf("%*s*inlining %s:\n", (void*)(depth-1),
                               "", ArithOpName[op]);

    if (!TArithRRNode::isOpInlinable(op))
      return NULL;
      
    NodeGen* n = theNodeGen;
    Node* arith = n->append(new TArithRRNode(op, receiver->preg(), arg->preg(),
                                             resultPR, intRcvr, intArg));

    // success case - no overflow, int tags
    MergeNode* ok = (MergeNode*)n->append(new MergeNode("inlineIntArithmetic ok"));
    SExpr* succExpr = new MapSExpr(Memory->smi_map->enclosing_mapOop(), resultPR, ok);
    // merge of success & failure branches
    MergeNode* done = (MergeNode*)ok->append(new MergeNode("inlineIntArithmetic done"));

    // failure case
    n->current = arith->append1(new NopNode);
    if (theSIC->useUncommonTraps &&
        sender()->rscope->isUncommonAt(sender()->bci(), true)) {
      n->uncommonBranch(currentExprStack(0), true);
      n->current = done;
      if (PrintInlining) {
        lprintf("%*s*making arithmetic failure uncommon\n", (void*)(depth-1),
                "");
      }
      return succExpr;
    } else {
      fint b = bci();
      PReg* error = new SAPReg(_sender, b, b);
      if (intRcvr && intArg) {
        // must be overflow
        n->loadOop(VMString[OVERFLOWERROR], error);
      } else {
        arith->hasSideEffects_now = true;    // may fail, so can't eliminate
        if (intRcvr || TARGET_ARCH == I386_ARCH) {
          // arg & TagMask already done by TArithRRNode
          // I386 does 'em all
        } else {
          PReg* t = new TempPReg(this, Temp1, false, true);
          n->append(new ArithRCNode(AndCCArithOp, t, Tag_Mask, t));
          n->current->hasSideEffects_now = true;
        }
        // Note: this code assumes that condcode EQ means overflow
        Node* branch = n->append(new BranchNode(EQBranchOp));
        // no overflow, must be type error
        n->loadOop(VMString[BADTYPEERROR], error);
        MergeNode* cont = (MergeNode*)n->append(
          new MergeNode("inlineIntArithmetic cont"));
        // overflow error
        PReg* err = new_ConstPReg(_sender, VMString[OVERFLOWERROR]);
        n->current = branch->append1(new AssignNode(err, error));
        n->branch(cont);
      }
      Node* dummy;
      SExpr* failExpr = genPrimFailure(NULL, error, dummy, done, resultPR);
      assert(done, "merge should always exist");
      return succExpr->mergeWith(failExpr, done);
    }
  }
Esempio n. 16
0
 const char* NodeGen::splitCondBranch( MergeNode*           targetNode,
                                       bool                 isBackwards,
                                       PReg*                targetPR,
                                       SExpr*               testExpr,
                                       BranchBCTargetStack* targetStack,
                                       SExprStack*          exprStack,
                                       PRegBList*           exprStackPRs, 
                                       SplitSig*            s ) {
   // try to split a conditional branch bc to avoid materializing
   // the boolean
   
   // local splitting only for now
 
   assert(targetPR->isConstPReg(), 
          "cond branch must be testing for constant");
   oop targetOop = ((ConstPReg*)targetPR)->constant;
   
   if (!testExpr->isMergeSExpr()) 
     return "testExpr not MergeSExpr";
   if (!((MergeSExpr*)testExpr)->isSplittable()) 
     return "textExpr not splittable";
   SExprBList* exprs = ((MergeSExpr*)testExpr)->exprs;
   assert(testExpr->node(), "splittable implies node()");
   Node* preceedingMerge = testExpr->node();
   if (current != preceedingMerge)
     return "not local"; // local only for now
   
   if ( preceedingMerge->nPredecessors() != exprs->length() )
     return "would have to iterate over predecessors";
     
   fint i;
   for ( i = 0;  
         i < exprs->length(); 
         ++i) {
      SExpr* e = exprs->nth(i);
      Node* n = e->node();
      if ( !preceedingMerge->isPredecessor(n) )
        return "merge not immediately after expr node";
      if ( !e->isConstantSExpr() )
        return "merge contains non-constant expression";
   }
   MergeNode* mergeForBranching      = new MergeNode("for branching");
   MergeNode* mergeForFallingThrough = new MergeNode("for falling through");
   mergeForBranching     ->setScope(currentScope());
   mergeForFallingThrough->setScope(currentScope());
   for ( i = 0;  
         i < exprs->length();  
         ++i) {
     SExpr* e = exprs->nth(i);
     Node* n = e->node();
     MergeNode* mn = e->constant() == targetOop
       ?  mergeForBranching
       :  mergeForFallingThrough;
     mn->setPrev(n);
     n->moveNext(preceedingMerge, mn);
   }     
   while (preceedingMerge->nPredecessors())
     preceedingMerge->removePrev(preceedingMerge->prev(0));
      
   current = mergeForBranching;
   branchCode( targetNode,
               isBackwards,
               NULL,
               NULL,
               targetStack,
               exprStack,
               exprStackPRs,
               s);
               
   append(mergeForFallingThrough);
   return NULL;
 }
Esempio n. 17
0
Field *
ProtoInterpreter::letfed_to_graph(SE_List *s, AM *space, Env *env,
    bool init)
{
  // Parse the input with the beautiful pattern matching language that
  // C++ affords us.
  if (! ((s->len() >= 3) & (*s)[1]->isList()))
    return field_err(s, space, "Malformed letfed expression: " + s->to_str());

  vector<SExpr *>::const_iterator iterator = s->args();
  SE_List *bindings = &dynamic_cast<SE_List &>(*(*iterator++));
  size_t n = bindings->len();

  vector<SExpr *> patterns;
  vector<SExpr *> initial_expressions;
  vector<SExpr *> update_expressions;

  for (size_t i = 0; i < n; i++) {
    SExpr *binding = (*bindings)[i];
    if (!binding->isList())
      compile_error(binding, "Malformed letfed binding: " + binding->to_str());
    SE_List *binding_list = &dynamic_cast<SE_List &>(*binding);
    if (binding_list->len() != 3)
      compile_error(binding, "Malformed letfed binding: " + binding->to_str());
    SExpr *pattern = (*binding_list)[0];
    if (!letfed_pattern_p(pattern))
      compile_error(pattern, "Malformed letfed pattern: " + pattern->to_str());
    patterns.push_back(pattern);
    initial_expressions.push_back((*binding_list)[1]);
    update_expressions.push_back((*binding_list)[2]);
  }

  // Create the environments, conditional OIs, and subspaces.
  Env *body_env = new Env(env), *update_env = new Env(env);
  OI *true_if_change, *false_if_change;
  AM *initial_space, *update_space;

  if (init) {
    true_if_change = new OI(s, Env::core_op("dchange"), space);
    false_if_change = new OI(s, Env::core_op("not"), space);
    false_if_change->add_input(true_if_change->output);
    initial_space = new AM(s, space, true_if_change->output);
    update_space = new AM(s, space, false_if_change->output);
  } else {
    true_if_change = false_if_change = 0;
    initial_space = 0;
    update_space = space;
  }

  // Evaluate the initial expressions.
  vector<OI *> ois;
  for (size_t i = 0; i < n; i++) {
    SExpr *binding = (*bindings)[i];
    SExpr *pattern = patterns[i];
    SExpr *initial_expression = initial_expressions[i];

    OI *delay = new OI(binding, Env::core_op("delay"), update_space);

    if (init) {
      OI *mux = new OI(binding, Env::core_op("mux"), space);
      mux->attributes["LETFED-MUX"] = new MarkerAttribute(true);
      mux->add_input(true_if_change->output);
      mux->add_input(sexp_to_graph(initial_expression, initial_space, env));
      delay->add_input(mux->output);
      ois.push_back(mux);
    } else {
      delay->output->range = sexp_to_type(initial_expression);
      ois.push_back(delay);
    }

    // Bind the pattern variables to the delayed fields in the
    // environment for the update expression.
    bind_letfed_pattern(pattern, delay->output, update_space, update_env);
  }

  // Evaluate the update expressions.
  for (size_t i = 0; i < n; i++) {
    SExpr *binding = (*bindings)[i];
    SExpr *pattern = patterns[i];
    SExpr *update_expression = update_expressions[i];

    Field *update = sexp_to_graph(update_expression, update_space, update_env);
    Field *field;

    if (init)
      field = ois[i]->output;
    else
      field = update;

    // Bind the pattern variables to the actual field in the body.
    bind_letfed_pattern(pattern, field, space, body_env);

    // Feed the update field back into the mux/delay OI.
    ois[i]->add_input(update);
  }

  // Evaluate the body.
  Field *field = 0;
  while (iterator != s->children.end())
    field = sexp_to_graph(*iterator++, space, body_env);

  return field;
}
Esempio n. 18
0
// returns the output field
Field* ProtoInterpreter::sexp_to_graph(SExpr* s, AM* space, Env *env) {
  V3 << "Interpret: " << ce2s(s) << " in " << ce2s(space) << endl;
  if(s->isSymbol()) {
    // All other symbols are looked up in the environment
    CompilationElement* elt = env->lookup(dynamic_cast<SE_Symbol &>(*s).name);
    if(elt==NULL) { 
      V4 << "Symbolic literal?\n";
      ProtoType* val = symbolic_literal(dynamic_cast<SE_Symbol &>(*s).name);
      if(val) { V4 << "- Yes\n"; return dfg->add_literal(val,space,s); }
      return field_err(s,space,"Couldn't find definition of "+s->to_str());
    } else if(elt->isA("Field")) { 
      V4 << "Found field: " << ce2s(elt) << endl;
      Field* f = &dynamic_cast<Field &>(*elt);
      if(f->domain==space) { return f;
      } if(f->domain->child_of(space)) {
        ierror(s,"Direct reference to child space in parent:"+ce2s(s));
      } else { // implicit restriction
        OI *oi = new OperatorInstance(s,Env::core_op("restrict"),space);
        oi->add_input(f);
        if(space->selector) oi->add_input(space->selector); 
        return oi->output;
      }
    } else if(elt->isA("Operator")) {
      V4 << "Lambda literal: " << ce2s(elt) << endl;
      return dfg->add_literal(new ProtoLambda(&dynamic_cast<Operator &>(*elt)),
          space, s);
    } else if(elt->isA("MacroSymbol")) {
      V4 << "Macro: " << ce2s(elt) << endl;
      return
        sexp_to_graph(dynamic_cast<MacroSymbol &>(*elt).pattern,space,env);
    } else return field_err(s,space,"Can't interpret "+elt->type_of()+" "+
                            s->to_str()+" as field");
  } else if(s->isScalar()) { // Numbers are literals
    V4 << "Numeric literal.\n";
    return
      dfg->add_literal(new ProtoScalar(dynamic_cast<SE_Scalar &>(*s).value),
          space,s);
  } else { // it must be a list
    // Lists are special forms or function applicatios
    SE_List* sl = &dynamic_cast<SE_List &>(*s);
    if(sl->len()==0) return field_err(sl,space,"Expression has no members"); 
    if(sl->op()->isSymbol()) { 
      // check if it's a special form
      string opname = dynamic_cast<SE_Symbol &>(*sl->op()).name;
      if(opname=="let") { return let_to_graph(sl,space,env,false);
      } else if(opname=="let*") { return let_to_graph(sl,space,env,true);
      } else if(opname=="all") { // evaluate children, returning last field
        Field* last=NULL;
        V4 << "Found 'all' construct\n";
        for(int j=1;j<sl->len();j++) last = sexp_to_graph((*sl)[j],space,env);
        return last;
      } else if(opname=="restrict"){ 
        return restrict_to_graph(sl,space,env);
      } else if(opname=="def" && sl->len()==3) { // variable definition
        SExpr *def=(*sl)[1], *exp=(*sl)[2];
        if(!def->isSymbol())
          return field_err(sl,space,"def name not a symbol: "+def->to_str());
        Field* f = sexp_to_graph(exp,space,env);
        env->force_bind(dynamic_cast<SE_Symbol &>(*def).name,f);
        V4 << "Defined variable: " << ce2s(f) << endl;
        return f;
      } else if(opname=="def" || opname=="primitive" || 
                opname=="lambda" || opname=="fun") {
        Operator* op = sexp_to_op(s,env);
        if(!(opname=="lambda" || opname=="fun")) return NULL;
        return dfg->add_literal(new ProtoLambda(op),space,s);
      } else if(opname=="annotate") {
        SE_List_iter li(sl); li.get_next(); // make iterator, discard op
        string name = li.get_token("operator name");
        CE* p = env->lookup(name);
        if(p==NULL) {
          compile_error(sl,"Can't find primitve '"+name+"' to annotate");
        } else if(!p->isA("Primitive")) {
          compile_error(sl,"Can't annotate '"+name+"': not a primitive");
        } else {
          // add in attributes
          parse_primitive_attributes(&li, &dynamic_cast<Primitive &>(*p));
        }
        return NULL; // annotations are like primitives: nothing returned
      } else if(opname=="letfed" || opname=="letfed+") {
        return letfed_to_graph(sl,space,env,opname=="letfed");
      } else if(opname=="macro") {
        V4 << "Defining macro\n";
        sexp_to_macro(sl,env);
        return NULL;
      } else if(opname=="include") {
        for(int j=1;j<sl->len();j++) {
          SExpr *ex = (*sl)[j];
          V4 << "Including file: "<<ce2s(ex)<<endl;
          if(ex->isSymbol())
            interpret_file(dynamic_cast<SE_Symbol &>(*ex).name);
          else compile_error(ex,"File name "+ex->to_str()+" is not a symbol");
        }
        return NULL;
      } else if(opname=="quote") {
        if(sl->len()!=2) 
          return field_err(sl,space,"Quote requires an argument: "+s->to_str());
        V4 << "Creating quote literal\n";
        return dfg->add_literal(quote_to_literal_type((*sl)[1]),space,s);
      } else if(opname=="quasiquote") {
        return field_err(sl,space,"Quasiquote only allowed in macros: "+sl->to_str());
      }
      // check if it's a macro
      CompilationElement* ce = env->lookup(opname);
      if(ce && ce->isA("Macro")) {
        V4 << "Applying macro\n";
        SExpr* new_expr;
        if(ce->isA("MacroOperator")) {
          new_expr = expand_macro(&dynamic_cast<MacroOperator &>(*ce),sl);
          if(new_expr->attributes.count("DUMMY")) // Mark of a failure
            return field_err(s,space,"Macro expansion failed on "+s->to_str());
        } else { // it's a MacroSymbol
          new_expr = sl->copy();
          dynamic_cast<SE_List &>(*new_expr).children[0]
            = dynamic_cast<Macro &>(*ce).pattern;
        }
        return sexp_to_graph(new_expr,space,env);
      }
    }
    // if we didn't return yet, it's an ordinary composite expression
    Operator *op = sexp_to_op(sl->op(),env);
    if(op->marked(":protected"))
      compile_warn(op,"operator '"+op->name+"' not intended for direct use.");
    OperatorInstance *oi = new OperatorInstance(s,op,space);
    for(vector<SExpr*>::iterator it=sl->args(); it!=sl->children.end(); it++) {
      Field* sub = sexp_to_graph(*it,space,env);
      // operator defs, primitives, and macros return null & are ignored
      if(sub) oi->add_input(sub);
    }
    if(!op->signature->legal_length(oi->inputs.size())) {
      compile_error(s,"Called "+ce2s(op)+" with "+i2s(oi->inputs.size())+
                    " arguments; it requires "+op->signature->num_arg_str());
    }
    V4 << "Added operator "<<ce2s(oi)<<endl;
    return oi->output;
  }
  ierror("Fell through sexp_to_graph w/o returning for: "+s->to_str());
}
Esempio n. 19
0
 Log * makeSTATSlog() {
     //Log state.
     std::vector<SExpr> fields;
     fields.push_back(SExpr(CONTENT_TYPE_S, "STATS"));
     
     std::vector<SExpr> fvector = {
         SExpr("flags"),
         SExpr("serv_connected", control::serv_connected,
               control::flags[control::serv_connected]),
         SExpr("control_connected", control::control_connected,
               control::flags[control::control_connected]),
         SExpr("fileio", control::fileio,
               control::flags[control::fileio]),
         SExpr("SENSORS", control::SENSORS,
               control::flags[control::SENSORS]),
         SExpr("GUARDIAN", control::GUARDIAN,
               control::flags[control::GUARDIAN]),
         SExpr("COMM", control::COMM,
               control::flags[control::COMM]),
         SExpr("LOCATION", control::LOCATION,
               control::flags[control::LOCATION]),
         SExpr("ODOMETRY", control::ODOMETRY,
               control::flags[control::ODOMETRY]),
         SExpr("OBSERVATIONS", control::OBSERVATIONS,
               control::flags[control::OBSERVATIONS]),
         SExpr("LOCALIZATION", control::LOCALIZATION,
               control::flags[control::LOCALIZATION]),
         SExpr("BALLTRACK", control::BALLTRACK,
               control::flags[control::BALLTRACK]),
         
         SExpr("VISION", control::VISION,
               control::flags[control::VISION]),
         
         SExpr("tripoint", control::tripoint,
               control::flags[control::tripoint]),
         
         SExpr("thumbnail", control::thumbnail,
               control::flags[control::thumbnail])
     };
     fields.push_back(SExpr(fvector));
     
     
     fields.push_back(SExpr("num_buffers", NUM_LOG_BUFFERS));
     fields.push_back(SExpr("num_cores", (int) NUM_CORES));
     
     SExpr ratios;
     ratios.append(SExpr("ratio"));
     for (int i = 0; i < NUM_LOG_BUFFERS; ++i) {
         ratios.append(SExpr(LOG_RATIO[i]));
     }
     fields.push_back(ratios);
     
     SExpr sizes;
     sizes.append(SExpr("size"));
     for (int i = 0; i < NUM_LOG_BUFFERS; ++i) {
         sizes.append(SExpr(LOG_BUFFER_SIZES[i]));
     }
     fields.push_back(sizes);
     
     time_t NOW = time(NULL);
     
     fields.push_back(SExpr("con_uptime", control::flags[control::serv_connected] ? difftime(NOW, cio_upstart) : 0));
     fields.push_back(SExpr("cnc_uptime", control::flags[control::control_connected] ? difftime(NOW, cnc_upstart) : 0));
     fields.push_back(SExpr("fio_uptime", control::flags[control::fileio] ? difftime(NOW, fio_upstart) : 0));
     
     fields.push_back(SExpr("log_uptime", difftime(NOW, main_upstart)));
     
     SExpr manages;
     manages.append(SExpr("bufmanage"));
     for (int i = 0; i < NUM_LOG_BUFFERS; ++i) {
         manages.append(makeBufManage(i));
     }
     fields.push_back(manages);
     
     /*
      This system of grabbing io state is subject to multi-threading accuracy drift.
      It is therefore only for estimates.
      */
     io_state_t zerostate;
     bzero(&zerostate, sizeof(io_state_t));
     
     SExpr state_total;
     state_total.append(SExpr("total-state"));
     for (int i = 0; i < NUM_LOG_BUFFERS; ++i) {
         state_total.append(makeBufState(&zerostate, total + i));
     }
     fields.push_back(state_total);
     
     if (control::flags[control::fileio]) {
         SExpr state_file;
         state_file.append(SExpr("file-state"));
         for (int i = 0; i < NUM_LOG_BUFFERS; ++i) {
             state_file.append(makeBufState(fio_start + i, total + i));
         }
         fields.push_back(state_file);
     }
     
     if (control::flags[control::serv_connected]) {
         SExpr state_serv;
         state_serv.append(SExpr("serv-state"));
         for (int i = 0; i < NUM_LOG_BUFFERS; ++i) {
             state_serv.append(makeBufState(cio_start + i, total + i));
         }
         fields.push_back(state_serv);
     }
     
     std::vector<SExpr> contents = {SExpr(fields)};
     
     return new Log(LOG_FIRST_ATOM_S, "makeSTATSlog()", time(NULL), LOG_VERSION, contents, "");
 };
Esempio n. 20
0
 SExpr* SCodeScope::typePredict(SendInfo* info) {
   // try static type prediction
   PReg* r = info->rcvr->preg();
   stringOop sel = info->sel;
   if (sel == VMString[IF_TRUE_] ||
       sel == VMString[IF_FALSE_] ||
       sel == VMString[IF_TRUE_FALSE_] ||
       sel == VMString[IF_FALSE_TRUE_] ||
       sel == VMString[OR]  || sel == VMString[AND] || sel == VMString[NOT]) {
     // boolean message
     if (PrintInlining) {
       lprintf("%*s*type-predicting %s\n", (void*)depth, "",
              sel->copy_null_terminated());
     }
     info->predicted = true;
     bool allowUnlikely = theSIC->useUncommonTraps;
     if (SICDeferUncommonBranches &&
         (sel == VMString[IF_TRUE_] ||
          sel == VMString[IF_FALSE_] ||
          sel == VMString[IF_TRUE_FALSE_] ||
          sel == VMString[IF_FALSE_TRUE_])) {
       // these bets are really safe - make uncommon even when recompiling
       // due to uncommon trap (if the ifTrue itself caused the trap,
       // rscope->isUncommonAt will be false, so this is safe)
       allowUnlikely = true;
     }
     if (allowUnlikely) {
       if (rscope->isUncommonAt(_bci, false)) {
         // ok, no uncommon trap here
       } else if (rscope->hasSubScopes(_bci)) {
         // has real send for ifTrue et al. -- must be NIC-compiled
         // make uncommon unlikely if no non-true/false receiver present
         RScopeBList* subs = rscope->subScopes(_bci);
         for (fint i = subs->length() - 1; i >= 0; i--) {
           RScope* s = subs->nth(i);
           SExpr* rcvr = s->receiverExpr();
           if (rcvr->hasMap()) {
             Map* m = rcvr->map();
             if (m != Memory-> true_map() &&
                 m != Memory->false_map()) {
               allowUnlikely = false;
               break;
             }
           }
         }
         if (WizardMode && !allowUnlikely)
           warning("SIC: non-bool receiver for ifTrue: et al. detected");
       }
       if (allowUnlikely) {
         // make unknown case unlikely despite 
         info->rcvr = info->rcvr->makeUnknownUnlikely(this);
       }
     }
     SExpr* rcvr = info->rcvr;
     SExpr* t = new ConstantSExpr(Memory->trueObj , r, NULL);
     SExpr* f = new ConstantSExpr(Memory->falseObj, r, NULL);
     // make sure we don't destroy splitting info; only add types if not
     // already present
     if (rcvr->findMap(Memory-> true_mapOop()) == NULL)
       rcvr = rcvr->mergeWith(t, NULL);
     if (rcvr->findMap(Memory->false_mapOop()) == NULL)
       rcvr = rcvr->mergeWith(f, NULL);
     return rcvr;
   }
   
   if (// binary integer arithmetic messages
       sel == VMString[PLUS] ||
       sel == VMString[MINUS] ||
       sel == VMString[PERCENT] ||
       sel == VMString[LESS_THAN] ||
       sel == VMString[LESS_EQUAL] || 
       sel == VMString[GREATER_EQUAL] ||
       sel == VMString[GREATER_THAN] |
       // integer looping messages
       sel == VMString[TO_DO_] ||
       sel == VMString[UP_TO_DO_] ||
       sel == VMString[DOWN_TO_DO_] ||
       sel == VMString[TO_BY_DO_] ||
       sel == VMString[UP_TO_BY_DO_] ||
       sel == VMString[DOWN_TO_BY_DO_] ||
       // unary integer arithmetic selectors
       sel == VMString[SUCCESSOR] ||
       sel == VMString[SUCC] ||
       sel == VMString[PREDECESSOR] ||
       sel == VMString[PRED]) {
     if (info->rcvr->findMap(Memory->smi_map->enclosing_mapOop())) return info->rcvr;
     if (PrintInlining) {
       lprintf("%*s*type-predicting %s\n", (void*)depth, "",
               sel->copy_null_terminated());
     }
     info->predicted = true;
     SExpr* res =
       info->rcvr->mergeWith(new MapSExpr(Memory->smi_map->enclosing_mapOop(),
                                          r, NULL), NULL);
     if (theSIC->useUncommonTraps && rscope->isUncommonAt(_bci, false)) {
       info->rcvr = res = res->makeUnknownUnlikely(this);
     }
     return res;
   }
   
   return info->rcvr;
 }
Esempio n. 21
0
 SExpr* SCodeScope::picPredict(SendInfo* info) {
   // check PICs for information
   if (!UsePICRecompilation) return info->rcvr;
   bool canBeUnlikely = theSIC->useUncommonTraps;
   if (rscope->hasSubScopes(_bci)) {
     RScopeBList* l = rscope->subScopes(_bci);
     if (l->first()->isUntakenScope() && l->length() == 1) {
       return picPredictUnlikely(info, (RUntakenScope*)l->first());
     } else if (info->rcvr->containsUnknown()) {
       if (PrintInlining) {
         lprintf("%*s*PIC-type-predicting %s (%ld maps)\n", (void*)depth, "",
                 info->sel->copy_null_terminated(), (void*)l->length());
       }
       for (fint i = 0; i < l->length(); i++) {
         RScope* r = l->nth(i);
         SExpr* expr = r->receiverExpr();
         if (expr->isUnknownSExpr()) {
           // untaken real send (from PIC)
         } else if (expr->map()->is_block()) {
           // for now, doesn't make sense to predict block maps because of
           // map cloning
           if (PrintInlining) {
             lprintf("%*s*not predicting block map\n", (void*)depth, ""); 
           }
           canBeUnlikely = false;
         } else {
           SExpr* alreadyThere = info->rcvr->findMap(expr->myMapOop());
           if (alreadyThere) {
             // generalize to map if only have constant
             if (alreadyThere->isConstantSExpr())
               info->rcvr = info->rcvr->mergeWith(expr, NULL);
           } else {
             // add map only if type isn't already present (for splitting)
             info->predicted = true;
             info->rcvr = info->rcvr->mergeWith(expr, NULL);
             if (expr->hasConstant() && l->length() == 1) {
               // check to see if single predicted receiver is true or false;
               // if so, add other boolean to prediction.  Reduces the number
               // of uncommon branches; not doing so appears to be overly
               // aggressive (as observed experimentally)
               oop c = expr->constant();
               if (c == Memory->trueObj &&
                   !info->rcvr->findMap(Memory->false_mapOop())) {
                 SExpr* f = new ConstantSExpr(Memory->falseObj, NULL, NULL);
                 info->rcvr = info->rcvr->mergeWith(f, NULL);
               } else if (c == Memory->falseObj &&
                          !info->rcvr->findMap(Memory->true_mapOop())) {
                 SExpr* t = new ConstantSExpr(Memory->trueObj, NULL, NULL);
                 info->rcvr = info->rcvr->mergeWith(t, NULL);
               }
             }
           }
         }
       }
     } else {
       // know receiver type precisely
       return info->rcvr;
     }
     // mark unknown branch as unlikely
     UnknownSExpr* u = info->rcvr->findUnknown();
     if (u && canBeUnlikely && theSIC->useUncommonTraps && 
         rscope->isUncommonAt(_bci, false)) {
       info->rcvr = info->rcvr->makeUnknownUnlikely(this);
     }
   } else if (theSIC->useUncommonTraps &&
              info->primFailure &&
              rscope->isUncommonAt(_bci, true)) {
     // this is the failure send of a primitive, and the failure was made
     // uncommon in the recompilee, and it was never taken, so keep it
     // uncommon
     if (PrintInlining) {
       lprintf("%*s*PIC-type-predicting %s as never executed (2)\n",
               (void*)depth, "", info->sel->copy_null_terminated());
     }
     info->rcvr = new UnknownSExpr(info->rcvr->preg(), NULL, true);
   }
    
   assert(info->rcvr->preg(), "should have a preg");
   return info->rcvr;
 }
Esempio n. 22
0
  SExpr* SCodeScope::inlineSend(SendInfo* info) {
    stringOop sel = info->sel;
    SExpr* res = NULL;
    info->resReg = new SAPReg(this);
    MergeNode* merge = NULL;
    fint argc = sel->arg_count();

    if (!Inline && !InlineSTMessages) {
      // don't do any inlining
      info->needRealSend = true;
    } else {
      info->rcvr = picPredict(info);
      UnknownSExpr* u = info->rcvr->findUnknown();
      if (u && !u->isUnlikely()) {
        info->rcvr = typePredict(info);
      }
      
      if (info->rcvr->really_hasMap(this)) {
        // single map - try to inline this send
        SSelfScope* s = tryLookup(info, info->rcvr);
        if (s) {
          SExpr* r = doInline(s, info->rcvr, theNodeGen->current, NULL);
          if (r->isNoResultSExpr()) {
            res = r;
          } else {
            theNodeGen->append(new NopNode());   // to get right scope for r
            res = r->shallowCopy(r->preg(), theNodeGen->current);
          }
        } else {
          if (PrintInlining) {
            lprintf("%*s*marking %s send ReceiverStatic\n",
                    (void*)depth,"", selector_string(sel));
          }
          // receiver type is constant (but e.g. method was too big to inline)
          info->l |= ReceiverStaticBit;
          info->needRealSend = true;
        }
      } else if (info->rcvr->isMergeSExpr()) {
        res = inlineMerge(info, merge);
      } else {
        // unknown receiver
        // NB: *must* use uncommon branch if marked unlikely because
        // future type tests won't test for unknown
        if (info->rcvr->findUnknown()->isUnlikely()) {
          // generate an uncommon branch for the unknown case, not a send
          theNodeGen->current = theNodeGen->uncommonBranch(currentExprStack(0),
                                                           info->restartPrim);
          info->needRealSend = false;
          if (PrintInlining) {
            lprintf("%*s*making %s uncommon\n", (void*)depth,"",selector_string(sel));
          }
        } else {
          info->needRealSend = true;
        }
      }
    }
    
    if (info->needRealSend) {
      SExpr* r = genRealSend(info);
      res = res ? res->mergeWith(r, merge) : r;
    }
    if (merge && res && !res->isNoResultSExpr()) theNodeGen->branch(merge);

    // now pop expr stack
    for (fint i = 0; i < argc; i++) exprStack->pop();
    if (!info->isSelfImplicit) exprStack->pop();
    if (!res) res = new NoResultSExpr;
    return res;
  }
Esempio n. 23
0
  SExpr* SPrimScope::inlineAtPut(bool objVector) {
    assert(_selector == VMString[objVector ? _AT_PUT_ : _BYTE_AT_PUT_],
           "bad selector");
    bool okRcvr = receiver->hasMap();
    Map* rm;
    if (okRcvr) {
      rm = receiver->map();
      if (objVector) {
        okRcvr = rm->is_objVector();
      } else {
        okRcvr = rm->is_byteVector();
      }
    }
    if (!okRcvr) {
      // receiver type not known statically
      return NULL;
    }
    if (PrintInlining)
      lprintf("%*s*inlining _%sAtPut:\n", (void*)(depth-1),
              "", objVector ? "" :"Byte");
    
    SExpr* arg = args->nth(1);
    NodeGen* ng = theNodeGen;
    if (SICDebug) ng->comment("inlined _At:Put:/_ByteAt:Put:");
    fint b = bci();
    bool intArg   = arg->hasMap() && arg->map() == Memory->smi_map;
    bool willFail = arg->hasMap() && arg->map() != Memory->smi_map;
    bool useUncommonTrap = !willFail && theSIC->useUncommonTraps &&
      sender()->rscope->isUncommonAt(sender()->bci(), true);
    PReg* errorPR = useUncommonTrap ? NULL : new SAPReg(_sender, b, b);
    Node* at;
    if (objVector) {
      PReg* elementArgPR = args->nth(0)->preg();
      
      // materialize value arg
      theNodeGen->materializeBlock(elementArgPR, _sender->sig, new PRegBList(1));
      
      fint size = ((slotsMap*)rm)->empty_vector_object_size();
      at = new ArrayAtPutNode(receiver->preg(), arg->preg(), intArg,
                              elementArgPR, resultPR, errorPR,
                              size * oopSize - Mem_Tag);
    } 
    else {
      SExpr* value = args->nth(0);
      bool intVal = value->hasMap() && value->map() == Memory->smi_map;
      willFail   |= value->hasMap() && value->map() != Memory->smi_map;
      at = new ByteArrayAtPutNode(receiver->preg(), arg->preg(), intArg, 
                                  value->preg(), intVal, resultPR, errorPR);
    }
    ng->append(at);
    
    // success case - int index, in bounds
    MergeNode* ok = (MergeNode*)ng->append(new NopNode);
    // merge of success & failure branches
    MergeNode* done = (MergeNode*)ok->append(new MergeNode("inlineAtPut done"));

    // failure case
    SExpr* res = receiver->shallowCopy(resultPR, ok);
    ng->current = at->append1(new MergeNode("inlineAtPut current"));
    if (useUncommonTrap) {
      if (PrintInlining) {
        lprintf("%*s*making atPut: failure uncommon\n", (void*)(depth-1), "");
      }
      ng->uncommonBranch(currentExprStack(0), true);
      ng->current = done;
    } else {
      Node* dummy;
      SExpr* failExpr = genPrimFailure(NULL, errorPR, dummy, done, resultPR);
      assert(done, "node should always exist");
      res = res->mergeWith(failExpr, done);
    }
    return res;
  }
Esempio n. 24
0
void Animation::fromSExpr(SExpr in)
{ 
	 m_ids.clear();

	//enum Type{None, Add, Remove, Move, Turn, Attack, Hurt, Eat, Grab, Throw, Give, Build};
	//Sigh
	if(in[0] == "add")
	{
      m_type = Add;
      m_ids.push_back(atoi( in[1].c_str() ));
	}
	else if(in[0] == "move")
	{
      m_type = Move;
      m_ids.push_back(atoi( in[1].c_str() ));
      m_x = atoi( in[2].c_str() );
      m_y = atoi( in[3].c_str() );
	}
	else if(in[0] == "remove")
	{
      m_type = Remove;
      m_ids.push_back(atoi( in[1].c_str() ));
	}
	else if(in[0] == "attack")
	{
		m_type = Attack;
		m_ids.push_back(atoi( in[1].c_str() ));
		m_x = atoi( in[2].c_str() );
		m_y = atoi( in[3].c_str() );
	}
	else if(in[0] == "hurt")
	{
		m_type = Hurt;

		SExpr ids = in.next().list();
	  
		int count = ids.numElements();
		for(int i=0; i < count; ++i)
		{
			m_ids.push_back( atoi( ids[0].c_str() ));
			ids = ids.next();
		}
   }
   else if(in[0] == "turn")
   {
		m_type = Turn;
		m_ids.push_back(atoi( in[1].c_str() ));
		m_x = atoi( in[2].c_str() ); //Facing direction
   }
   //enum Type{None, Add, Remove, Move, Turn, Attack, Hurt, Eat, Grab, Throw, Give, Build};
   else if(in[0] == "eat")
   {
		m_type = Eat;
		m_ids.push_back(atoi( in[1].c_str() ));
		m_ids.push_back(atoi( in[2].c_str() ));
   }
   else if(in[0] == "grab")
   {
		m_type = Grab;
		m_ids.push_back(atoi( in[1].c_str() ));
		m_ids.push_back(atoi( in[2].c_str() ));
   }
   else if(in[0] == "throw")
   {
		m_type = Throw;
		m_ids.push_back(atoi( in[1].c_str() ));
		m_ids.push_back(atoi( in[2].c_str() ));
		m_x = atoi( in[3].c_str() );
		m_y = atoi( in[4].c_str() );
	}
	else if(in[0] == "give")
	{
		m_type = Give;
		m_ids.push_back(atoi( in[1].c_str() ));
		m_ids.push_back(atoi( in[2].c_str() ));
	}
	else if(in[0] == "build")
	{
		m_type = Build;
		m_ids.push_back(atoi( in[1].c_str() ));
		m_x = atoi( in[2].c_str() );
		m_y = atoi( in[3].c_str() );
	}
	else
	{
		//We don't know what this was...
		m_type = None;
	}   
}
Esempio n. 25
0
  SExpr* SPrimScope::inlineIntComparison() {
    BranchOpCode cond;
           if (_selector == VMString[_INT_EQ_]) {
      cond = EQBranchOp;
    } else if (_selector == VMString[_INT_LT_]) {
      cond = LTBranchOp;
    } else if (_selector == VMString[_INT_LE_]) {
      cond = LEBranchOp;
    } else if (_selector == VMString[_INT_GT_]) {
      cond = GTBranchOp;
    } else if (_selector == VMString[_INT_GE_]) {
      cond = GEBranchOp;
    } else if (_selector == VMString[_INT_NE_]) {
      cond = NEBranchOp;
    } else {
      return NULL;
    }

    bool intRcvr =
      receiver->hasMap() && receiver->map() == Memory->smi_map;
    SExpr* arg = args->nth(0);
    bool intArg = arg->hasMap() && arg->map() == Memory->smi_map;
    if (PrintInlining)
      lprintf("%*s*inlining int comparison prim\n", (void*)(depth-1), "");

    NodeGen* n = theNodeGen;
    Node* branch = n->append(new TBranchNode(cond, receiver->preg(), intRcvr,
                                             arg->preg(), intArg));

    // false branch
    n->move(falsePR(), resultPR);
    SExpr* falseExpr= new ConstantSExpr(Memory->falseObj, resultPR, n->current);
    MergeNode* done = (MergeNode*)n->append(
      new MergeNode("inlineIntComparison done"));

    // true branch
    n->current = branch->append1(new AssignNode(truePR(), resultPR));
    SExpr* trueExpr = new ConstantSExpr(Memory->trueObj, resultPR, n->current);
    n->branch(done);

    SExpr* res = trueExpr->copyMergeWith(falseExpr, resultPR, done);
    // failure branch
    if (!intRcvr || !intArg) {
      branch->hasSideEffects_now = true;
      if (theSIC->useUncommonTraps &&
          sender()->rscope->isUncommonAt(sender()->bci(), true)) {
        n->current = branch->append(2, new NopNode);
        n->uncommonBranch(currentExprStack(0), true);
        n->current = done;
        if (PrintInlining) {
          lprintf("%*s*making int comparison failure uncommon\n",
                  (void*)(depth-1), "");
        }
      } else {
        fint b = bci();
        PReg* error = new SAPReg(_sender, b, b);
        PReg* err = new_ConstPReg(_sender, VMString[BADTYPEERROR]);
        n->current = branch->append(2, new AssignNode(err, error));
        Node* dummy;
        SExpr* failExpr = genPrimFailure(NULL, error, dummy, done, resultPR);
        assert(done, "merge should always exist");
        res = (MergeSExpr*)res->mergeWith(failExpr, done);
      }
    }
    return res;
  }
Esempio n. 26
0
  SExpr* SCodeScope::inlineMerge(SendInfo* info, MergeNode*& merge) {
    // inline the send by type-casing; return uninlined cases in others list
    // If merge has no predecessors, return NULL for merge ref.
    SExpr* res = NULL;
    assert(info->rcvr->isMergeSExpr(), "must be a merge");
    MergeSExpr* r = (MergeSExpr*)info->rcvr;
    stringOop sel = info->sel;
    merge = NULL;

    if (r->isSplittable() && shouldSplit(info)) {
      return splitMerge(info, merge);
    }
                    
    fint ncases = r->exprs->length();
    if (ncases > SICTypeCaseLimit) {
      info->needRealSend = true;
      if (PrintInlining) {
        lprintf("%*s*not type-casing %s (%ld > SICTypeCaseLimit)\n",
                (void*)depth, "", selector_string(sel), (void*)ncases);
      }
      return res;
    }
    assert( merge == NULL, "I assume merge is out param only");
    merge = new MergeNode("inlineMerge merge");

    if (SICDebug) {
      char* s = NEW_RESOURCE_ARRAY(char, 200);
      sprintf(s, "begin type-case of %s (ends at node N%ld)",
              sel->copy_null_terminated(), long(merge->id()));
      theNodeGen->comment(s);
    }
    if (PrintInlining) {
      lprintf("%*s*type-casing %s\n", (void*)depth, "", selector_string(sel));
    }

    // build list of cases to inline
    // (add only immediate maps at first, collect others in ...2 lists
    SSelfScopeBList* slist  = new SSelfScopeBList(ncases);
    SSelfScopeBList* slist2 = new SSelfScopeBList(ncases);
    SExprBList* elist  = new SExprBList(ncases);
    SExprBList* elist2 = new SExprBList(ncases);
    SExprBList* others = new SExprBList(ncases);
    OopBList* mlist  = new OopBList(ncases);
    OopBList* mlist2 = new OopBList(ncases);
    bool needMapLoad = false;
    fint i;
    for (i = 0; i < ncases; i++) {    
      SExpr* nth = r->exprs->nth(i);
      assert(!nth->isConstantSExpr() || nth->next == NULL ||
             nth->constant() == nth->next->constant(),
             "shouldn't happen: merged consts - convert to map");
      SSelfScope* s;

      if (!nth->hasMap()  ||  (s = tryLookup(info, nth)) == NULL) {
        // cannot inline
        others->append(nth);
        info->needRealSend = true;
        continue;
      }
      // can inline this case

      // Notice that for immediates, instead of putting the constants in the mlist,
      // we put the maps. No point in optimizing just for 17. -- dmu 6/05
      Map* map = nth->map();
      if (map == Memory->smi_map  ||  map == Memory->float_map) {
        slist ->append(s);        // immediate maps go first
        // Bug fix: instead of nth->shallowCopy, must generalize to any 
        // with same map, not just the same constant, because other ints (for example)
        // will pass the type test, too. -- dmu 6/05
        elist ->append(new MapSExpr(map->enclosing_mapOop(), r->preg(), NULL));
        mlist ->append(map->enclosing_mapOop());
        continue;
      }
      // can inline but not immediate map
      slist2->append(s);        // append later
      elist2->append(nth->shallowCopy(r->preg(), NULL)); // use preg of merge
      if (nth->isConstantSExpr()) {
        mlist2->append(nth->constant());
      }
      else {
        needMapLoad = true; // will need to load map of testee
        mlist2->append(map->enclosing_mapOop());
      }
    }

    mlist->appendList(mlist2);
    elist->appendList(elist2);
    slist->appendList(slist2);
        
    // now do the type test and inline the individual cases
    if (slist->length() > 0) {
      memoizeBlocks(sel);
      
      Node* typeCase =
        theNodeGen->append(new TypeTestNode(r->preg(), mlist, needMapLoad,
                                            info->needRealSend));
      Node* fallThrough = typeCase->append(new NopNode);
      for (i = 0; i < slist->length(); i++) {
        theNodeGen->current = typeCase->append(i + 1, new NopNode);
        SExpr* e = doInline(slist->nth(i), elist->nth(i), theNodeGen->current, merge);
        if (!e->isNoResultSExpr()) {
          theNodeGen->append(new NopNode);
          e = e->shallowCopy(info->resReg, theNodeGen->current);
          res = res ? res->mergeWith(e, merge) : e;
        }
        theNodeGen->branch(merge);
      }
      theNodeGen->current = fallThrough;
    }
    if (res && res->isMergeSExpr()) 
      res->setNode(merge, info->resReg);
      
    assert( info->needRealSend &&  others->length() ||
           !info->needRealSend && !others->length(), "inconsistent");
           
    // NB: *must* use uncommon branch if marked unlikely because
    // future type tests won't test for unknown
                      
    if (others->isEmpty()) {
      // typecase cannot fail
      theNodeGen->deadEnd();
    }
    else if ( others->length() == 1
         &&   others->first()->isUnknownSExpr()
         &&   ((UnknownSExpr*)others->first())->isUnlikely()) {
            // generate an uncommon branch for the unknown case, not a send
            theNodeGen->uncommonBranch(currentExprStack(0), info->restartPrim);
            info->needRealSend = false;
            if (PrintInlining)
              lprintf("%*s*making %s uncommon (2)\n", (void*)depth,"",selector_string(sel));
    }
    return res;
  }
Esempio n. 27
0
  SExpr* SPrimScope::inlineAt(bool objVector) {
    assert(_selector == VMString[objVector ? _AT_ : _BYTE_AT_],
           "bad selector");
    bool okRcvr = receiver->hasMap();
    Map* rm;
    if (okRcvr) {
      rm = receiver->map();
      if (objVector) {
        okRcvr = rm->is_objVector();
      } else {
        okRcvr = rm->is_byteVector();
      }
    }
    if (!okRcvr) {
      // receiver type not known statically
      return NULL;
    }
    if (PrintInlining)
      lprintf("%*s*inlining %s\n", (void*)(depth-1), "",
              objVector ? "_At:" : "_ByteAt:");
    
    SExpr* arg = args->nth(0);
    NodeGen* ng = theNodeGen;
    if (SICDebug) ng->comment("inlined _At:/_ByteAt:");
    fint b = bci();
    bool intArg   = arg->hasMap() && arg->map() == Memory->smi_map;
    bool willFail = arg->hasMap() && arg->map() != Memory->smi_map;
    bool useUncommonTrap = !willFail && theSIC->useUncommonTraps &&
      sender()->rscope->isUncommonAt(sender()->bci(), true);
    // optimization: don't set error reg if using uncommon trap
    // (primitive will be reexecuted anyway)
    PReg* errorPR = useUncommonTrap ? NULL : new SAPReg(_sender, b, b);
    Node* at;
    if (objVector) {
      fint size = ((slotsMap*)rm)->empty_vector_object_size();
      at = new ArrayAtNode(receiver->preg(), arg->preg(), intArg,
                           resultPR, errorPR, size * oopSize - Mem_Tag);
                           
    } else {
      at = new ByteArrayAtNode(receiver->preg(), arg->preg(), intArg,
                               resultPR, errorPR);
    }
    ng->append(at);
    
    // success case - int index, in bounds
    NopNode* ok = (NopNode*)ng->append(new NopNode);
    // merge of success & failure branches
    MergeNode* done = (MergeNode*)ok->append(new MergeNode("inlineAt done"));

    // failure case
    ng->current = at->append1(new NopNode);
    if (useUncommonTrap) {
      if (PrintInlining) {
        lprintf("%*s*making at: failure uncommon\n", (void*)(depth-1), "");
      }
      ng->uncommonBranch(currentExprStack(0), true);
      ng->current = done;
    } else {
      Node* dummy;
      SExpr* failExpr = genPrimFailure(NULL, errorPR, dummy, done, resultPR);
      assert(done, "merge should exist");
    }
    return new UnknownSExpr(resultPR, ok);
  }
Esempio n. 28
0
    uint32_t cnc_setCameraParams(Log * arg) {
        size_t u = arg->data().size();
        bool success = receivedParams.ParseFromString(arg->data());
        if(!success) {
            std::cerr<<"Failed to Parse Params\n";
        } else {
            SExpr s;

            SExpr h = SExpr("hflip",receivedParams.h_flip());
            SExpr v = SExpr("vflip",receivedParams.v_flip());
            SExpr ae = SExpr("autoexposure",receivedParams.auto_exposure());
            SExpr b = SExpr("brightness",receivedParams.brightness());
            SExpr c = SExpr("contrast",receivedParams.contrast());
            SExpr sat = SExpr("saturation",receivedParams.saturation());
            SExpr hue = SExpr("hue",receivedParams.hue());
            SExpr sharp = SExpr("sharpness",receivedParams.sharpness());
            SExpr gamma = SExpr("gamma",receivedParams.gamma());
            SExpr awb = SExpr("auto_whitebalance",receivedParams.autowhitebalance());
            SExpr expo = SExpr("exposure",receivedParams.exposure());
            SExpr gain = SExpr("gain",receivedParams.gain());
            SExpr wb = SExpr("white_balance",receivedParams.whitebalance());
            SExpr ftb = SExpr("fade_to_black",receivedParams.fadetoblack());

            s.append(h);
            s.append(v);
            s.append(ae);
            s.append(b);
            s.append(c);
            s.append(sat);
            s.append(hue);
            s.append(sharp);
            s.append(gamma);
            s.append(awb);
            s.append(expo);
            s.append(gain);
            s.append(wb);
            s.append(ftb);

            std::string stringToWrite = s.serialize();

            #ifdef V5_ROBOT
                std::cout<<"Saving as V5"<<std::endl;
                if(receivedParams.whichcamera() == "TOP"){
                    std::cout<<"TOP Params Received"<<std::endl;
                    std::ofstream file("/home/nao/nbites/Config/V5topCameraParams.txt");
                    std::cout<<stringToWrite<<std::endl;
                    file << stringToWrite;
                    file.close();
                    std::cout<<"Saving Done"<<std::endl;
                } else  {
                    std::cout<<"Bottom Params Received"<<std::endl;
                    std::ofstream file("/home/nao/nbites/Config/V5bottomCameraParams.txt");
                    std::cout<<stringToWrite<<std::endl;
                    file << stringToWrite;
                    file.close();
                    std::cout<<"Saving Done"<<std::endl;
                }
            #else
                std::cout<<"Saving as V4"<<std::endl;
                if(receivedParams.whichcamera() == "TOP"){
                    std::cout<<"TOP Params Received"<<std::endl;
                    std::ofstream file("/home/nao/nbites/Config/V4topCameraParams.txt");
                    file << stringToWrite;
                    file.close();
                    std::cout<<"Saving Done"<<std::endl;
                } else  {
                    std::cout<<"Bottom Params Received"<<std::endl;
                    std::ofstream file("/home/nao/nbites/Config/V4bottomCameraParams.txt");
                    file << stringToWrite;
                    file.close();
                    std::cout<<"Saving Done"<<std::endl;
                }
            #endif
        }
        return 0;
    }
Esempio n. 29
0
  SExpr* SPrimScope::genPrimFailure(PrimNode* call, PReg* errorReg,
                                    Node*& test, MergeNode*& merge,
                                    PReg* resultReg, bool failure) {
    // generate primitive failure code
    // two modes:
    //    if call == NULL, omit the test for failure because it's already
    //          been generated (inlined prim.); in this case, errorReg
    //          must be set
    //    if call != NULL, generate test code (setting test & merge node args)
    // returns the result of the failure branch

    // pop prim args (they're not on the expr stack anymore in the fail branch)
    while (npop-- > 0) exprStack()->pop();
    
    SCodeScope* s = sender();
    NodeGen* ng = theNodeGen;
    if (call) {
      fint b = bci();
      SAPReg* t = new SAPReg(s, b, b);
      // extract tag field and test for mark tag
      ng->append(new ArithRCNode(AndArithOp, call->dest(), Tag_Mask, t));
      ng->append(new ArithRCNode(SubCCArithOp, t, Tag_Mask, ng->noPR));
      test = ng->append(new BranchNode(NEBranchOp));
      // failure branch; load error string
      if (!errorReg) errorReg = new SAPReg(s, b, b);
      ng->current = 
        test->append(new ArithRCNode(SubArithOp, call->dest(),
                                     Mark_Tag-Mem_Tag, errorReg));
    }

    SExpr* failReceiver = hasFailBlock ? failBlock : receiver;
    SendInfo* info = new SendInfo(failReceiver, NormalLookupType, false, false,
                                  (stringOop)failSelector, NULL);
    info->computeNSends(rscope, bci());
    info->primFailure = failure;
    info->restartPrim = call == NULL;   // restart inlined prims (unc. traps)
    s->exprStack->push(failReceiver);
    if (errorReg->isConstPReg()) {
      s->exprStack->push(new ConstantSExpr(((ConstPReg*)errorReg)->constant,
                                           errorReg, ng->current));
    } else {
      s->exprStack->push(new MapSExpr(Memory->stringObj->map()->enclosing_mapOop(),
                                      errorReg, ng->current));
    }
    ConstPReg* failSelReg = new_ConstPReg(s, selector());
    s->exprStack->push(new ConstantSExpr(selector(), failSelReg, NULL));
    SExpr* res = s->inlineSend(info);

    if (res->isNoResultSExpr()) {
      // never returns
      ng->current = merge; // set to NULL if no merge
    } 
    else {
      if (needZap) {
        assert(failBlock->preg()->isBlockPReg(), "should be a block");
        ng->zapBlock((BlockPReg*)failBlock->preg());
      }
      ng->move(res->preg(), resultReg);
      res = res->shallowCopy(resultReg, ng->current);
      // moved creation down from before if res->isNoResult... 
      //   to avoid creating unreachable merge -- dmu
      if (merge == NULL) merge = new MergeNode("genPrimFailure merge"); 
      ng->append(merge);
    }
    return res;
  }
Esempio n. 30
0
    WastConverter(const std::string& outDir, const boost::filesystem::path& path) : outDir_(outDir) {
        baseName_ = path.stem().string();

        SExpr fileExpr = SExprParser::parseFile(path.string());
        for (const SExpr& child : fileExpr.children()) {
            const std::string& firstValue = child[0].value();
            if (firstValue == "module") {
                setCurrentModule(child);
            } else if (firstValue == "assert_invalid") {
                std::ofstream outStream(generateOutFile("invalid"));
                outStream << child[1].toString();
                outStream.close();
            } else if (firstValue == "assert_return_nan") {
                SExpr functionCall = convertInvoke(child[1]);
                SExpr newTest = SExprParser::parseString("if (i32.eq (i32.and () " + functionCall.toString() + ") (nop) (unreachable)");
                mainFunction_.addChild(newTest);
            } else if (firstValue == "assert_return") {
                if (child.children().size() == 2) {
                    SExpr functionCall = convertInvoke(child[1]);

                    mainFunction_.addChild(functionCall);
                } else {
                    std::string compareType = child[2][0].value().substr(0, 3);

                    SExpr functionCall = convertInvoke(child[1]);

                    SExpr newTest = SExprParser::parseString("if (" + compareType + ".eq " + functionCall.toString() + " " + child[2].toString() +") (nop) (unreachable)");
                    mainFunction_.addChild(newTest);
                }
            } else if (firstValue == "assert_trap") {
                SExpr functionCall = convertInvoke(child[1]);

                SExpr mainFunctionWithTrap = mainFunction_;
                mainFunctionWithTrap.addChild(functionCall);

                SExpr result = currentModuleExpr_;
                result.addChild(mainFunctionWithTrap);

                std::ofstream outStream(generateOutFile("trap"));
                outStream << result.toString();
                outStream.close();
            } else if (firstValue == "invoke") {
                SExpr functionCall = convertInvoke(child[1]);

                mainFunction_.addChild(functionCall);
            } else {
                std::cerr << "Can't handle assert " << child.toString() << std::endl;
            }
        }
        SExpr positiveModule = currentModuleExpr_;
        positiveModule.addChild(mainFunction_);

        std::ofstream outStream(generatePositiveOutFile("positive"));
        outStream << positiveModule.toString();
        outStream.close();
    }