expression_t * expression_createv(u_char op, int numOperands, va_list operands) { int i; expression_operand_t *operand; expression_t *newexpr = expression_create_empty(op); if (numOperands < operations[op].minOperands || (operations[op].maxOperands && numOperands > operations[op].maxOperands)) { fprintf(stderr, "at_createExpression() : Invalid number of operands %d for operation %s\n", numOperands, operations[op].label); free(newexpr); return NULL; } if(!newexpr->operation->eval) { // invalid operation fprintf(stderr, "at_createExpression() : Uknown operation 0x%x\n", op); free(newexpr); return NULL; } /* be sure to create a NULL entry in the operations array (just for safety ... * if someone would ever try to evaluate an empty expression_t) */ newexpr->operands = calloc(1, sizeof(expression_operand_t *)); newexpr->operands[0] = NULL; for(i = 0; i < numOperands; i++) { if((operand = va_arg(operands, expression_operand_t *)) != NULL) { if(!operand_add(newexpr, operand)) { /* TODO - Error Messages */ if(newexpr->operands) free(newexpr->operands); free(newexpr); return NULL; } } } return newexpr; }
static object *insert_ltable(char *column, char *limit, line_item *v, int type) { short global = masm_level; char *s; object *o = NULL; paragraph *p, *q; line_item vnew; value *vlbase; int x, size; int base_displacement = 0; #ifdef STRUCTURE_DEPTH object *adhesionp = (active_x) ? active_instance[active_x - 1] : NULL; int adhesion_level = -1; int b4 = type; #endif if (type == UNDEFINED) global = 0; else { load_name(column, limit); if (label_highest_byte == 0) return NULL; #ifdef SYNONYMS if (*label_margin == '(') load_qualifier(label_margin, limit); #endif s = label_margin; while (*s++ == '*') global--; } #ifdef STRUCTURE_DEPTH if ((adhesionp) && (global == adhesionp->l.passflag) && (type) && (type ^ SET) && (type ^ BLANK)) { o = findlabel_in_node(); adhesion_level = adhesionp->l.r.l.xref; if (adhesion_level < 0) adhesion_level = 0; global = adhesion_level; if (uselector['B'-'A']) printf("[L%x:A%x:G%x:V%x:P%X]%s:%s\n", masm_level, adhesion_level, global, type, adhesionp->l.passflag, adhesionp->l.name, name); } else { if (global > 0) { o = retrieve_dynamic_label(); if (o) { if (o->l.r.l.xref ^ global) o = NULL; } } else { #ifdef HASH o = hash_locate(0); #else o = retrieve_label(); #endif } } #else if (global > 0) { o = retrieve_dynamic_label(); if (o) { if (o->l.r.l.xref ^ global) o = NULL; } } else { #ifdef HASH o = hash_locate(0); #else o = retrieve_label(); #endif } #endif if ((type == LOCATION) || (type == BLANK)) { if (x = actual->flags & 129) { vnew = *v; v = &vnew; if (x & 128) { if (type == LOCATION) type = EQUF; v->b[RADIX/8-5] = actual->rbase; base_displacement = 1; } if (x == 1) { vlbase = (value *) actual->runbank; operand_add(v, &vlbase->value); } } } if (o) { if (type == BLANK) return o; x = o->l.valued; if (x == BLANK) { o->l.valued = type; o->l.value = *v; return o; } /************************************* $blank does not alter any label which already exists *************************************/ #ifdef RECORD if (type == RECORD) { if ((branch_record == 0) && (record_nest == 0)) base_displacement = 1; type = EQUF; if (actual->flags & 128) { vnew = *v; v = &vnew; v->b[RADIX/8-5] = actual->rbase; } } #endif if (x) { if (type ^ x) { if ((pass) && ((type == LOCATION) || (base_displacement))) { if ((x == EQU) || (x == SET) || (x == EQUF)) return o; } flagp(o->l.name, "may not be retyped"); return o; } } if (type == FORM) return o; if (type == SET) { } else { if (background_pass) { if (type == LOCATION) checkwave(v, o, actual->flags); else if (base_displacement) checkwaveb(v, o); } else { #ifdef BINARY if (o->l.valued == UNDEFINED) o->l.valued = type; else #endif { flagp1p(o->l.name, "may not be restated"); return o; } } } } else { #ifdef EQUAZE if ((type == EQU) || (type == SET)) type = BLANK; #endif size = sizeof(label) + label_length - PARAGRAPH; if (global > 0) { flotsam -= size; if (flotsam < 0) { flag_either_pass("too many dynamic labels", "abandon"); exit(0); } o = floatop; floatop = (object *) ((char *) floatop + size); o->l.along = NULL; floatop->i = 0; } else { o = lr; if (remainder < size) o = buy_ltable(); remainder -= size; lr = (object *) ((char *) lr + size); } lr->i = 0; p = (paragraph *) o->l.name; q = (paragraph *) name; x = label_length >> 2; while (x--) *p++ = *q++; o->l.r.i = 0; o->l.r.l.xref = global; #ifdef HASH o->l.hashlink = NULL; #endif #ifdef BINARY o->l.link = NULL; #endif o->l.down = NULL; o->l.along = NULL; o->h.type = LABEL; o->h.length = size; o->l.passflag = 0; o->l.valued = type; if (type == SET) o->l.value = zero_o; if (global > 0) { } else { #ifdef STRUCTURE_DEPTH if ((active_x) && (global == adhesion_level) && (b4) && (b4 ^ SET) && (b4 ^ BLANK)) inslabel(o); else #endif { #ifdef HASH hash_in(o); #endif if ((list) || (o->l.valued == UNDEFINED)) { insert_label(o); } } } } if (type == SET) { } else o->l.value = *v; o->l.passflag = masm_level; if ((uselector['L'-'A']) && (masm_level)) { printf("[%x<-%x:%x:%s:%d:%s]\n", masm_level, global, type, file_label[depth]->l.name, ll[depth], o->l.name); } if ((type == LOCATION) || (type == BLANK)) { o->l.r.l.rel = counter_of_reference | 128; if (actual->relocatable) o->l.r.l.y |= 1; else o->l.r.l.y &= 254; } if (base_displacement) o->l.r.l.rel = counter_of_reference | 128; return o; }