某些脚本语言的算术运算

时间:2011-07-14 18:46:45

标签: c parsing scripting

我正在研究某种脚本语言。包含结构的值是

struct myvar
{
 char  name[NAMELEN];
 int   type;
 void* value;
}
type = 0  --> int* value
type = 1  --> char* value
type = 2  --> float* value

我遇到了算术运算的一些问题。似乎我需要在每个操作上提交各种类型的转换,这会转换为为每个操作编写一大堆代码,如:

case 0:  // "="
 if(factor1.name)
 {
    if((factor1.type == 1) && (factor2.type==1))
    {
        free(factor1.value);
        int len = (strlen((STRING)factor2.value)+1)*sizeof(char);
        factor1.value = malloc(len);
        memcpy(factor1.value,factor2.value,len);
    }
    else if((factor1.type == 2) && (factor2.type==2))
    *(FLOAT*)factor1.value = *(FLOAT*)factor2.value;
    else if((factor1.type == 0) && (factor2.type==0))
    *(INTEGER*)factor1.value = *(INTEGER*)factor2.value;
    else if((factor1.type == 0) && (factor2.type==2))
    *(INTEGER*)factor1.value = *(FLOAT*)factor2.value;
    else if((factor1.type == 2) && (factor2.type==0))
    *(FLOAT*)factor1.value = *(INTEGER*)factor2.value;
    else
     GetNextWord("error");
 }
 break;

有没有办法避免这种令人厌烦的程序?否则我别无选择,只能为“=”,“〜”,“+”,“ - ”,“*”,“/”,“%”,“>”中的每一个复制粘贴这段代码, “<”, “&GT =”, “< =”, “==”, “〜=”, “AND”, “OR”

3 个答案:

答案 0 :(得分:3)

使用union而不是struct作为值:

struct myvar {
  enum {
    STRING, INT, FLOAT,
  } type;

  union {
    char  strval[NAMELEN];
    int   intval;
    float fltval;
  } val;
};

然后用你的脚本语言执行赋值运算符:

factor1 = factor2;

根据您要执行的类型获取正确的值:

switch (operand.type) {
  case STRING:
    printf("%s", operand.val.strval);
    break;

  case INT:
    printf("%d", operand.val.intval);
    break;

  case FLOAT:
    printf("%f", operand.val.fltval);
    break;
}

答案 1 :(得分:2)

我建议如下:在应用操作时,首先应该强制操作数类型。例如,如果你的操作数类型是int和float,你应该将int值强制转换为float值,并继续执行float操作。对于所有操作,强制是相同的(或几乎相同的)。通过这种方法,您可以考虑更少的案例。

答案 2 :(得分:2)

如何编写3个toType函数:

char* toType0(myvar* from)
{
   if (from->type == 0) return (char*)(from->value);
   else if (from->type == 1) return itoa((int*)from->value);
   else...
}
int toType1(myvar* from)
{
   //convert to int...
}

然后在转换例程中,您可以执行以下操作:

 switch (factor1.type)
 {
    case 0:
     { char* other = toType0(&factor2);
     //assign or add or whatever....
     };
     break;
     case 1:
     { int other = toType1(&factor2);
     //assign or add or whatever....
     };
     break;
     ...
  }