void MinDistance(Ph_Object self, Ph_Member query, Ph_Member *test, int count) { int m,i, length; double *va, *vb, distance; struct MinData *data = (struct MinData *)self->data; PhGetField(query, data->field, va); length = TypeInt(TypeType( Ph_ObjField(query, data->field)->type, 0), 0); for(m=0;m < count;m++) { PhGetField(test[m], data->field, vb); distance = 0.0; for(i = 0; i < length; i++) { if(va[i] > vb[i]) distance += (va[i] - vb[i]); } Ph_MemDistance(test[m]) = distance; } }
/* Type * ParseIntRange(Type * type) { Var * min, * max; Bookmark bookmark; bookmark = SetBookmark(); ParseExpressionType(TypeType(NULL)); if (TOK && TOP != 0) { min = BufPop(); max = NULL; if (NextIs(TOKEN_DOTDOT)) { ExpectExpression(NULL); if (TOK) { max = BufPop(); type = TypeDerive(type); } } if (VarIsIntConst(min) && VarIsIntConst(max)) { type = TypeAllocRange(min, max); if (type->range.min > type->range.max) { SyntaxErrorBmk("range minimum bigger than maximum", bookmark); } } else { SyntaxErrorBmk("expected type constant expression", bookmark); } } return type; } */ Type * ParseType2(InstrOp mode) /* Purpose: Parse: <int> [".." <int>] | <var> | proc <VarList> Input: mode Type of variable for which we parse. */ { Var * var; Type * type = NULL, * variant_type = NULL; Var * min, * max; Bookmark bookmark; next: type = ParseType3(); if (!TOK) return NULL; if (type == NULL) { bookmark = SetBookmark(); ParseExpressionType(TypeType(NULL)); if (TOK && TOP != 0) { min = BufPop(); max = NULL; if (NextIs(TOKEN_DOTDOT)) { ExpectExpression(NULL); if (TOK) { max = BufPop(); } } type = NULL; if (max == NULL) { var = min; if (var->mode == INSTR_TYPE) { type = var->type; } else if (var->mode == INSTR_VAR && var->type->variant == TYPE_TYPE) { type = var->type_value; SetFlagOn(var->submode, SUBMODE_USED_AS_TYPE); } // This is directly type if (type != NULL) { // For integer type, constants may be defined if (type->variant == TYPE_INT) { // type = ParseIntRange(type); goto const_list; } goto done; } max = var; } if (VarIsIntConst(min) && VarIsIntConst(max)) { type = TypeAllocRange(min, max); if (type->range.min > type->range.max) { SyntaxErrorBmk("range minimum bigger than maximum", bookmark); } } else { SyntaxErrorBmk("expected type constant expression", bookmark); } } else if (TOK == TOKEN_STRING) { type = TypeAlloc(TYPE_VAR); type->typevar = VarNewStr(NAME); NextToken(); } } const_list: // Parse type specific constants // There can be list of constants specified in block. // First thing in the block must be an identifier, so we try to open the block with this in mind. // We try to parse constants only for integer types (in future, we may try other numberic or string types) if (type != NULL && type->variant == TYPE_INT && !type->is_enum) { if (TOK != TOKEN_OR) { type = ParseConstList(type); } } done: if (TOK) { if (variant_type != NULL) { variant_type->right = type; type = variant_type; } if (NextIs(TOKEN_OR)) { variant_type = TypeAlloc(TYPE_VARIANT); variant_type->left = type; goto next; } } return type; }
Type * ParseType3() { Type * type = NULL, * variant_type = NULL; Type * elmt, * t; Var * var; BigInt * st; //# "type" restrict_type if (NextIs(TOKEN_TYPE2)) { variant_type = ParseType2(INSTR_VAR); type = TypeType(variant_type); //# "enum" ["struct"] } else if (NextIs(TOKEN_ENUM)) { type = TypeAlloc(TYPE_INT); type->range.flexible = true; type->is_enum = true; if (NextIs(TOKEN_STRUCT)) { ParseEnumStruct(type); } else { type = ParseConstList(type); } //# "proc" args } else if (NextIs(TOKEN_PROC)) { type = TypeAlloc(TYPE_PROC); ParseArgList(SUBMODE_ARG_IN, type); if (TOK) { ProcTypeFinalize(type); } //# "macro" args } else if (NextIs(TOKEN_MACRO)) { type = TypeAlloc(TYPE_MACRO); ParseArgList(SUBMODE_ARG_IN, type); // Struct } else if (NextIs(TOKEN_STRUCT)) { type = TypeAlloc(TYPE_STRUCT); ParseArgList(SUBMODE_EMPTY, type); // String } else if (NextIs(TOKEN_STRING_TYPE)) { type = TypeAlloc(TYPE_STRING); // Array } else if (NextIs(TOKEN_ARRAY)) { type = TypeAlloc(TYPE_ARRAY); t = NULL; if (TOK == TOKEN_OPEN_P) { EnterBlockWithStop(TOKEN_EQUAL); while (TOK != TOKEN_ERROR && !NextIs(TOKEN_BLOCK_END)) { elmt = ParseIntType(); if (type->index == NULL) { type->index = elmt; } else if (t != NULL) { t->right = TypeTuple(t->right, elmt); t = t->right; } else { t = TypeTuple(type->index, elmt); type->index = t; } NextIs(TOKEN_COMMA); }; } // If no dimension has been defined, use flexible array. // This is possible only for constants now. if (TOK) { if (type->index == NULL) { elmt = TypeAlloc(TYPE_INT); elmt->range.flexible = true; elmt->range.min = 0; type->index = elmt; } } // Element STEP may be defined if (TOK) { if (NextIs(TOKEN_STEP)) { ExpectExpression(NULL); if (TOK) { var = STACK[0]; st = VarIntConst(var); if (st != NULL) { type->step = IntN(st); } else { SyntaxError("Expected integer constant"); } } } } if (TOK) { if (NextIs(TOKEN_OF)) { type->element = ParseSubtype(); } else { type->element = TypeByte(); } } if (TOK) { if (type->step == 0) { type->step = TypeSize(type->element); } } } else if (NextIs(TOKEN_ADR2)) { elmt = NULL; if (NextIs(TOKEN_OF)) { elmt = ParseSubtype(); } type = TypeAdrOf(elmt); } return type; }
Ph_Image ViewBar_Image(Ph_Object self, Ph_Member m) { PhImageFunc *func; Ph_Image image; struct ViewImageData *sdata = (struct ViewImageData *)self->super->data; struct ViewBarData *data = (struct ViewBarData *)self->data; int bar_width, vec_length, space, x, i, inc; double *vector, factor; if(sdata->field[0]) { /* call the superclass (image) to initialize the image */ func = (PhImageFunc*)PhObjFunc(self->super, "image"); assert(func); image = func(self->super, m); } if(!sdata->field[0] || !image) { /* call the super-superclass (view) to initialize the image */ func = (PhImageFunc*)PhObjFunc(self->super->super, "image"); assert(func); image = func(self->super->super, m); assert(image); /* clear to black */ memset(image->data[0], 0, image->width*image->height*image->channels); } if(Ph_ObjGet(m, data->vector_field, &vector) == PH_ERROR) { fprintf(stderr, "Error getting %s field for %s\n", data->vector_field, Ph_MemName(m)); Ph_ImageFree(image); return NULL; } vec_length = TypeInt(TypeType( Ph_ObjField(m, data->vector_field)->type, 0), 0); /* determine the bar_width and space */ x = 0; inc = 1; bar_width = image->width / vec_length; if(bar_width == 0) { bar_width = 1; space = 0; inc = (int)ceil((double)vec_length / image->width); } else { bar_width /= data->spacing + 1; if(bar_width == 0) { space = image->width / vec_length / 2; bar_width = space; if(bar_width == 0) { bar_width = 1; x = (image->width - vec_length) / 2; } } else space = bar_width * data->spacing; } factor = image->height / (data->maximum - data->minimum); for(i=0;i<vec_length;i+=inc,x+=bar_width+space) { int j, height; double sum = 0.0; /* average together inc elements */ for(j=0;j<inc;j++) sum += vector[i+j]; sum /= inc; height = (int)((sum - data->minimum) * factor + 0.5); if(height <= 0) continue; if(height > image->height) height = image->height; Ph_ImagePutBlock(image, image->height-height, x, height, bar_width, data->color[0], data->color[1], data->color[2]); } return image; }