rdate.cpp

来自「eC++编译器源码」· C++ 代码 · 共 119 行

CPP
119
字号
#include <SYSTEM.h>
#include <RType.h>
#include <RTuple.h>
#include <RInterpret.h>
#include <Errors.h>
#include <Date.h>
#include <SInOut.h>
#include <InOut.h>
#include <String.h>
#include <Calendar.h>
//This is a sample program that illustrates how to add new types to xdb
  const unsigned int TDATE=9;  /*type id; must be system-unique for every type; numbers>=20 are available*/
  const unsigned int DOW=150;     /*must be unique per type starting at 150; convert date to numeric day of week*/
  unsigned int intx;
  char format[20];

  unsigned int declarer(ADDRESS context, unsigned int requestedWidth) /*returns width in bytes*/
  { //the argument is the width requested in the "create" command
    return sizeof(Date)*2;   /*bytes per word*/
  };
  
  void invoke(unsigned int method, pStack ps)
  { //the arguments are a method index and a pointer to an evaluation stack 
    pOperand pl,pr;
    Date cl,cr;
    Date  *pc;
    unsigned int day,month,year,hour,min,sec,ms;
    int i;
    DEC(ps->top);               //decrement stack pointer
    pl = ADR(ps->s[ps->top-1]); //create pointers to top two operands
    pr = ADR(ps->s[ps->top]);
    if (pr->ot != TDATE) {      //check the type of the top operand
        SoftwareError("Rdate.invoke:type not supported");
    } else {
        pc = ADR(pr->t);        //coerce operand descriptor field to *Date
        cr = *pc;               //copy Date value to a local variable
    };
    if (method == ORD(cmp)) {   //if method is a comparison
      if (pl->ot != TDATE) {    //make sure that the left operand is a Date
        SoftwareError("Rdate.invoke:type not supported");
      } else {
        pc = ADR(pl->t);        //coerce right operand to Date and copy
        cl = *pc;
      };
      pl->ot = intx;            //set the result type on top-of-stack to integer
      i = Compare(cl,cr);       //perform compare -1 <; 0 ==; +1 >
      pl->l = LONG(i);          //set result value on the top-of-stack
    } else if (method == DOW) { //only method supported for Dates: day-of-week
      Out(day, month, year, hour, min, sec, ms, cr); //convert cr to components
      pr->ot = intx;                                 //set result type
      pr->l = LONG(DayOfWeek(year,month,day));       //get day-of-week
      INC(ps->top);                                  //inc top-of-stack index
    } else {
      SoftwareError("Rdate.invoke:method not supported");
    };
  };
  
  typedef char Achar[50];
  boolean inoutr(ADDRESS context, unsigned int method, pTuple p,
       unsigned int index, unsigned int width, WORD &v[])
  { //this method performs all input/output conversions as well as constants
    Date *pr, *pr1;
    unsigned int pos;
    Date c;
    pOperand po;
    Achar *val;
    pr = ADDRESS(p)+LONG(index);  //tuple+byte-offset is the field's address
    if (method == LOAD) {         //load binary value into an operand descriptor
      po = ADR(v);
      po->ot = TDATE;             //set operand type to Date
      pr1 = ADR(po->t);
      *pr1 = *pr;
      return true;                //indicate operand loaded successfully
    } else if (method == STORE) { //copy Date from stack operand to tuple
      po = ADR(v);
      if (po->ot != TDATE) {return false; };
      pr1 = ADR(po->t);
      *pr = *pr1;
      return true;
    } else if (method == CONVERT) {
      po = ADR(v);
      po->ot = TDATE;  //convert a string representing a Date to a binary value on the stack
      pr1 = ADR(po->t);
      return Read(*p, index, *pr1); 
    } else if ((method == WRITE) || (method == UPDATE)) {
      val = ADR(v);
      pos = 0;        //convert Date string to a binary value and store in a tuple
      return Read(*val, pos, *pr);
    } else if (method == READ) {
      val = ADR(v);             //convert a binary date to a string for output
      Write(*pr, *val, format); /* %2u:%2u:%2u.%3c*/
      return true;
    } else if (method == CHECK) {
      val = ADR(v);
      pos = 0;               //validate that a string represents a valid date
      return Read(*val, pos, c);
    } else if (method == OPERATOR) { //invoked by parser to validate method calls
      val = ADR(v);
      if (CompareCS(*val, "dow")==0) { //check if method name is supported
        *val = "op=150;narg=2;";  //return method index and number-of-arguments+1
        return true;              //argument type checking is performed at runtime
      };
    };
    return false;
  };
  
  char ss[10];
  unsigned int i;
void main(void)
{
  format = "%2u/%2u/%4u";  //the default output format for Dates; used in Read method above
  Register("date", "Rdate", TDATE, declarer, invoke, inoutr);
  //register the type name, module that implements the type; type code and three callback procedures
  ss[0] = '\0'; i = 0;
  i = 10/*24*/;           //specify the default field width
  Format(TDATE, WRITE, ss, i);
  intx = Id("int");       //retrieve the type id for integer results
};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?