Пример #1
0
const char *typeStr(Value v) {
    const char *s = "?";
    if (IS_NIL(v)) {
        s = "nil";
    } else if (IS_NUM(v)) {
        s = "number";
    } else if (IS_STRING(v)) {
        s = "string";
    } else if (IS_ARRAY(v)) {
        s = "array";
    } else if (IS_MAP(v)) {
        s = "map";
    } else if (IS_FUNC(v)) {
        s = "func";
    } else if (IS_CFUNC(v)) {
        s = "cfunc";
    } else if (IS_CF(v)) {
        s = "cf";
    } else if (IS_CP(v)) {
        s = "cp";
    } else if (IS_PROTO(v)) {
        s = "proto";
    } else if (IS_REG(v)) {
        s = "reg";
    }
    return s;
}
Пример #2
0
void mutate(char *ind, char *offspring)
{
	int ind_len = length(ind);
	int dep, seg_len, sub_len;
	char subtree[MAX_IND_LEN];
	int mutation_pnt = gen_rnd(INT, 1, length(ind) - 1).i;

	if (IS_FUNC(ind[mutation_pnt]))	// if the node selected to be mutated is a function
	{								// grow a random subtree from mutation-point such that the whole individual size remains within the range
		traverse(ind, FROM_ROOT, mutation_pnt, &dep);
		seg_len = traverse(ind, FROM_PNT, mutation_pnt, NULL);
		gen_ind(subtree, MAX_DEPTH - dep, MAX_IND_LEN - 4 - (ind_len - seg_len));
		sub_len = length(subtree);

		memcpy(offspring, ind, mutation_pnt);
		memcpy(offspring + mutation_pnt, subtree, sub_len);
		memcpy(offspring + mutation_pnt + sub_len, ind + mutation_pnt + seg_len, MAX_IND_LEN - (mutation_pnt + seg_len));
		memcpy(offspring, ind, MAX_IND_LEN);
	}
	else // if a terminal is selected as mutation point
	{
		ind[mutation_pnt] = gen_rnd(INT, X, CONST_END).i;	// choose another terminal as replacement
		memcpy(offspring, ind, MAX_IND_LEN);
	}
}
Пример #3
0
void
fh_debug(FILE *stream, js_val *val, int indent, bool newline)
{
  switch (val->type) {
    case T_BOOLEAN:
      fprintf(stream, "%s", !val->boolean.val ? "false" : "true");
      break;
    case T_NUMBER:
      debug_num(stream, val);
      break;
    case T_STRING:
      if (fh->opt_interactive)
        cfprintf(stream, ANSI_YELLOW, "'%s'", val->string.ptr);
      else
        fprintf(stream, "%s", val->string.ptr);
      break;
    case T_NULL:
      cfprintf(stream, ANSI_GRAY, "null");
      break;
    case T_UNDEF:
      cfprintf(stream, ANSI_GRAY, "undefined");
      break;
    case T_OBJECT:
      if (IS_ARR(val))
        debug_arr(stream, val, indent);
      else if (IS_FUNC(val))
        cfprintf(stream, ANSI_BLUE, "[Function]");
      else if (IS_DATE(val))
        fprintf(stream, "[Date %ld]", (long)val->object.primitive->number.val);
      else
        debug_obj(stream, val, indent, false);
      break;
  }
  if (newline) fprintf(stream, "\n");
}
Пример #4
0
// Debug an object with extra verbosity, displaying non-enumerable properties.
void
fh_debug_verbose(FILE *stream, js_val *val, int indent)
{
  switch (val->type) {
    case T_BOOLEAN:
      fprintf(stream, "Boolean: (%s)", !val->boolean.val ? "false" : "true");
      break;
    case T_NUMBER:
      debug_num(stream, val);
      break;
    case T_STRING:
      cfprintf(stream, ANSI_YELLOW, "String: '%s'", val->string.ptr);
      break;
    case T_NULL:
      cfprintf(stream, ANSI_GRAY, "null");
      break;
    case T_UNDEF:
      cfprintf(stream, ANSI_GRAY, "undefined");
      break;
    case T_OBJECT:
      if (IS_ARR(val))
        fprintf(stream, "Array: ");
      else if (IS_FUNC(val))
        cfprintf(stream, ANSI_BLUE, "Function: ");
      else
        fprintf(stream, "Object: ");
      break;
  }

  if (IS_OBJ(val))
    debug_obj(stream, val, indent, true);

  fprintf(stream, "\n");
}
Пример #5
0
void push(char *node, char *stack, int *sp, char *cur_dep, char *max_dep)
{
	if (IS_FUNC(*node))
	{
		(*cur_dep)++;
		stack[++*sp] = DEL;	// put delimiter in the beginning of the stack and between two instructions

		if (*max_dep < *cur_dep)
			*max_dep = *cur_dep;

		if (*node == SIN || *node == COS)
			stack[++*sp] = *node;
		else if (*node == IFLTE)
			for(int i=0; i<4; i++)
				stack[++*sp] = IFLTE;
		else
			for(int i=0; i<2; i++)
				stack[++*sp] = *node;
	}
	else
	{
		(*sp)--;
		while(stack[*sp] == DEL)
		{
			if (*sp == 0)
				break;
			*sp -= 2;
			(*cur_dep)--;
		}
	}
}
Пример #6
0
int functionp(int addr){
    int val;
    
    val = findsym(addr);
    if(val != -1)
        return(IS_FUNC(val));
    else
        return(0);
}
Пример #7
0
ImmT c_rt_lib0exec(ImmT ___nl__func, ImmT *___ref___arrI){
	if(!IS_HASH(___nl__func) && !IS_ARRHASH(___nl__func))
		nl_die_internal("function struct must by a hash", NAME(___nl__func));
	NlFunction *func = (NlFunction*)c_rt_lib0hash_get_value_dec(___nl__func, c_rt_lib0string_new("name"));
	if(!IS_FUNC(func))
		nl_die_internal("can call only function: %s", NAME(func));
	if(!IS_ARR(*___ref___arrI))
		nl_die_internal("expected array: %s", NAME(*___ref___arrI));
	NlArray *arr = priv_arr_to_change(___ref___arrI);
	ImmT (*f)(int n, ImmT *arg) = func->f;
	dec_ref((ImmT*)func);
	return (*f)(arr->size, arr->arr);
}
Пример #8
0
int lambdap(int addr){
        int symaddr;
    
        symaddr = findsym(symname(addr));
    if(symaddr == NIL)
        return(0);
    else {
        if((IS_FUNC(symaddr)) && (IS_LAMBDA(symaddr)))
                return(1);
        else
                return(0);
    }
}
Пример #9
0
int fsubrp(int addr){
        int symaddr;
    
        symaddr = findsym(symname(addr));
    if(symaddr == NIL)
        return(0);
    else {
        if((IS_FUNC(symaddr)) && (IS_FSUBR(symaddr)))
                return(1);
        else
                return(0);
    }
}
Пример #10
0
obj_t * apply(obj_t *args, obj_t *env) {

	assert(IS_LIST(args));

	if (IS_LIST(CAR(args)) && IS_FUNC(CAR(CAR(args)))) {

		return (FUNC(CAR(CAR(args))))(CDR(args), env);
	} else if (IS_LIST(CAR(args)) && IS_DEFUNC(CAR(CAR(args)))) {

		obj_t * func_args;
		obj_t * call_args;

		obj_t * body;
		obj_t * result;

		body = clone_obj(BODY(CAR(CAR(args))));
		func_args = ARGS(CAR(CAR(args)));
		call_args = CDR(args);

		/* ((<DEFUNC:[args=(X)][body=(TIMES X X)]>) 3) */

		while (IS_LIST(func_args) && IS_LIST(call_args)) {
			obj_t * func_arg = CAR(func_args);
			obj_t * call_arg = CAR(call_args);

			replace_obj(func_arg, call_arg, body);

			func_args = CDR(func_args);
			call_args = CDR(call_args);
		}

		if ((IS_LIST(func_args) && !IS_LIST(call_args)) ||
				(!IS_LIST(func_args) && IS_LIST(call_args))) {

			free_obj(body); /* clean up */

			fprintf(stdout, "Unexpected number of arguments\n");
			return alloc_fail();
		}

		result = eval(body, env);

		free_obj(body);

		return result;

	} else {

		return clone_obj(args);
	}
}
Пример #11
0
void markcell(int addr){
    if(USED_CELL(addr))
        return;
 
    MARK_CELL(addr); 
    if(car(addr) != 0)
        markcell(car(addr));

    if(cdr(addr) != 0)
        markcell(cdr(addr));
    
    if((GET_BIND(addr) != 0) && (IS_FUNC(addr)))
        markcell(GET_BIND(addr));
     
}
Пример #12
0
Object call_function(Object func) {
    Object ret;
    if (IS_FUNC(func)) {
        resolve_method_self(func);
        /* call native */
        if (GET_FUNCTION(func)->native != NULL) {
            return GET_FUNCTION(func)->native();
        } else {
            TmFrame* f = push_frame(func);
            /*
            if (GET_FUNCTION(func)->modifier == 0) {
                return tm_eval(f);
            }*/
            L_recall:
            if (setjmp(f->buf)==0) {
                return tm_eval(f);
            } else {
                f = tm->frame;
                /* handle exception in this frame */
                if (f->jmp != NULL) {
                    f->pc = f->jmp;
                    f->jmp = NULL;
                    goto L_recall;
                /* there is no handler, throw to last frame */
                } else {
                    push_exception(f);
                    tm->frame--;
                    longjmp(tm->frame->buf, 1);
                }
            }
        }
    } else if (IS_DICT(func)) {
        ret = class_new(func);
        Object *_fnc = dict_get_by_str(ret, "__init__");
        if (_fnc != NULL) {
            call_function(*_fnc);
        }
        return ret;
    }
    tm_raise("File %o, line=%d: call_function:invalid object %o", GET_FUNCTION_FILE(tm->frame->fnc), 
        tm->frame->lineno, func);
    return NONE_OBJECT;
}
Пример #13
0
int traverse(char * ind, bool type, int point, int *depth)
{
	char cur_dep = 0;
	char max_dep = 0;
	char node;
	char stack[MAX_IND_LEN*10];
	int sp = -1;
	int pntr;

	if (type == FROM_ROOT)
		pntr = 0;	//start from root down to the point
	else
		pntr = point; 	//start from the point until valid expression

	node = ind[pntr++];

	if (!IS_FUNC(node))
	{
		if (depth)
			*depth = 1;
		return 1;
	}
	else
	{
		while(1)
		{
			push(&node, stack, &sp, &cur_dep, &max_dep);
			if (type == FROM_ROOT && pntr == point)
			{
				*depth = cur_dep;
				return point;	//which is length if started from root
			}
			else if (sp == 0)
			{
				if (depth)
					*depth = max_dep;
				return pntr - point;
			}
			node = ind[pntr++];
		}
	}
	return -1;	//should never reach here, just to avoid warning
}
Пример #14
0
/*-----------------------------------------------------------------*/
int
allocVariables (symbol * symChain)
{
  symbol *sym;
  symbol *csym;
  int stack = 0;
  int saveLevel = 0;

  /* go thru the symbol chain   */
  for (sym = symChain; sym; sym = sym->next)
    {
      /* if this is a typedef then add it */
      /* to the typedef table             */
      if (IS_TYPEDEF (sym->etype))
        {
          /* check if the typedef already exists    */
          csym = findSym (TypedefTab, NULL, sym->name);
          if (csym && csym->level == sym->level)
            werror (E_DUPLICATE_TYPEDEF, sym->name);

          SPEC_EXTR (sym->etype) = 0;
          addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
          continue;             /* go to the next one */
        }
      /* make sure it already exists */
      csym = findSymWithLevel (SymbolTab, sym);
      if (!csym || (csym && csym->level != sym->level))
        csym = sym;

      /* check the declaration */
      checkDecl (csym, 0);

      /* if this is a function or a pointer to a */
      /* function then do args processing        */
      if (funcInChain (csym->type))
        {
          processFuncArgs (csym);
        }

      /* if this is an extern variable then change */
      /* the level to zero temporarily             */
      if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
        {
          saveLevel = csym->level;
          csym->level = 0;
        }

      /* if this is a literal then it is an enumerated */
      /* type so need not allocate it space for it     */
      if (IS_LITERAL (sym->etype))
        continue;

      /* generate the actual declaration */
      if (csym->level)
        {
          allocLocal (csym);
          if (csym->onStack)
            stack += getSize (csym->type);
        }
      else
        allocGlobal (csym);

      /* restore the level */
      if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
        csym->level = saveLevel;
    }

  return stack;
}
Пример #15
0
/*-----------------------------------------------------------------*/
void
allocLocal (symbol * sym)
{
  /* generate an unique name */
  SNPRINTF (sym->rname, sizeof(sym->rname),
            "%s%s_%s_%d_%d",
            port->fun_prefix,
            currFunc->name, sym->name, sym->level, sym->block);

  sym->islocal = 1;
  sym->localof = currFunc;

  /* if this is a static variable */
  if (IS_STATIC (sym->etype))
    {
      allocGlobal (sym);
      sym->allocreq = 1;
      return;
    }

  /* if volatile then */
  if (IS_VOLATILE (sym->etype))
    sym->allocreq = 1;

  /* this is automatic           */

  /* if it's to be placed on the stack */
  if (options.stackAuto || reentrant)
    {
      sym->onStack = 1;
      if (options.useXstack)
        {
          /* PENDING: stack direction for xstack */
          SPEC_OCLS (sym->etype) = xstack;
          SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
          xstackPtr += getSize (sym->type);
        }
      else
        {
          SPEC_OCLS (sym->etype) = istack;
          if (port->stack.direction > 0)
            {
              SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
              stackPtr += getSize (sym->type);
            }
          else
            {
              stackPtr -= getSize (sym->type);
              SPEC_STAK (sym->etype) = sym->stack = stackPtr;
            }
        }
      allocIntoSeg (sym);
      return;
    }

  /* else depending on the storage class specified */

  /* if this is a function then assign code space    */
  if (IS_FUNC (sym->type))
    {
      SPEC_OCLS (sym->etype) = code;
      return;
    }

  /* if this is a bit variable and no storage class */
  if (bit && IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
    {
      SPEC_SCLS (sym->type) = S_BIT;
      SPEC_OCLS (sym->type) = bit;
      allocIntoSeg (sym);
      return;
    }

  if ((SPEC_SCLS (sym->etype) == S_DATA) || (SPEC_SCLS (sym->etype) == S_REGISTER))
    {
      SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
      allocIntoSeg (sym);
      return;
    }

  if (allocDefault (sym))
    {
      return;
    }

  /* again note that we have put it into the overlay segment
     will remove and put into the 'data' segment if required after
     overlay  analysis has been done */
  if (options.model == MODEL_SMALL)
    {
      SPEC_OCLS (sym->etype) =
        (options.noOverlay ? port->mem.default_local_map : overlay);
    }
  else
    {
      SPEC_OCLS (sym->etype) = port->mem.default_local_map;
    }
  allocIntoSeg (sym);
}
Пример #16
0
/*-----------------------------------------------------------------*/
void
allocGlobal (symbol * sym)
{
  /* symbol name is internal name  */
  if (!sym->level)              /* local statics can come here */
    SNPRINTF (sym->rname, sizeof(sym->rname),
              "%s%s", port->fun_prefix, sym->name);

  /* add it to the operandKey reset */
  if (!isinSet (operKeyReset, sym))
    {
      addSet(&operKeyReset, sym);
    }

  /* if this is a literal e.g. enumerated type */
  /* put it in the data segment & do nothing   */
  if (IS_LITERAL (sym->etype))
    {
      SPEC_OCLS (sym->etype) = data;
      return;
    }

  /* if this is a function then assign code space    */
  if (IS_FUNC (sym->type))
    {
      SPEC_OCLS (sym->etype) = code;
      /* if this is an interrupt service routine
         then put it in the interrupt service array */
      if (FUNC_ISISR (sym->type) && !options.noiv &&
          (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
        {
          if (interrupts[FUNC_INTNO (sym->type)])
            werror (E_INT_DEFINED,
                    FUNC_INTNO (sym->type),
                    interrupts[FUNC_INTNO (sym->type)]->name);
          else
            interrupts[FUNC_INTNO (sym->type)] = sym;

          /* automagically extend the maximum interrupts */
          if (FUNC_INTNO (sym->type) >= maxInterrupts)
            maxInterrupts = FUNC_INTNO (sym->type) + 1;
        }
      /* if it is not compiler defined */
      if (!sym->cdef)
        allocIntoSeg (sym);

      return;
    }

  /* if this is a bit variable and no storage class */
  if (bit && IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
    {
      SPEC_OCLS (sym->type) = bit;
      allocIntoSeg (sym);
      return;
    }

  if (sym->level)
    /* register storage class ignored changed to FIXED */
    if (SPEC_SCLS (sym->etype) == S_REGISTER)
      SPEC_SCLS (sym->etype) = S_FIXED;

  /* if it is fixed, then allocate depending on the */
  /* current memory model, same for automatics      */
  if (SPEC_SCLS (sym->etype) == S_FIXED ||
      SPEC_SCLS (sym->etype) == S_AUTO)
    {
      if (port->mem.default_globl_map != xdata)
        {
          if (sym->ival && SPEC_ABSA (sym->etype))
            {
              /* absolute initialized global */
              SPEC_OCLS (sym->etype) = x_abs;
            }
          else if (sym->ival && sym->level == 0 && port->mem.initialized_name)
            {
              SPEC_OCLS (sym->etype) = initialized;
            }
          else
            {
              /* set the output class */
              SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
            }
          /* generate the symbol  */
          allocIntoSeg (sym);
          return;
        }
      else
        {
          SPEC_SCLS (sym->etype) = S_XDATA;
        }
    }

  allocDefault (sym);
  return;
}
Пример #17
0
/*-----------------------------------------------------------------*/
static S4O_RET
scan4op (lineNode **pl, const char *pReg, const char *untilOp,
         lineNode **plCond)
{
  char *p;
  int len;
  bool isConditionalJump;
  int rIdx;
  S4O_RET ret;
  bool findPushPop;

  findPushPop = untilOp && (strcmp (untilOp, "push") == 0 || strcmp (untilOp, "pop") == 0);

  /* pReg points to e.g. "ar0"..."ar7" */
  len = strlen (pReg);

  /* get index into pReg table */
  for (rIdx = 0; rIdx < mcs51_nRegs; ++rIdx)
    if (strcmp (regs8051[rIdx].name, pReg + 1) == 0)
      break;

  /* sanity check */
  if (rIdx >= mcs51_nRegs)
    {
      DEADMOVEERROR();
      return S4O_ABORT;
    }

  for (; *pl; *pl = (*pl)->next)
    {
      if (!(*pl)->line || (*pl)->isDebug || (*pl)->isComment)
        continue;

      /* don't optimize across inline assembler,
         e.g. isLabel doesn't work there */
      if ((*pl)->isInline)
        return S4O_ABORT;

      if ((*pl)->visited)
        return S4O_VISITED;
      (*pl)->visited = TRUE;

      /* found untilOp? */
      if (untilOp && strncmp ((*pl)->line, untilOp, strlen (untilOp)) == 0)
        {
          p = (*pl)->line + strlen (untilOp);
          if (*p == '\t' && strncmp (p + 1, pReg, len) == 0)
            return S4O_FOUNDOPCODE;
          else
            {
              /* found untilOp but without our pReg */
              return S4O_ABORT;
            }
        }

      /* found pReg? */
      p = strchr ((*pl)->line, '\t');
      if (p)
        {
          /* skip '\t' */
          p++;

          /* when looking for push or pop and we find a direct access of sp: abort */
          if (findPushPop && strstr (p, "sp"))
            return S4O_ABORT;

          /* course search */
          if (strstr (p, pReg + 1))
            {
              /* ok, let's have a closer look */

              /* does opcode read from pReg? */
              if (bitVectBitValue (port->peep.getRegsRead ((*pl)), rIdx))
                return S4O_RD_OP;
              /* does opcode write to pReg? */
              if (bitVectBitValue (port->peep.getRegsWritten ((*pl)), rIdx))
                return S4O_WR_OP;

              /* we can get here, if the register name is
                 part of a variable name: ignore it */
            }
        }

      /* found label? */
      if ((*pl)->isLabel)
        {
          const char *start;
          char label[SDCC_NAME_MAX + 1];
          int len;

          if (!isLabelDefinition ((*pl)->line, &start, &len, FALSE))
            return S4O_ABORT;
          memcpy (label, start, len);
          label[len] = '\0';
          /* register passing this label */
          if (!setLabelRefPassedLabel (label))
            {
              DEADMOVEERROR();
              return S4O_ABORT;
            }
          continue;
        }

      /* branch or terminate? */
      isConditionalJump = FALSE;
      switch ((*pl)->line[0])
        {
          case 'a':
            if (strncmp ("acall", (*pl)->line, 5) == 0)
              {
                /* for comments see 'lcall' */
                ret = termScanAtFunc (*pl, rIdx);
                if (ret != S4O_CONTINUE)
                  return ret;
                break;
              }
            if (strncmp ("ajmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          case 'c':
            if (strncmp ("cjne", (*pl)->line, 4) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'd':
            if (strncmp ("djnz", (*pl)->line, 4) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'j':
            if (strncmp ("jmp", (*pl)->line, 3) == 0)
              /* "jmp @a+dptr": no chance to trace execution */
              return S4O_ABORT;
            if (strncmp ("jc",  (*pl)->line, 2) == 0 ||
                strncmp ("jnc", (*pl)->line, 3) == 0 ||
                strncmp ("jz",  (*pl)->line, 2) == 0 ||
                strncmp ("jnz", (*pl)->line, 3) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            if (strncmp ("jbc", (*pl)->line, 3) == 0 ||
                strncmp ("jb",  (*pl)->line, 2) == 0 ||
                strncmp ("jnb", (*pl)->line, 3) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'l':
            if (strncmp ("lcall", (*pl)->line, 5) == 0)
              {
                const char *p = (*pl)->line+5;
                while (*p == ' ' || *p == '\t')
                  p++;
                while (isdigit (*p))
                  p++;
                if (isdigit(p[-1]) && *p == '$') /* at least one digit */
                  {
                    /* this is a temp label for a pcall */
                    *pl = findLabel (*pl);
                    if (!*pl)
                      return S4O_ABORT;
                    break;
                  }

                ret = termScanAtFunc (*pl, rIdx);
                /* If it's a 'normal' 'caller save' function call, all
                   registers have been saved until the 'lcall'. The
                   'life range' of all registers end at the lcall,
                   and we can terminate our search.
                 * If the function is 'banked', the registers r0, r1 and r2
                   are used to tell the trampoline the destination. After
                   that their 'life range' ends just like the other registers.
                 * If it's a 'callee save' function call, registers are saved
                   by the callee. We've got no information, if the register
                   might live beyond the lcall. Therefore we've to continue
                   the search.
                */
                if (ret != S4O_CONTINUE)
                  return ret;
                break;
              }
            if (strncmp ("ljmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          case 'p':
            if (strncmp ("pop", (*pl)->line, 3) == 0 ||
                strncmp ("push", (*pl)->line, 4) == 0)
              return S4O_PUSHPOP;
            break;
          case 'r':
            if (strncmp ("reti", (*pl)->line, 4) == 0)
              return S4O_TERM;

            if (strncmp ("ret", (*pl)->line, 3) == 0)
              {
                /* pcall uses 'ret' */
                if (isFunc (*pl))
                  {
                    /* for comments see 'lcall' */
                    ret = termScanAtFunc (*pl, rIdx);
                    if (ret != S4O_CONTINUE)
                      return ret;
                    break;
                  }

                /* it's a normal function return */
                if (!((*pl)->ic) || (IS_SYMOP (IC_LEFT ((*pl)->ic)) &&
                    IS_FUNC (OP_SYM_TYPE(IC_LEFT ((*pl)->ic))) &&
                    FUNC_CALLEESAVES (OP_SYM_TYPE(IC_LEFT ((*pl)->ic)))))
                  return S4O_ABORT;
                else
                  return S4O_TERM;
              }
            break;
          case 's':
            if (strncmp ("sjmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          default:
            break;
        } /* switch ((*pl)->line[0]) */

      if (isConditionalJump)
        {
          *plCond = findLabel (*pl);
          if (!*plCond)
            return S4O_ABORT;
          return S4O_CONDJMP;
        }
    } /* for (; *pl; *pl = (*pl)->next) */
  return S4O_ABORT;
}
Пример #18
0
/*
 * Actually emit the initial values in .asm format.
 */
static void
emitIvals(struct dbuf_s *oBuf, symbol *sym, initList *list, long lit, int size)
{
    int i;
    ast *node;
    operand *op;
    value *val = NULL;
    int inCodeSpace = 0;
    char *str = NULL;
    int in_code;

    assert (size <= sizeof(long));
    assert (!list || (list->type == INIT_NODE));
    node = list ? list->init.node : NULL;

    in_code = emitIvalLabel(oBuf, sym);
    if (!in_code)
        dbuf_printf (oBuf, "\tdb\t");

    if (!node) {
        // initialize as zero
        for (i = 0; i < size; i++) {
            if (in_code) {
                dbuf_printf (oBuf, "\tretlw 0x%02x\n", lit & 0xff);
            } else {
                dbuf_printf (oBuf, "%s0x%02x", (i == 0) ? "" : ", ", lit & 0xff);
            }
            lit >>= 8;
        } // for
        if (!in_code)
            dbuf_printf (oBuf, "\n");
        return;
    } // if

    op = NULL;
    if (constExprTree(node) && (val = constExprValue(node, 0))) {
        op = operandFromValue(val);
        DEBUGprintf ("%s: constExpr ", __FUNCTION__);
    } else if (IS_AST_VALUE(node)) {
        op = operandFromAst(node, 0);
    } else if (IS_AST_OP(node)) {
        str = parseIvalAst(node, &inCodeSpace);
        DEBUGprintf("%s: AST_OP: %s\n", __FUNCTION__, str);
        op = NULL;
    } else {
        assert ( !"Unhandled construct in intializer." );
    }

    if (op) {
        aopOp(op, NULL, 1);
        assert(AOP(op));
        //printOperand(op, of);
    }

    for (i = 0; i < size; i++) {
        char *text;

        /*
         * FIXME: This is hacky and needs some more thought.
         */
        if (op && IS_SYMOP(op) && IS_FUNC(OP_SYM_TYPE(op))) {
            /* This branch is introduced to fix #1427663. */
            PCOI(AOP(op)->aopu.pcop)->offset+=i;
            text = get_op(AOP(op)->aopu.pcop, NULL, 0);
            PCOI(AOP(op)->aopu.pcop)->offset-=i;
        } else {
            text = op ? aopGet(AOP(op), i, 0, 0)
                : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0);
        } // if
        if (in_code) {
            dbuf_printf (oBuf, "\tretlw %s\n", text);
        } else {
            dbuf_printf (oBuf, "%s%s", (i == 0) ? "" : ", ", text);
        }
    } // for
    if (!in_code)
        dbuf_printf (oBuf, "\n");
}
Пример #19
0
static char *
parseIvalAst (ast *node, int *inCodeSpace) {
#define LEN 4096
    char *buffer = NULL;
    char *left, *right;

    if (IS_AST_VALUE(node)) {
        value *val = AST_VALUE(node);
        symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
        if (inCodeSpace && val->type
                && (IS_FUNC(val->type) || IS_CODE(getSpec(val->type))))
        {
            *inCodeSpace = 1;
        }
        if (inCodeSpace && sym
                && (IS_FUNC(sym->type)
                    || IS_CODE(getSpec(sym->type))))
        {
            *inCodeSpace = 1;
        }

        DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
        if (IS_AST_LIT_VALUE(node)) {
            buffer = Safe_alloc(LEN);
            SNPRINTF(buffer, LEN, "0x%lx", AST_ULONG_VALUE (node));
        } else if (IS_AST_SYM_VALUE(node)) {
            assert ( AST_SYMBOL(node) );
            /*
            printf ("sym %s: ", AST_SYMBOL(node)->rname);
            printTypeChain(AST_SYMBOL(node)->type, stdout);
            printTypeChain(AST_SYMBOL(node)->etype, stdout);
            printf ("\n---sym %s: done\n", AST_SYMBOL(node)->rname);
            */
            buffer = Safe_strdup(AST_SYMBOL(node)->rname);
        } else {
            assert ( !"Invalid values type for initializers in AST." );
        }
    } else if (IS_AST_OP(node)) {
        DEBUGprintf ("%s: AST_OP\n", __FUNCTION__);
        switch (node->opval.op) {
        case CAST:
            assert (node->right);
            buffer = parseIvalAst(node->right, inCodeSpace);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
            break;
        case '&':
            assert ( node->left && !node->right );
            buffer = parseIvalAst(node->left, inCodeSpace);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
            break;
        case '+':
            assert (node->left && node->right );
            left = parseIvalAst(node->left, inCodeSpace);
            right = parseIvalAst(node->right, inCodeSpace);
            buffer = Safe_alloc(LEN);
            SNPRINTF(buffer, LEN, "(%s + %s)", left, right);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
            Safe_free(left);
            Safe_free(right);
            break;
        case '[':
            assert ( node->left && node->right );
            assert ( IS_AST_VALUE(node->left) && AST_VALUE(node->left)->sym );
            right = parseIvalAst(node->right, inCodeSpace);
            buffer = Safe_alloc(LEN);
            SNPRINTF(buffer, LEN, "(%s + %u * %s)",
                    AST_VALUE(node->left)->sym->rname, getSize(AST_VALUE(node->left)->type), right);
            Safe_free(right);
            DEBUGprintf ("%s: %s\n", __FUNCTION__, &buffer[0]);
            break;
        default:
            assert ( !"Unhandled operation in initializer." );
            break;
        }
    } else {
        assert ( !"Invalid construct in initializer." );
    }

    return (buffer);
}
Пример #20
0
/*-----------------------------------------------------------------*/
static void
pic14emitOverlay (struct dbuf_s * aBuf)
{
        set *ovrset;

        /*  if (!elementsInSet (ovrSetSets))*/

        /* the hack below, fixes translates for devices which
        * only have udata_shr memory */
        dbuf_printf (aBuf, "%s\t%s\n",
                (elementsInSet(ovrSetSets)?"":";"),
                port->mem.overlay_name);

        /* for each of the sets in the overlay segment do */
        for (ovrset = setFirstItem (ovrSetSets); ovrset;
        ovrset = setNextItem (ovrSetSets))
        {

                symbol *sym;

                if (elementsInSet (ovrset))
                {
                /* this dummy area is used to fool the assembler
                otherwise the assembler will append each of these
                declarations into one chunk and will not overlay
                        sad but true */

                        /* I don't think this applies to us. We are using gpasm.  CRF */

                        dbuf_printf (aBuf, ";\t.area _DUMMY\n");
                        /* output the area informtion */
                        dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name);   /* MOF */
                }

                for (sym = setFirstItem (ovrset); sym;
                sym = setNextItem (ovrset))
                {

                        /* if extern then do nothing */
                        if (IS_EXTERN (sym->etype))
                                continue;

                                /* if allocation required check is needed
                                then check if the symbol really requires
                        allocation only for local variables */
                        if (!IS_AGGREGATE (sym->type) &&
                                !(sym->_isparm && !IS_REGPARM (sym->etype))
                                && !sym->allocreq && sym->level)
                                continue;

                                /* if global variable & not static or extern
                        and addPublics allowed then add it to the public set */
                        if ((sym->_isparm && !IS_REGPARM (sym->etype))
                                && !IS_STATIC (sym->etype))
                                addSetHead (&publics, sym);

                                /* if extern then do nothing or is a function
                        then do nothing */
                        if (IS_FUNC (sym->type))
                                continue;

                        /* print extra debug info if required */
                        if (options.debug || sym->level == 0)
                        {
                                if (!sym->level)
                                {               /* global */
                                        if (IS_STATIC (sym->etype))
                                                dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */
                                        else
                                                dbuf_printf (aBuf, "G_");       /* scope is global */
                                }
                                else
                                        /* symbol is local */
                                        dbuf_printf (aBuf, "L%s_",
                                        (sym->localof ? sym->localof->name : "-null-"));
                                dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
                        }

                        /* if is has an absolute address then generate
                        an equate for this no need to allocate space */
                        if (SPEC_ABSA (sym->etype))
                        {

                                if (options.debug || sym->level == 0)
                                        dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));

                                dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
                                        sym->rname,
                                        SPEC_ADDR (sym->etype));
                        }
                        else
                        {
                                if (options.debug || sym->level == 0)
                                        dbuf_printf (aBuf, "==.\n");

                                /* allocate space */
                                dbuf_printf (aBuf, "%s:\n", sym->rname);
                                dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
                        }

                }
        }
}
Пример #21
0
/*
 * Emit a set of symbols.
 * type - 0: have symbol tell whether it is local, extern or global
 *        1: assume all symbols in set to be global
 *        2: assume all symbols in set to be extern
 */
static void
emitSymbolSet(set *s, int type)
{
    symbol *sym;
    initList *list;
    unsigned sectionNr = 0;

    for (sym = setFirstItem(s); sym; sym = setNextItem(s)) {
#if 0
        fprintf (stdout, ";    name %s, rname %s, level %d, block %d, key %d, local %d, ival %p, static %d, cdef %d, used %d\n",
                sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival, IS_STATIC(sym->etype), sym->cdef, sym->used);
#endif

        if (sym->etype && SPEC_ABSA(sym->etype)
                && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))
                && sym->ival)
        {
            // handle config words
            pic14_assignConfigWordValue(SPEC_ADDR(sym->etype),
                    (int)list2int(sym->ival));
            pic14_stringInSet(sym->rname, &emitted, 1);
            continue;
        }

        if (sym->isstrlit) {
            // special case: string literals
            emitInitVal(ivalBuf, sym, sym->type, NULL);
            continue;
        }

        if (type != 0 || sym->cdef
                || (!IS_STATIC(sym->etype)
                    && IS_GLOBAL(sym)))
        {
            // bail out for ___fsadd and friends
            if (sym->cdef && !sym->used) continue;

            /* export or import non-static globals */
            if (!pic14_stringInSet(sym->rname, &emitted, 0)) {

                if (type == 2 || IS_EXTERN(sym->etype) || sym->cdef)
                {
                    /* do not add to emitted set, it might occur again! */
                    //if (!sym->used) continue;
                    // declare symbol
                    emitIfNew (extBuf, &emitted, "\textern\t%s\n", sym->rname);
                } else {
                    // declare symbol
                    emitIfNew (gloBuf, &emitted, "\tglobal\t%s\n", sym->rname);
                    if (!sym->ival && !IS_FUNC(sym->type)) {
                        // also define symbol
                        if (IS_ABSOLUTE(sym->etype)) {
                            // absolute location?
                            //dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\t0x%04X\n", moduleName, sectionNr++, SPEC_ADDR(sym->etype));
                            // deferred to pic14_constructAbsMap
                        } else {
                            dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\n", moduleName, sectionNr++);
                            dbuf_printf (gloDefBuf, "%s\tres\t%d\n\n", sym->rname, getSize(sym->type));
                        }
                    } // if
                } // if
                pic14_stringInSet(sym->rname, &emitted, 1);
            } // if
        } // if
        list = sym->ival;
        //if (list) showInitList(list, 0);
        if (list) {
            resolveIvalSym( list, sym->type );
            emitInitVal(ivalBuf, sym, sym->type, sym->ival);
            dbuf_printf (ivalBuf, "\n");
        }
    } // for sym
}
Пример #22
0
char evaluate(char *ind, float *vals, int i)
{
	int p = 0;
	int q = -1;
	char tmp[MAX_IND_LEN] = {0};
	float vals_stack[3*MAX_DEPTH];	// careful!

	p = length(ind) - 1;
	char node;
	while(p != -1)
	{
		node = ind[p--];
		while(!IS_FUNC(node))
		{
			vals_stack[++q] = vals[node];		// put args into the stack
			node = ind[p--];
		}
		switch(node)
		{
			case ADD:
				vals_stack[q-1] = vals_stack[q] + vals_stack[q-1];
				q--;
				break;
			case SUB:
				vals_stack[q-1] = vals_stack[q] - vals_stack[q-1];
				q--;
				break;
			case MUL:
				vals_stack[q-1] = vals_stack[q] * vals_stack[q-1];
				q--;
				break;
			case DIV:
				if (vals_stack[q-1] < 0.001)
					vals_stack[q-1] = vals_stack[q];
				else
					vals_stack[q-1] = vals_stack[q] / vals_stack[q-1];
				q--;
				break;
			case IFLTE:
				if (vals_stack[q] <= vals_stack[q-1])
					vals_stack[q-3] = vals_stack[q-2];	// else vals_stack[q-3] = vals_stack[q-3];
				q -= 3;
				break;
			case COS:
				vals_stack[q] = cos(vals_stack[q]);
				break;
			case SIN:
				vals_stack[q] = sin(vals_stack[q]);
				break;
			default:
				break;
		}
	}
	if (q != 0)
	{
		printf("p or q error! p=%i , q=%i, len=%i \n", p, q, length(ind));
		exit(1);
	}
	if (vals_stack[0] > 0)
		return 1;
	else
		return 0;
}