Пример #1
0
/* This routine will free any child nodes, and then free itself */
static void exprValListFreeData(exprVal * val)
{
	exprVal *next;

	while (val) {
		/* Remember the next */
		next = val->next;

		/* Free name */
		exprFreeMem(val->vname);

		/* Free ourself */
		exprFreeMem(val);

		val = next;
	}
}
Пример #2
0
/* This routine will free the value list */
int exprValListFree(exprValList * vlist)
{
	/* Make sure it exists, if not it is not error */
	if (vlist == NULL)
		return EXPR_ERROR_NOERROR;

	/* Free the nodes */
	exprValListFreeData(vlist->head);

	/* Freethe container */
	exprFreeMem(vlist);

	return EXPR_ERROR_NOERROR;
}
Пример #3
0
/* This routine will free the function list */
int exprFuncListFree(exprFuncList *f)
    {
    /* Make sure it exists, if not it is not error */
    if(f == NULL)
        return EXPR_ERROR_NOERROR;

    /* Free the nodes */
    if(f->head)
        {
        exprFuncListFreeData(f->head);

        /* Freethe container */
        exprFreeMem(f);
        }

    return EXPR_ERROR_NOERROR;
    }
Пример #4
0
/* This routine will create the function object */
exprFunc *exprCreateFunc(exprFuncType ptr, char *name, int min, int max, int refmin, int refmax)
    {
    exprFunc *tmp;
    char *vtmp;

    /* Make sure the name is valid */
    if(!exprValidIdent(name))
        return NULL;

    /* Create it */
    tmp = exprAllocMem(sizeof(exprFunc));
    if(tmp == NULL)
        return NULL;

    /* Allocate space for the name */
    vtmp = exprAllocMem(strlen(name) + 1);

    if(vtmp == NULL)
        {
        exprFreeMem(tmp);
        return NULL;
        }

    /* Set the memory to zero */
    memset(tmp, 0, sizeof(exprFunc));

    /* Copy the data over */
    strcpy(vtmp, name);
    tmp->fname = vtmp;
    tmp->fptr = ptr;
    tmp->min = min;
    tmp->max = max;
    tmp->refmin = refmin;
    tmp->refmax = refmax;

    return tmp;
    }
Пример #5
0
/* Function will parse a call to a function */
int exprInternalParseFunction(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int p1, int p2)
{
  int pos;
  int num, cur;
  int refnum, refcur;
  int plevel = 0;
  int lv, err;
  exprNode *tmp;
  exprFuncType fptr;
  int argmin, argmax;
  int refargmin, refargmax;
  int type;
  exprFuncList *l;
  exprValList *vars;
  EXPRTYPE *addr;
  EXPRTYPE **reftmp;

  /* We should have a function list */
  l = exprGetFuncList(obj);
  if(l == NULL)
    return EXPR_ERROR_NOSUCHFUNCTION;

  /* check paren. location */
  if(p2 <= p1)
    return EXPR_ERROR_SYNTAX;

  /* second paren. should not be after the end */
  if(p2 > end)
    return EXPR_ERROR_SYNTAX;

  /* Item before parenthesis should be an identifier */
  if(tokens[p1 - 1].type != EXPR_TOKEN_IDENTIFIER)
    {
      obj->starterr = tokens[p1 - 1].start;
      obj->enderr = tokens[p1].end;
      return EXPR_ERROR_SYNTAX;
    }


  /* Look up the function */
  err = exprFuncListGet(l, tokens[p1 - 1].data.str, &fptr, &type, &argmin, &argmax, &refargmin, &refargmax);
  if(err != EXPR_ERROR_NOERROR)
    {
      if(err == EXPR_ERROR_NOTFOUND)
        {
          obj->starterr = tokens[p1 - 1].start;
          obj->enderr = tokens[p1 - 1].end;
          return EXPR_ERROR_NOSUCHFUNCTION;
        }
      else
        return err;
    }

  /* Make sure the function exists */
  if(fptr == NULL && type == 0)
    {
      obj->starterr = tokens[p1 - 1].start;
      obj->enderr = tokens[p1 - 1].end;
      return EXPR_ERROR_NOSUCHFUNCTION;
    }

  /* Count arguments */
  if(p2 == p1 + 1)
    {
      num = 0;
      refnum = 0;
    }
  else
    {
      num = 1;
      refnum = 0;


      /* count commas */
      for(pos = p1 + 1; pos < p2; pos++)
        {
          switch(tokens[pos].type)
            {
              case EXPR_TOKEN_OPAREN:
                plevel++;
                break;

              case EXPR_TOKEN_CPAREN:
                plevel--;
                if(plevel < 0)
                  {
                    obj->starterr = tokens[pos].start;
                    obj->enderr = tokens[pos].end;
                    return EXPR_ERROR_UNMATCHEDPAREN;
                  }
                break;

              case EXPR_TOKEN_COMMA:
                /* Found comma */
                if(plevel == 0)
                  num++;
                break;

              case EXPR_TOKEN_AMPERSAND:
                /* Found reference mark */
                if(plevel == 0)
                  {
                    /* This may only occur after the open parenthesis or comma */
                    if(tokens[pos - 1].type == EXPR_TOKEN_OPAREN || tokens[pos - 1].type == EXPR_TOKEN_COMMA)
                      refnum++;
                    else
                      return EXPR_ERROR_SYNTAX;
                  }
                break;
            }
        }

      /* plevel should be zero */
      if(plevel != 0)
        return EXPR_ERROR_UNMATCHEDPAREN;
    }

  /* We now have the number of total arguments and
     number of ref arguments.  Get number of normal
     arguments */
  num = num - refnum;

  /* Make sure number of arguments is correct */
  /* Here we make sure the limits are greater
     or equal to zero because any negative number
     could be used to specify no limit */
  if(argmin >= 0 && num < argmin)
    {
      obj->starterr = tokens[p1 - 1].start;
      obj->enderr = tokens[p2].end;
      return EXPR_ERROR_BADNUMBERARGUMENTS;
    }

  if(argmax >= 0 && num > argmax)
    {
      obj->starterr = tokens[p1 - 1].start;
      obj->enderr = tokens[p2].end;
      return EXPR_ERROR_BADNUMBERARGUMENTS;
    }

  if(refargmin >= 0 && refnum < refargmin)
    {
      obj->starterr = tokens[p1 - 1].start;
      obj->enderr = tokens[p2].end;
      return EXPR_ERROR_BADNUMBERARGUMENTS;
    }

  if(refargmax >= 0 && refnum > refargmax)
    {
      obj->starterr = tokens[p1 - 1].start;
      obj->enderr = tokens[p2].end;
      return EXPR_ERROR_BADNUMBERARGUMENTS;
    }

  /* Set tmp to null in case of no arguments */
  tmp = NULL;
  reftmp = NULL;

  if(num > 0)
    {
      /* Allocate subnodes */
      tmp = exprAllocNodes(num);
      if(tmp == NULL)
        return EXPR_ERROR_MEMORY;
    }

  if(refnum > 0)
    {
      /* Allocate ref pointers */
      reftmp = exprAllocMem(sizeof(EXPRTYPE*) * refnum);
      if(reftmp == NULL)
        {
          exprFreeMem(tmp);
          return EXPR_ERROR_MEMORY;
        }
    }



  /* Set this node's data */
  node->type = EXPR_NODETYPE_FUNCTION;
  node->data.function.fptr = fptr;
  node->data.function.nodecount = num;
  node->data.function.nodes = tmp;
  node->data.function.refcount = refnum;
  node->data.function.refs = reftmp;
  node->data.function.type = type;

  /* parse each subnode */
  if(num + refnum > 0)
    {
      plevel = 0;
      cur = 0;
      refcur = 0;
      lv = p1 + 1;

      /* look for commas if more than 1 arg */
      if(num + refnum > 1)
        {
          for(pos = p1 + 1; pos < p2; pos++)
            {
              switch(tokens[pos].type)
                {
                  case EXPR_TOKEN_OPAREN:
                    plevel++;
                    break;

                  case EXPR_TOKEN_CPAREN:
                    plevel--;
                    break; /* Already checked paren nesting above */

                  case EXPR_TOKEN_COMMA:
                    /* Found comma */
                    if(plevel == 0)
                      {
                        /* parse inside */
                        if(tokens[lv].type == EXPR_TOKEN_AMPERSAND)
                          {
                            if(lv != pos - 2)
                              {
                                obj->starterr = tokens[lv].start;
                                obj->enderr = tokens[pos].end;
                                return EXPR_ERROR_SYNTAX;
                              }

                            /* It is a reference */
                            if(tokens[lv + 1].type != EXPR_TOKEN_IDENTIFIER)
                              {
                                obj->starterr = tokens[lv].start;
                                obj->enderr = tokens[lv + 1].end;
                                return EXPR_ERROR_SYNTAX;
                              }


                            /* Make sure it is not a constant */
                            vars = exprGetConstList(obj);
                            if(vars)
                              {
                                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
                                if(addr)
                                  {
                                    obj->starterr = tokens[lv].start;
                                    obj->enderr = tokens[lv + 1].start;
                                    return EXPR_ERROR_REFCONSTANT;
                                  }
                              }

                            /* Get variable list */
                            vars = exprGetVarList(obj);
                            if(vars == NULL)
                              return EXPR_ERROR_NOVARLIST;

                            /* Get variable address */
                            exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
                            if(addr == NULL)
                              {
                                /* Add variable to list */
                                exprValListAdd(vars, tokens[lv + 1].data.str, 0.0);

                                /* Try to get address again */
                                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
                                if(addr == NULL)
                                  return EXPR_ERROR_MEMORY; /* Could not add variable */
                              }

                            /* Set reference item */
                            reftmp[refcur] = addr;

                            /* increase ref arg number and lv position*/
                            refcur++;
                            lv = pos + 1;
                          }
                        else
                          {
                            err = exprInternalParse(obj, &(tmp[cur]), tokens, lv, pos - 1);
                            if(err != EXPR_ERROR_NOERROR)
                              return err;

                            /* increase arg number and lv position*/
                            lv = pos + 1;
                            cur++;
                          }
                      }
                    break;
                }
            }
        }

      /* lv should point after the last comma, or open paren. if only 1 arg */
      if(tokens[lv].type == EXPR_TOKEN_AMPERSAND)
        {
          if(lv != p2 - 2)
            {
              obj->starterr = tokens[lv].start;
              obj->enderr = tokens[p2].end;
              return EXPR_ERROR_SYNTAX;
            }

          /* It is a reference */
          if(tokens[lv + 1].type != EXPR_TOKEN_IDENTIFIER)
            {
              obj->starterr = tokens[lv].start;
              obj->enderr = tokens[lv + 1].end;
              return EXPR_ERROR_SYNTAX;
            }

          /* Make sure it is not a constant */
          vars = exprGetConstList(obj);
          if(vars)
            {
              exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
              if(addr)
                {
                  obj->starterr = tokens[lv].start;
                  obj->enderr = tokens[lv + 1].start;
                  return EXPR_ERROR_REFCONSTANT;
                }
            }

          /* Get variable list */
          vars = exprGetVarList(obj);
          if(vars == NULL)
            return EXPR_ERROR_NOVARLIST;

          /* Get variable address */
          exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
          if(addr == NULL)
            {
              /* Add variable to list */
              exprValListAdd(vars, tokens[lv + 1].data.str, 0.0);

              /* Try to get address again */
              exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
              if(addr == NULL)
                return EXPR_ERROR_MEMORY; /* Could not add variable */
            }

          /* Set reference item */
          reftmp[refcur] = addr;
        }
      else
        {
          err = exprInternalParse(obj, &(tmp[cur]), tokens, lv, p2 - 1);
          if(err != EXPR_ERROR_NOERROR)
            return err;
        }
    }


  return EXPR_ERROR_NOERROR;
}