예제 #1
0
 inline static auto &&write (_Stream &&os_, _Value const *val_) {
     static auto const count_ = [] (auto const *val_) {
         auto len_ = std::size_t {};
         while (val_ [len_] != _Value ()) ++len_;
         return len_;
     };
     return std::forward<_Stream> (os_) (
         val_, sizeof (_Value) * count_ (val_));
 }
예제 #2
0
ACExpression *ACDoc::_Expression1(sInt level)
{
  sInt op,pri;
  ACExpression *a,*b,*c;

  if(level==0)
    return _Value();

  a = _Expression1(level-1);
  for(;;)
  {
    op = BinaryOp(Scan.Token,pri);
    if(!op || pri!=level)
      break;
    Scan.Scan();
    b = _Expression1(level-1);
    if(op==ACE_COND1)
    {
      if(Scan.Token!=':')
        Scan.Error(L"':' missing in conditional operator");
      Scan.Scan();
      c = _Expression1(level-1);
      a = NewExpr(ACE_COND1,a,NewExpr(ACE_COND2,b,c));
    }
    else if(op==ACE_IMPLIES)
    {
      a = NewExpr(ACE_OR,NewExpr(ACE_NOT,a,0),b);
    }
    else
    {
      a = NewExpr(op,a,b);
    }
  }

  return a;
}
예제 #3
0
ACExpression *ACDoc::_Value()
{
  if(Scan.IfToken('+'))
    return NewExpr(ACE_POSITIVE,_Value(),0);
  if(Scan.IfToken('-'))
    return NewExpr(ACE_NEGATIVE,_Value(),0);
  if(Scan.IfToken('~'))
    return NewExpr(ACE_COMPLEMENT,_Value(),0);
  if(Scan.IfToken('!'))
    return NewExpr(ACE_NOT,_Value(),0);

  ACExpression *e = NewExpr(0,0,0);

  if(Scan.IfToken(AC_TOK_TRUE))
  {
    e->Op = ACE_TRUE;
  }
  else if(Scan.IfToken(AC_TOK_FALSE))
  {
    e->Op = ACE_FALSE;
  }
  else if(Scan.IfName(L"RENDER_DX9"))
  {
    e->Op = ACE_RENDER;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->ValueI = sRENDER_DX9;
    e->Literal->ValueF = e->Literal->ValueI;
  }
  else if(Scan.IfName(L"RENDER_DX11"))
  {
    e->Op = ACE_RENDER;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->ValueI = sRENDER_DX11;
    e->Literal->ValueF = e->Literal->ValueI;
  }
  else if(Scan.IfName(L"RENDER_OGL2"))
  {
    e->Op = ACE_RENDER;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->ValueI = sRENDER_OGL2;
    e->Literal->ValueF = e->Literal->ValueI;
  }
  else if(Scan.Token==sTOK_NAME)
  {
    sPoolString name;
    ACVar *var;
    ACType *type;
    ACPermuteMember *mem;

    Scan.ScanName(name);

    type = FindType(name);
    if(type)
    {
      e->Op = ACE_CONSTRUCT;
      e->CastType = type;
      _ParameterList(&e->Left);
    }
    else
    {
      var = FindFunc(name);
      if(!var)
        var = FindVar(name);
      if(var)
      {
        e->Op = ACE_VAR;
        e->Variable = var;
      }
      else
      {
        mem = 0;
        if(UsePermute)
          mem = sFind(UsePermute->Members,&ACPermuteMember::Name,name);
        if(mem)
        {
          e->Op = ACE_PERMUTE;
          e->Permute = mem;
        }
        else
        {
          Scan.Error(L"unkown symbol %q",name);
        }
      }
    }
  }
  else if(Scan.Token==sTOK_INT)
  {
    e->Op = ACE_LITERAL;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_INT;
    e->Literal->Value = Scan.ValueString;
    e->Literal->ValueI = Scan.ValI;
    e->Literal->ValueF = e->Literal->ValueI;
    Scan.Scan();
  }
  else if(Scan.Token==sTOK_FLOAT)
  {
    e->Op = ACE_LITERAL;
    e->Literal = Pool->Alloc<ACLiteral>();
    sClear(*e->Literal);
    e->Literal->Token = sTOK_FLOAT;
    e->Literal->Value = Scan.ValueString;
    e->Literal->ValueF = Scan.ValF;
    e->Literal->ValueI = e->Literal->ValueF;
    Scan.Scan();
  }
  else if(Scan.Token=='{')
  {
    e->Op = ACE_LITERAL;
    e->Literal = _Literal();
  }
  else if(Scan.Token=='(')
  {
    Scan.Match('(');
    ACType *ctype = 0;
    if(Scan.Token==sTOK_NAME)
      ctype = FindType(Scan.Name);

    if(ctype && Scan.DirtyPeek()==')')
    {
      Scan.Scan();
      Scan.Match(')');
      e->Op = ACE_CAST;
      e->CastType = ctype;
      e->Left = _Expression();
      return e;                         // this is handled like a prefix operator!
    }
    else
    {
      e = _Expression();
      Scan.Match(')');
    }
  }
  else
  {
    Scan.Error(L"value expected");
  }

postfix:
  if(Scan.IfToken('['))
  {
    e = NewExpr(ACE_INDEX,e,_Expression());
    Scan.Match(']');
    goto postfix;
  }
  if(Scan.IfToken('.'))
  {
    e = NewExpr(ACE_MEMBER,e,0);
    Scan.ScanName(e->Member);
    goto postfix;
  }
  if(Scan.IfToken(AC_TOK_INC))
  {
    e = NewExpr(ACE_POSTINC,e,0);
    goto postfix;
  }
  if(Scan.IfToken(AC_TOK_DEC))
  {
    e = NewExpr(ACE_POSTDEC,e,0);
    goto postfix;
  }
  if(Scan.Token=='(')
  {
    if((e->Op==ACE_VAR && e->Variable->Function))
    {
      e->Op = ACE_CALL;
      _ParameterList(&e->Left);
    }
    else if(e->Op==ACE_MEMBER && e->Member)
    {
      e->Right = NewExpr(ACE_CALL,0,0);
      _ParameterList(&e->Right->Left);
    }
    else
    {
      Scan.Error(L"you can only call() functions and members");
      ACExpression *dummy = NewExpr(ACE_CALL,0,0);
      _ParameterList(&dummy->Left);
    }
    goto postfix;
  }

  return e;
}