示例#1
0
  void PatternCompiler::visit(VariablePattern& pattern, int value)
  {
    // Assign to the variable if it isn't a throwaway.
    if (*pattern.name() != "_")
    {
      compiler_.compileAssignment(pattern.pos(), pattern.resolved(), value,
                                  true);
    }

    // Compile the inner pattern.
    if (!pattern.pattern().isNull())
    {
      pattern.pattern()->accept(*this, value);
    }
  }
示例#2
0
 void Resolver::resolveParam(gc<Pattern> param)
 {
   VariablePattern* variable = param->asVariablePattern();
   if (variable != NULL)
   {
     // It's a variable, so resolve its inner pattern.
     if (!variable->pattern().isNull())
     {
       scope_->resolve(*variable->pattern());
     }
   }
   else
   {
     // Not a variable, so just resolve it normally.
     scope_->resolve(*param);
   }
 }
void PatternParser::parseVariablePattern(Pattern* pattern, vector<string>& tokenList)
{
    // Formats are:
    //     PatternName  VARIABLE
    //     PatternName  time1  factor1  time2  factor2  ...

    // ... check for enough tokens

    int nTokens = tokenList.size();
    if ( nTokens < 2 ) throw InputError(InputError::TOO_FEW_ITEMS, "");
    string* tokens = &tokenList[0];

    // ... cast pattern to VariablePattern

    VariablePattern* varPat = static_cast<VariablePattern*>(pattern);

    // ... return if second token is the pattern type keyword

    if ( Utilities::match(tokens[1], "VARIABLE") ) return;

    // ... read in pairs of times and pattern factors
    //     (times can be in decimal hours or hours:minutes format)

    string timeUnits("");
    int    seconds;
    double factor;
    int i = 1;
    while ( i < nTokens )
    {
        seconds = Utilities::getSeconds(tokens[i], timeUnits);
        if ( seconds < 0 )
        {
            throw InputError(InputError::INVALID_TIME, tokens[i] + " " + timeUnits);
        }
        i++;
        if ( i >= nTokens ) throw InputError(InputError::TOO_FEW_ITEMS, "");
        if ( !Utilities::parseNumber(tokens[i], factor) )
        {
            throw InputError(InputError::INVALID_NUMBER, tokens[i]);
        }
        varPat->addTime(seconds);
        varPat->addFactor(factor);
        i++;
    }
}
示例#4
0
 void Resolver::makeParamSlot(gc<Pattern> param)
 {
   VariablePattern* variable = param->asVariablePattern();
   if (variable != NULL && *variable->name() != "_")
   {
     // It's a variable, so create a named local for it and resolve the
     // variable.
     variable->setResolved(makeLocal(param->pos(), variable->name()));
     
     // Note that we do *not* resolve the variable's inner pattern here. We
     // do that after all param slots are resolved so that we can ensure the
     // param slots are contiguous.
   }
   else
   {
     // We don't have a variable for this parameter, but the argument
     // will still be on the stack, so make an unnamed slot for it.
     makeLocal(param->pos(), String::format("(%d)", unnamedSlotId_++));
   }
 }
示例#5
0
  void ExprCompiler::compileParamField(PatternCompiler& compiler,
                                         gc<Pattern> param, int slot)
  {
    VariablePattern* variable = param->asVariablePattern();
    if (variable != NULL)
    {
      // It's a variable, so compile its inner pattern. We don't worry about
      // the variable itself because the calling convention ensures its value
      // is already in the right slot.
      compiler.compile(variable->pattern(), slot);

      // If we closed over the parameter, then we don't want in a local slot,
      // we want it in the upvar, so create it and copy the value up.
      if (*variable->name() != "_" &&
          variable->resolved()->scope() == NAME_CLOSURE)
      {
        write(variable->pos(),
              OP_SET_UPVAR, variable->resolved()->index(), slot, 1);
      }
    }
    else
    {
      // Not a variable, so just compile it normally.
      compiler.compile(param, slot);
    }
  }
示例#6
0
  void Compiler::declareVariables(gc<Pattern> pattern, Module* module)
  {
    RecordPattern* record = pattern->asRecordPattern();
    if (record != NULL)
    {
      for (int i = 0; i < record->fields().count(); i++)
      {
        declareVariables(record->fields()[i].value, module);
      }

      return;
    }

    VariablePattern* variable = pattern->asVariablePattern();
    if (variable != NULL)
    {
      declareVariable(variable->pos(), variable->name(), module);

      if (!variable->pattern().isNull())
      {
        declareVariables(variable->pattern(), module);
      }
    }
  }
示例#7
0
 void Scope::visit(VariablePattern& pattern, int dummy)
 {
   if (*pattern.name() != "_")
   {
     if (isTopLevel())
     {
       // It's a top-level module variable. Since these are forward declared,
       // they should already exist. Just look up the existing one.
       int module = resolver_.compiler_.getModuleIndex(resolver_.module_);
       int index = resolver_.module_.findVariable(pattern.name());
       
       if (index == -1)
       {
         resolver_.compiler_.reporter().error(pattern.pos(),
             "Variable '%s' is not defined.", pattern.name()->cString());
         
         // Put a fake index in so we can continue and report more errors.
         index = 0;
       }
       
       pattern.setResolved(new ResolvedName(module, index));
     }
     else
     {
       // Declaring a local variable, so create a slot for it.
       gc<ResolvedName> resolved = resolver_.makeLocal(pattern.pos(),
                                                       pattern.name());
       pattern.setResolved(resolved);
     }
   }
   
   if (!pattern.pattern().isNull())
   {
     pattern.pattern()->accept(*this, dummy);
   }
 }