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; }
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); } }
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"); }
// 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"); }
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)--; } } }
int functionp(int addr){ int val; val = findsym(addr); if(val != -1) return(IS_FUNC(val)); else return(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); }
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); } }
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); } }
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); } }
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)); }
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; }
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 }
/*-----------------------------------------------------------------*/ 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; }
/*-----------------------------------------------------------------*/ 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); }
/*-----------------------------------------------------------------*/ 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; }
/*-----------------------------------------------------------------*/ 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; }
/* * 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"); }
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); }
/*-----------------------------------------------------------------*/ 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); } } } }
/* * 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 }
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; }