From: Jerome St-Louis Date: Wed, 6 Aug 2014 22:57:14 +0000 (-0400) Subject: compiler/libec: Improvements to units operations X-Git-Tag: 0.44.10PR2~17 X-Git-Url: https://ecere.com/cgi-bin/gitweb.cgi?p=sdk;a=commitdiff_plain;h=f4957c9c082bc7ce880af428ddcd795770200fc9 compiler/libec: Improvements to units operations - Not giving ambiguity warning when comparing related units on both side of comparison operator - Not giving ambiguity warning on multiplication/division, giving base data type instead (powers / ratios) - WARNING: Radians a = Pi/2; Degrees b = a * 180 / Pi; // This will now understand as Degrees the ratio of 180*a by Pi!!! (Degrees conversions had to be fixed in units.ec) --- diff --git a/compiler/bootstrap/ecp/bootstrap/ecp.c b/compiler/bootstrap/ecp/bootstrap/ecp.c index b49ea26..7012b1c 100644 --- a/compiler/bootstrap/ecp/bootstrap/ecp.c +++ b/compiler/bootstrap/ecp/bootstrap/ecp.c @@ -1465,6 +1465,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/ast.c b/compiler/bootstrap/libec/bootstrap/ast.c index 71e8294..b4ceb23 100644 --- a/compiler/bootstrap/libec/bootstrap/ast.c +++ b/compiler/bootstrap/libec/bootstrap/ast.c @@ -1426,6 +1426,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/copy.c b/compiler/bootstrap/libec/bootstrap/copy.c index 0fd2dcf..18dede6 100644 --- a/compiler/bootstrap/libec/bootstrap/copy.c +++ b/compiler/bootstrap/libec/bootstrap/copy.c @@ -882,6 +882,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; @@ -1545,7 +1548,9 @@ result->loc = exp->loc; result->isConstant = exp->isConstant; result->byReference = exp->byReference; result->opDestType = exp->opDestType; +result->usedInComparison = exp->usedInComparison; result->needTemplateCast = exp->needTemplateCast; +result->parentOpDestType = exp->parentOpDestType; } return result; } diff --git a/compiler/bootstrap/libec/bootstrap/dbpass.c b/compiler/bootstrap/libec/bootstrap/dbpass.c index fe13ab9..5ef6aa8 100644 --- a/compiler/bootstrap/libec/bootstrap/dbpass.c +++ b/compiler/bootstrap/libec/bootstrap/dbpass.c @@ -909,6 +909,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/ecdefs.c b/compiler/bootstrap/libec/bootstrap/ecdefs.c index 9bde309..80d393b 100644 --- a/compiler/bootstrap/libec/bootstrap/ecdefs.c +++ b/compiler/bootstrap/libec/bootstrap/ecdefs.c @@ -2074,6 +2074,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; @@ -2101,6 +2104,8 @@ this->addedThis = 0; this->needCast = 0; this->thisPtr = 0; this->opDestType = 0; +this->parentOpDestType = 0; +this->usedInComparison = 0; this->needTemplateCast = 0; } @@ -2871,6 +2876,9 @@ __ecereNameSpace__ecere__com__eClass_AddDataMember(class, "addedThis", "bool", 4 __ecereNameSpace__ecere__com__eClass_AddDataMember(class, "needCast", "bool", 4, 4, 1); __ecereNameSpace__ecere__com__eClass_AddDataMember(class, "thisPtr", "bool", 4, 4, 1); __ecereNameSpace__ecere__com__eClass_AddDataMember(class, "opDestType", "bool", 4, 4, 1); +__ecereNameSpace__ecere__com__eClass_AddDataMember(class, "usedInComparison", "bool", 4, 4, 1); +__ecereNameSpace__ecere__com__eClass_AddDataMember(class, "ambiguousUnits", "bool", 4, 4, 1); +__ecereNameSpace__ecere__com__eClass_AddDataMember(class, "parentOpDestType", "bool", 4, 4, 1); __ecereNameSpace__ecere__com__eClass_AddDataMember(class, "needTemplateCast", "uint", 4, 4, 1); class = __ecereNameSpace__ecere__com__eSystem_RegisterClass(5, "Enumerator", 0, sizeof(struct Enumerator), 0, (void *)0, (void *)0, module, 1, 1); if(((struct __ecereNameSpace__ecere__com__Module *)(((char *)module + sizeof(struct __ecereNameSpace__ecere__com__Instance))))->application == ((struct __ecereNameSpace__ecere__com__Module *)(((char *)__thisModule + sizeof(struct __ecereNameSpace__ecere__com__Instance))))->application && class) diff --git a/compiler/bootstrap/libec/bootstrap/expression.c b/compiler/bootstrap/libec/bootstrap/expression.c index 8a564ea..50f571e 100644 --- a/compiler/bootstrap/libec/bootstrap/expression.c +++ b/compiler/bootstrap/libec/bootstrap/expression.c @@ -955,6 +955,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/firstPass.c b/compiler/bootstrap/libec/bootstrap/firstPass.c index 5347196..72f169c 100644 --- a/compiler/bootstrap/libec/bootstrap/firstPass.c +++ b/compiler/bootstrap/libec/bootstrap/firstPass.c @@ -747,6 +747,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/freeAst.c b/compiler/bootstrap/libec/bootstrap/freeAst.c index a1c375e..f3be115 100644 --- a/compiler/bootstrap/libec/bootstrap/freeAst.c +++ b/compiler/bootstrap/libec/bootstrap/freeAst.c @@ -1523,6 +1523,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/grammar.c b/compiler/bootstrap/libec/bootstrap/grammar.c index 7274800..c3487ae 100644 --- a/compiler/bootstrap/libec/bootstrap/grammar.c +++ b/compiler/bootstrap/libec/bootstrap/grammar.c @@ -899,6 +899,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/loadSymbols.c b/compiler/bootstrap/libec/bootstrap/loadSymbols.c index ad9e318..36654ba 100644 --- a/compiler/bootstrap/libec/bootstrap/loadSymbols.c +++ b/compiler/bootstrap/libec/bootstrap/loadSymbols.c @@ -477,6 +477,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/output.c b/compiler/bootstrap/libec/bootstrap/output.c index dc806f2..817e1f0 100644 --- a/compiler/bootstrap/libec/bootstrap/output.c +++ b/compiler/bootstrap/libec/bootstrap/output.c @@ -908,6 +908,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/pass0.c b/compiler/bootstrap/libec/bootstrap/pass0.c index 6f6d609..458870c 100644 --- a/compiler/bootstrap/libec/bootstrap/pass0.c +++ b/compiler/bootstrap/libec/bootstrap/pass0.c @@ -1100,6 +1100,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/pass1.c b/compiler/bootstrap/libec/bootstrap/pass1.c index e3420d9..3b1cfa4 100644 --- a/compiler/bootstrap/libec/bootstrap/pass1.c +++ b/compiler/bootstrap/libec/bootstrap/pass1.c @@ -994,6 +994,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/pass15.c b/compiler/bootstrap/libec/bootstrap/pass15.c index 3bc7da5..5ad2d97 100644 --- a/compiler/bootstrap/libec/bootstrap/pass15.c +++ b/compiler/bootstrap/libec/bootstrap/pass15.c @@ -1400,6 +1400,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; @@ -7935,6 +7938,15 @@ break; } } +unsigned int RelatedUnits(struct __ecereNameSpace__ecere__com__Class * c1, struct __ecereNameSpace__ecere__com__Class * c2) +{ +if(c1->base->type == 3) +c1 = c1->base; +if(c2->base->type == 3) +c2 = c2->base; +return c1 == c2; +} + extern char * __ecereNameSpace__ecere__com__PrintString(struct __ecereNameSpace__ecere__com__Class * class, const void * object, ...); extern struct __ecereNameSpace__ecere__com__Class * __ecereClass___ecereNameSpace__ecere__sys__TempFile; @@ -13194,6 +13206,12 @@ struct __ecereNameSpace__ecere__sys__OldList * list = exp->__anon1.list; struct Expression * prev = exp->prev; struct Expression * next = exp->next; +if(exp->expType && exp->expType->kind == 8 && (!e->expType || e->expType->kind != 8)) +{ +FreeType(e->expType); +e->expType = exp->expType; +e->expType->refCount++; +} ComputeExpression(e); FreeType(exp->expType); FreeType(exp->destType); @@ -16202,6 +16220,8 @@ unsigned int useDestType = 0, useSideType = 0; struct Location oldyylloc = yylloc; unsigned int useSideUnit = 0; struct __ecereNameSpace__ecere__com__Class * destClass = (exp->destType && exp->destType->kind == 8 && exp->destType->__anon1._class) ? exp->destType->__anon1._class->__anon1.registered : (((void *)0)); +unsigned int powerOp = 0, relationOp = 0; +struct __ecereNameSpace__ecere__com__Class * c1 = (((void *)0)), * c2 = (((void *)0)); struct Type * dummy = (dummy = __ecereNameSpace__ecere__com__eInstance_New(__ecereClass_Type), dummy->count = 1, dummy->refCount = 1, dummy); switch(exp->__anon1.op.op) @@ -16234,6 +16254,7 @@ case GE_OP: case NE_OP: boolResult = 1; useSideType = 1; +relationOp = 1; break; case '+': case '-': @@ -16253,6 +16274,8 @@ case '/': case '%': useSideType = 1; useDestType = 1; +if(exp->__anon1.op.op == '/') +powerOp = 1; break; case '&': case '*': @@ -16260,6 +16283,8 @@ if(exp->__anon1.op.exp1) { useSideType = 1; useDestType = 1; +if(exp->__anon1.op.op == '*') +powerOp = 1; } break; } @@ -16303,6 +16328,17 @@ if(exp->__anon1.op.exp1->destType) FreeType(exp->__anon1.op.exp1->destType); exp->__anon1.op.exp1->destType = dummy; dummy->refCount++; +if(powerOp) +exp->__anon1.op.exp1->opDestType = 1; +if(relationOp) +exp->__anon1.op.exp1->usedInComparison = 1; +} +if(exp->__anon1.op.op == '+' || exp->__anon1.op.op == '-') +{ +if(exp->opDestType) +exp->__anon1.op.exp1->parentOpDestType = 1; +if(exp->usedInComparison) +exp->__anon1.op.exp1->usedInComparison = 1; } if(exp->__anon1.op.exp1->destType && exp->__anon1.op.op != '=') exp->__anon1.op.exp1->destType->count++; @@ -16310,6 +16346,7 @@ ProcessExpressionType(exp->__anon1.op.exp1); if(exp->__anon1.op.exp1->destType && exp->__anon1.op.op != '=') exp->__anon1.op.exp1->destType->count--; exp->__anon1.op.exp1->opDestType = 0; +exp->__anon1.op.exp1->usedInComparison = 0; if(!exp->__anon1.op.exp2 && (exp->__anon1.op.op == INC_OP || exp->__anon1.op.op == DEC_OP) && exp->__anon1.op.exp1->expType && exp->__anon1.op.exp1->expType->kind == 8 && exp->__anon1.op.exp1->expType->__anon1._class && exp->__anon1.op.exp1->expType->__anon1._class->__anon1.registered && exp->__anon1.op.exp1->expType->__anon1._class->__anon1.registered->type == 3) { exp->__anon1.op.exp2 = MkExpConstant("1"); @@ -16408,6 +16445,10 @@ if(exp->__anon1.op.exp2->destType) FreeType(exp->__anon1.op.exp2->destType); exp->__anon1.op.exp2->destType = dummy; dummy->refCount++; +if(powerOp) +exp->__anon1.op.exp2->opDestType = 1; +if(relationOp) +exp->__anon1.op.exp2->usedInComparison = 1; } if(type1 && boolResult && useSideType && type1->kind == 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && (type1->__anon1._class->__anon1.registered->type == 2 || type1->__anon1._class->__anon1.registered->type == 4)) { @@ -16434,8 +16475,16 @@ e = (*e->__anon1.list).last; if(e->type == 11 && e->__anon1.cast.exp) e->__anon1.cast.exp->needCast = 1; } +if(exp->__anon1.op.op == '+' || exp->__anon1.op.op == '-') +{ +if(exp->opDestType) +exp->__anon1.op.exp2->parentOpDestType = 1; +if(exp->usedInComparison) +exp->__anon1.op.exp2->usedInComparison = 1; +} ProcessExpressionType(exp->__anon1.op.exp2); exp->__anon1.op.exp2->opDestType = 0; +exp->__anon1.op.exp2->usedInComparison = 0; if(exp->__anon1.op.exp2->destType && exp->__anon1.op.op != '=') exp->__anon1.op.exp2->destType->count--; if(!assign && (exp->__anon1.op.exp1 || exp->__anon1.op.op == '~')) @@ -16507,6 +16556,17 @@ if(type2) type2->refCount++; } } +c1 = type1 && type1->kind == 8 && type1->__anon1._class ? type1->__anon1._class->__anon1.registered : (((void *)0)); +c2 = type2 && type2->kind == 8 && type2->__anon1._class ? type2->__anon1._class->__anon1.registered : (((void *)0)); +if(relationOp && ((exp->__anon1.op.exp1 && exp->__anon1.op.exp1->ambiguousUnits && (!c2 || c2->type != 3)) || (exp->__anon1.op.exp2 && exp->__anon1.op.exp2->ambiguousUnits && (!c1 || c1->type != 3)))) +Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "ambiguous units in relation operation\n", (((void *)0)))); +if(!relationOp && ((exp->__anon1.op.exp1 && exp->__anon1.op.exp1->ambiguousUnits) || (exp->__anon1.op.exp2 && exp->__anon1.op.exp2->ambiguousUnits)) && (!powerOp || !c1 || c1->type != 3 || !c2 || c2->type != 3 || !RelatedUnits(c1, c2))) +{ +if(exp->opDestType || exp->usedInComparison) +exp->ambiguousUnits = 1; +else +Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "ambiguous units\n", (((void *)0)))); +} dummy->kind = 0; if(exp->__anon1.op.op == SIZEOF) { @@ -16535,6 +16595,10 @@ exp->expType->refCount++; } else if(!assign) { +if(c1 && !c1->dataType) +c1->dataType = ProcessTypeString(c1->dataTypeString, 0); +if(c2 && !c2->dataType) +c2->dataType = ProcessTypeString(c2->dataTypeString, 0); if(boolOps) { if(exp->__anon1.op.exp1) @@ -16566,19 +16630,36 @@ exp->__anon1.op.exp2->expType = MkClassType("bool"); exp->__anon1.op.exp2->expType->truth = 1; } } +else if(powerOp && exp->__anon1.op.exp1 && exp->__anon1.op.exp2 && ((c1 && c1->type == 3) || (c2 && c2->type == 3))) +{ +if(c1 && c1->type == 3 && c2 && c2->type == 3) +{ +if(c1->dataType->kind == 7) +exp->expType = c1->dataType; +else if(c2->dataType->kind == 7) +exp->expType = c2->dataType; +else if(c1->dataType->kind == 6) +exp->expType = c1->dataType; +else if(c2->dataType->kind == 6) +exp->expType = c2->dataType; +else +exp->expType = c1->dataType; +} +else if((c1 && c1->type == 3) || exp->__anon1.op.op == '/') +exp->expType = type1; +else +exp->expType = type2; +if(exp->expType) +exp->expType->refCount++; +} else if(exp->__anon1.op.exp1 && exp->__anon1.op.exp2 && ((useSideType) || ((!type1 || type1->kind != 8 || !strcmp(type1->__anon1._class->string, "String")) && (!type2 || type2->kind != 8 || !strcmp(type2->__anon1._class->string, "String"))))) { if(type1 && type2 && ((type1->kind == 8 && type1->__anon1._class && strcmp(type1->__anon1._class->string, "String")) == (type2->kind == 8 && type2->__anon1._class && strcmp(type2->__anon1._class->string, "String")))) { -if(exp->__anon1.op.op == '-' && ((type1->kind == 8 && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 4) || (type2->kind == 8 && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4))) +if(exp->__anon1.op.op == '-' && ((c1 && c1->type == 4) || (c2 && c2->type == 4))) { -struct Type * intType; +struct Type * intType = ProcessTypeString((c1 && c1->dataType->kind == 4) || (c2 && c2->dataType->kind == 4) ? "int64" : "int", 0); -if(!type1->__anon1._class->__anon1.registered->dataType) -type1->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type1->__anon1._class->__anon1.registered->dataTypeString, 0); -if(!type2->__anon1._class->__anon1.registered->dataType) -type2->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type2->__anon1._class->__anon1.registered->dataTypeString, 0); -intType = ProcessTypeString((type1->__anon1._class->__anon1.registered->dataType->kind == 4 || type2->__anon1._class->__anon1.registered->dataType->kind == 4) ? "int64" : "int", 0); if(exp->__anon1.op.exp1->destType) FreeType(exp->__anon1.op.exp1->destType); if(exp->__anon1.op.exp2->destType) @@ -16598,8 +16679,13 @@ FreeType(exp->__anon1.op.exp1->destType); exp->__anon1.op.exp1->destType = type2; type2->refCount++; } -if(!boolResult && type1->kind == 8 && (!exp->destType || exp->destType->kind != 8) && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3 && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3 && type1->__anon1._class->__anon1.registered != type2->__anon1._class->__anon1.registered) +if(!boolResult && !exp->opDestType && (!exp->destType || exp->destType->kind != 8) && c1 && c1->type == 3 && c2 && c2->type == 3 && c1 != c2) +{ +if(exp->usedInComparison || exp->parentOpDestType) +exp->ambiguousUnits = 1; +else Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "operating on %s and %s with an untyped result, assuming %s\n", (((void *)0))), type1->__anon1._class->string, type2->__anon1._class->string, type1->__anon1._class->string); +} if(type1->kind == 13 && type1->__anon1.type->kind == 20 && type2->kind != 13) { struct Expression * argExp = GetTemplateArgExp(type1->__anon1.type->__anon1.templateParameter, thisClass, 1); @@ -16619,6 +16705,7 @@ if(!exp->__anon1.op.exp2->expType) if(type2) FreeType(type2); type2 = exp->__anon1.op.exp2->expType = ProcessTypeString("int", 0); +c2 = (((void *)0)); type2->refCount++; } ProcessExpressionType(exp->__anon1.op.exp2); @@ -16748,7 +16835,7 @@ Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "incompatibl } } } -else if(!boolResult && (!useSideUnit) && type2 && type1 && type2->kind == 8 && type1->kind != 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3) +else if(!boolResult && !useSideUnit && c2 && c2->type == 3 && type1 && type1->kind != 8) { if(exp->__anon1.op.exp1->destType) FreeType(exp->__anon1.op.exp1->destType); @@ -16760,7 +16847,7 @@ exp->expType = type2; if(type2) type2->refCount++; } -else if(!boolResult && (!useSideUnit) && type1 && type2 && type1->kind == 8 && type2->kind != 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3) +else if(!boolResult && !useSideUnit && c1 && c1->type == 3 && type2 && type2->kind != 8) { if(exp->__anon1.op.exp2->destType) FreeType(exp->__anon1.op.exp2->destType); @@ -16776,40 +16863,38 @@ else if(type1) { unsigned int valid = 0; -if(!boolResult && useSideUnit && type1 && type1->kind == 8 && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3 && type2 && type2->kind != 8) +if(!boolResult && useSideUnit && c1 && c1->type == 3 && type2 && type2->kind != 8) { if(exp->__anon1.op.exp2->destType) FreeType(exp->__anon1.op.exp2->destType); -if(!type1->__anon1._class->__anon1.registered->dataType) -type1->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type1->__anon1._class->__anon1.registered->dataTypeString, 0); -exp->__anon1.op.exp2->destType = type1->__anon1._class->__anon1.registered->dataType; +exp->__anon1.op.exp2->destType = c1->dataType; exp->__anon1.op.exp2->destType->refCount++; CheckExpressionType(exp->__anon1.op.exp2, exp->__anon1.op.exp2->destType, 0, 0); if(type2) FreeType(type2); type2 = exp->__anon1.op.exp2->destType; +c2 = type2 && type2->kind == 8 && type2->__anon1._class ? type2->__anon1._class->__anon1.registered : (((void *)0)); if(type2) type2->refCount++; exp->expType = type2; type2->refCount++; } -if(!boolResult && useSideUnit && type2 && type2->kind == 8 && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3 && type1 && type1->kind != 8) +if(!boolResult && useSideUnit && c2 && c2->type == 3 && type1 && type1->kind != 8) { if(exp->__anon1.op.exp1->destType) FreeType(exp->__anon1.op.exp1->destType); -if(!type2->__anon1._class->__anon1.registered->dataType) -type2->__anon1._class->__anon1.registered->dataType = ProcessTypeString(type2->__anon1._class->__anon1.registered->dataTypeString, 0); -exp->__anon1.op.exp1->destType = type2->__anon1._class->__anon1.registered->dataType; +exp->__anon1.op.exp1->destType = c2->dataType; exp->__anon1.op.exp1->destType->refCount++; CheckExpressionType(exp->__anon1.op.exp1, exp->__anon1.op.exp1->destType, 0, 0); type1 = exp->__anon1.op.exp1->destType; +c1 = type1 && type1->kind == 8 && type1->__anon1._class ? type1->__anon1._class->__anon1.registered : (((void *)0)); exp->expType = type1; type1->refCount++; } if(!boolResult || exp->__anon1.op.op == '>' || exp->__anon1.op.op == '<' || exp->__anon1.op.op == GE_OP || exp->__anon1.op.op == LE_OP) { -unsigned int op1IsEnum = type1 && type1->kind == 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 4; -unsigned int op2IsEnum = type2 && type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4; +unsigned int op1IsEnum = c1 && c1->type == 4; +unsigned int op2IsEnum = c2 && c2->type == 4; if(exp->__anon1.op.op == '*' || exp->__anon1.op.op == '/' || exp->__anon1.op.op == '-' || exp->__anon1.op.op == '|' || exp->__anon1.op.op == '^') { @@ -16868,7 +16953,7 @@ valid = 1; } if(!valid) { -if(type2 && type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3 && (type1->kind != 8 || !type1->__anon1._class || !type1->__anon1._class->__anon1.registered || type1->__anon1._class->__anon1.registered->type != 3)) +if(c2 && c2->type == 3 && (!c1 || c1->type != 3)) { if(exp->__anon1.op.exp1->destType) FreeType(exp->__anon1.op.exp1->destType); @@ -16918,13 +17003,13 @@ PrintType(exp->__anon1.op.exp1->expType, type1String, 0, 1); PrintType(exp->__anon1.op.exp2->expType, type2String, 0, 1); } Compiler_Warning(__ecereNameSpace__ecere__GetTranslatedString("ec", "incompatible expressions %s (%s) and %s (%s)\n", (((void *)0))), expString1, type1String, expString2, type2String); -if(type1->kind == 8 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 4) +if(c1 && c1->type == 4) { exp->expType = exp->__anon1.op.exp1->expType; if(exp->__anon1.op.exp1->expType) exp->__anon1.op.exp1->expType->refCount++; } -else if(type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4) +else if(c2 && c2->type == 4) { exp->expType = exp->__anon1.op.exp2->expType; if(exp->__anon1.op.exp2->expType) @@ -16936,7 +17021,7 @@ exp->__anon1.op.exp2->expType->refCount++; } else if(type2) { -if(type2->kind == 8 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 4) +if(c2 && c2->type == 4) { struct Type * oldType = exp->__anon1.op.exp1->expType; @@ -16962,7 +17047,7 @@ exp->__anon1.op.exp1->destType->refCount++; } else if(type2 && (!type1 || (type2->kind == 8 && type1->kind != 8))) { -if(type1 && type2->__anon1._class && type2->__anon1._class->__anon1.registered && type2->__anon1._class->__anon1.registered->type == 3) +if(type1 && c2 && c2->type == 3) { if(exp->__anon1.op.exp1->destType) FreeType(exp->__anon1.op.exp1->destType); @@ -16985,7 +17070,7 @@ type2->refCount++; } else if(type1 && (!type2 || (type1->kind == 8 && type2->kind != 8))) { -if(type2 && type1->__anon1._class && type1->__anon1._class->__anon1.registered && type1->__anon1._class->__anon1.registered->type == 3) +if(c2 && c2->type == 3) { if(exp->__anon1.op.exp2->destType) FreeType(exp->__anon1.op.exp2->destType); @@ -17058,6 +17143,8 @@ if(!e->next) { FreeType(e->destType); e->opDestType = exp->opDestType; +e->usedInComparison = exp->usedInComparison; +e->parentOpDestType = exp->parentOpDestType; e->destType = exp->destType; if(e->destType) { @@ -17065,6 +17152,8 @@ exp->destType->refCount++; } } ProcessExpressionType(e); +if(e->ambiguousUnits) +exp->ambiguousUnits = 1; if(!exp->expType && !e->next) { exp->expType = e->expType; @@ -19543,6 +19632,7 @@ __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ParseExpressionString", __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ReplaceExpContents", "void ReplaceExpContents(Expression checkedExp, Expression newExp)", ReplaceExpContents, module, 1); __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ApplyAnyObjectLogic", "void ApplyAnyObjectLogic(Expression e)", ApplyAnyObjectLogic, module, 1); __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ApplyLocation", "void ApplyLocation(Expression exp, Location loc)", ApplyLocation, module, 1); +__ecereNameSpace__ecere__com__eSystem_RegisterFunction("RelatedUnits", "bool RelatedUnits(ecere::com::Class c1, ecere::com::Class c2)", RelatedUnits, module, 1); __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ProcessExpressionType", "void ProcessExpressionType(Expression exp)", ProcessExpressionType, module, 1); __ecereNameSpace__ecere__com__eSystem_RegisterFunction("DeclareFunctionUtil", "void DeclareFunctionUtil(External neededBy, const String s)", DeclareFunctionUtil, module, 1); __ecereNameSpace__ecere__com__eSystem_RegisterFunction("ComputeDataTypes", "void ComputeDataTypes(void)", ComputeDataTypes, module, 1); diff --git a/compiler/bootstrap/libec/bootstrap/pass16.c b/compiler/bootstrap/libec/bootstrap/pass16.c index 6601c54..0fb0248 100644 --- a/compiler/bootstrap/libec/bootstrap/pass16.c +++ b/compiler/bootstrap/libec/bootstrap/pass16.c @@ -827,6 +827,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/pass2.c b/compiler/bootstrap/libec/bootstrap/pass2.c index fefd9b1..b8960f0 100644 --- a/compiler/bootstrap/libec/bootstrap/pass2.c +++ b/compiler/bootstrap/libec/bootstrap/pass2.c @@ -724,6 +724,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/pass3.c b/compiler/bootstrap/libec/bootstrap/pass3.c index 3d65dea..2fcd642 100644 --- a/compiler/bootstrap/libec/bootstrap/pass3.c +++ b/compiler/bootstrap/libec/bootstrap/pass3.c @@ -1545,6 +1545,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/bootstrap/libec/bootstrap/type.c b/compiler/bootstrap/libec/bootstrap/type.c index e05e624..f2c1f0c 100644 --- a/compiler/bootstrap/libec/bootstrap/type.c +++ b/compiler/bootstrap/libec/bootstrap/type.c @@ -1072,6 +1072,9 @@ unsigned int addedThis; unsigned int needCast; unsigned int thisPtr; unsigned int opDestType; +unsigned int usedInComparison; +unsigned int ambiguousUnits; +unsigned int parentOpDestType; unsigned int needTemplateCast; } ecere_gcc_struct; diff --git a/compiler/libec/src/copy.ec b/compiler/libec/src/copy.ec index aaf451f..9b27ac7 100644 --- a/compiler/libec/src/copy.ec +++ b/compiler/libec/src/copy.ec @@ -226,7 +226,9 @@ Expression MoveExpContents(Expression exp) result.isConstant = exp.isConstant; result.byReference = exp.byReference; result.opDestType = exp.opDestType; + result.usedInComparison = exp.usedInComparison; result.needTemplateCast = exp.needTemplateCast; + result.parentOpDestType = exp.parentOpDestType; } return result; diff --git a/compiler/libec/src/ecdefs.ec b/compiler/libec/src/ecdefs.ec index dfbfa59..7a3ea19 100644 --- a/compiler/libec/src/ecdefs.ec +++ b/compiler/libec/src/ecdefs.ec @@ -672,6 +672,9 @@ public: bool needCast; bool thisPtr; bool opDestType; + bool usedInComparison; + bool ambiguousUnits; + bool parentOpDestType; uint needTemplateCast; void Clear() @@ -692,6 +695,8 @@ public: needCast = false; thisPtr = false; opDestType = false; + parentOpDestType = false; + usedInComparison = false; needTemplateCast = 0; } }; diff --git a/compiler/libec/src/pass15.ec b/compiler/libec/src/pass15.ec index edb9e63..c19a875 100644 --- a/compiler/libec/src/pass15.ec +++ b/compiler/libec/src/pass15.ec @@ -5725,6 +5725,14 @@ void ComputeExpression(Expression exp) OldList * list = exp.list; Expression prev = exp.prev; Expression next = exp.next; + + // For operations which set the exp type on brackets exp after the inner exp was processed... + if(exp.expType && exp.expType.kind == classType && (!e.expType || e.expType.kind != classType)) + { + FreeType(e.expType); + e.expType = exp.expType; + e.expType.refCount++; + } ComputeExpression(e); //FreeExpContents(exp); FreeType(exp.expType); @@ -7768,6 +7776,13 @@ void ApplyLocation(Expression exp, Location loc) } } +bool RelatedUnits(Class c1, Class c2) +{ + if(c1.base.type == unitClass) c1 = c1.base; + if(c2.base.type == unitClass) c2 = c2.base; + return c1 == c2; +} + void ProcessExpressionType(Expression exp) { bool unresolved = false; @@ -8260,6 +8275,8 @@ void ProcessExpressionType(Expression exp) Location oldyylloc = yylloc; bool useSideUnit = false; Class destClass = (exp.destType && exp.destType.kind == classType && exp.destType._class) ? exp.destType._class.registered : null; + bool powerOp = false, relationOp = false; + Class c1 = null, c2 = null; // Dummy type to prevent ProcessExpression of operands to say unresolved identifiers yet Type dummy @@ -8306,6 +8323,7 @@ void ProcessExpressionType(Expression exp) // Gives boolean result boolResult = true; useSideType = true; + relationOp = true; break; case '+': case '-': @@ -8330,6 +8348,7 @@ void ProcessExpressionType(Expression exp) case '%': useSideType = true; useDestType = true; + if(exp.op.op == '/') powerOp = true; break; case '&': case '*': @@ -8338,6 +8357,7 @@ void ProcessExpressionType(Expression exp) // For & operator, useDestType nicely ensures the result will fit in a bool (TODO: Fix for generic enum) useSideType = true; useDestType = true; + if(exp.op.op == '*') powerOp = true; } break; @@ -8395,6 +8415,17 @@ void ProcessExpressionType(Expression exp) if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType); exp.op.exp1.destType = dummy; dummy.refCount++; + if(powerOp) + exp.op.exp1.opDestType = true; + if(relationOp) + exp.op.exp1.usedInComparison = true; + } + if(exp.op.op == '+' || exp.op.op == '-') + { + if(exp.opDestType) + exp.op.exp1.parentOpDestType = true; + if(exp.usedInComparison) + exp.op.exp1.usedInComparison = true; } // TESTING THIS HERE... @@ -8403,6 +8434,7 @@ void ProcessExpressionType(Expression exp) if(exp.op.exp1.destType && exp.op.op != '=') exp.op.exp1.destType.count--; exp.op.exp1.opDestType = false; + exp.op.exp1.usedInComparison = false; // Fix for unit and ++ / -- if(!exp.op.exp2 && (exp.op.op == INC_OP || exp.op.op == DEC_OP) && exp.op.exp1.expType && exp.op.exp1.expType.kind == classType && @@ -8506,6 +8538,10 @@ void ProcessExpressionType(Expression exp) if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType); exp.op.exp2.destType = dummy; dummy.refCount++; + if(powerOp) + exp.op.exp2.opDestType = true; + if(relationOp) + exp.op.exp2.usedInComparison = true; } // TESTING THIS HERE... (DANGEROUS) @@ -8534,8 +8570,16 @@ void ProcessExpressionType(Expression exp) if(e.type == castExp && e.cast.exp) e.cast.exp.needCast = true; } + if(exp.op.op == '+' || exp.op.op == '-') + { + if(exp.opDestType) + exp.op.exp2.parentOpDestType = true; + if(exp.usedInComparison) + exp.op.exp2.usedInComparison = true; + } ProcessExpressionType(exp.op.exp2); exp.op.exp2.opDestType = false; + exp.op.exp2.usedInComparison = false; if(exp.op.exp2.destType && exp.op.op != '=') exp.op.exp2.destType.count--; if(!assign && (exp.op.exp1 || exp.op.op == '~')) @@ -8609,6 +8653,24 @@ void ProcessExpressionType(Expression exp) if(type2) type2.refCount++; } } + c1 = type1 && type1.kind == classType && type1._class ? type1._class.registered : null; + c2 = type2 && type2.kind == classType && type2._class ? type2._class.registered : null; + + if(relationOp && + ( (exp.op.exp1 && exp.op.exp1.ambiguousUnits && (!c2 || c2.type != unitClass)) || + (exp.op.exp2 && exp.op.exp2.ambiguousUnits && (!c1 || c1.type != unitClass))) ) + Compiler_Warning($"ambiguous units in relation operation\n"); + + if(!relationOp && + ((exp.op.exp1 && exp.op.exp1.ambiguousUnits) || + (exp.op.exp2 && exp.op.exp2.ambiguousUnits)) && + (!powerOp || !c1 || c1.type != unitClass || !c2 || c2.type != unitClass || !RelatedUnits(c1, c2))) + { + if(exp.opDestType || exp.usedInComparison) + exp.ambiguousUnits = true; + else + Compiler_Warning($"ambiguous units\n"); + } dummy.kind = voidType; @@ -8640,6 +8702,11 @@ void ProcessExpressionType(Expression exp) } else if(!assign) { + if(c1 && !c1.dataType) + c1.dataType = ProcessTypeString(c1.dataTypeString, false); + if(c2 && !c2.dataType) + c2.dataType = ProcessTypeString(c2.dataTypeString, false); + if(boolOps) { if(exp.op.exp1) @@ -8669,11 +8736,33 @@ void ProcessExpressionType(Expression exp) exp.op.exp2.expType.truth = true; } } + else if(powerOp && exp.op.exp1 && exp.op.exp2 && ((c1 && c1.type == unitClass) || (c2 && c2.type == unitClass))) + { + // * or / with at least one unit operand + if(c1 && c1.type == unitClass && c2 && c2.type == unitClass) + { + // This is where we'd handle unit powers e.g. square meters or meters/seconds + // For now using base types + if(c1.dataType.kind == doubleType) exp.expType = c1.dataType; + else if(c2.dataType.kind == doubleType) exp.expType = c2.dataType; + else if(c1.dataType.kind == floatType) exp.expType = c1.dataType; + else if(c2.dataType.kind == floatType) exp.expType = c2.dataType; + else + exp.expType = c1.dataType; + } + else if((c1 && c1.type == unitClass) || exp.op.op == '/') // 1/units should not be typed with unit + exp.expType = type1; + else + exp.expType = type2; + + if(exp.expType) + exp.expType.refCount++; + } else if(exp.op.exp1 && exp.op.exp2 && ((useSideType /*&& (useSideUnit || - ((!type1 || type1.kind != classType || type1._class.registered.type != unitClass) && - (!type2 || type2.kind != classType || type2._class.registered.type != unitClass)))*/) || + ((!c1 || c1.type != unitClass) && + (!c2 || c2.type != unitClass)))*/) || ((!type1 || type1.kind != classType || !strcmp(type1._class.string, "String")) && (!type2 || type2.kind != classType || !strcmp(type2._class.string, "String"))))) { @@ -8682,18 +8771,9 @@ void ProcessExpressionType(Expression exp) ((type1.kind == classType && type1._class && strcmp(type1._class.string, "String")) == (type2.kind == classType && type2._class && strcmp(type2._class.string, "String")))) { // Added this check for enum subtraction to result in an int type: - if(exp.op.op == '-' && - ((type1.kind == classType && type1._class.registered && type1._class.registered.type == enumClass) || - (type2.kind == classType && type2._class.registered && type2._class.registered.type == enumClass)) ) + if(exp.op.op == '-' && ((c1 && c1.type == enumClass) || (c2 && c2.type == enumClass)) ) { - Type intType; - if(!type1._class.registered.dataType) - type1._class.registered.dataType = ProcessTypeString(type1._class.registered.dataTypeString, false); - if(!type2._class.registered.dataType) - type2._class.registered.dataType = ProcessTypeString(type2._class.registered.dataTypeString, false); - - intType = ProcessTypeString( - (type1._class.registered.dataType.kind == int64Type || type2._class.registered.dataType.kind == int64Type) ? "int64" : "int", false); + Type intType = ProcessTypeString((c1 && c1.dataType.kind == int64Type) || (c2 && c2.dataType.kind == int64Type) ? "int64" : "int", false); if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType); if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType); @@ -8712,12 +8792,17 @@ void ProcessExpressionType(Expression exp) } // Warning here for adding Radians + Degrees with no destination type - if(!boolResult && type1.kind == classType && (!exp.destType || exp.destType.kind != classType) && - type1._class.registered && type1._class.registered.type == unitClass && - type2._class.registered && type2._class.registered.type == unitClass && - type1._class.registered != type2._class.registered) - Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n", - type1._class.string, type2._class.string, type1._class.string); + if(!boolResult && !exp.opDestType && (!exp.destType || exp.destType.kind != classType) && + c1 && c1.type == unitClass && + c2 && c2.type == unitClass && + c1 != c2) + { + if(exp.usedInComparison || exp.parentOpDestType) + exp.ambiguousUnits = true; + else + Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n", + type1._class.string, type2._class.string, type1._class.string); + } if(type1.kind == pointerType && type1.type.kind == templateType && type2.kind != pointerType) { @@ -8742,7 +8827,7 @@ void ProcessExpressionType(Expression exp) { if(type2) FreeType(type2); - type2 = exp.op.exp2.expType = ProcessTypeString("int", false); + type2 = exp.op.exp2.expType = ProcessTypeString("int", false); c2 = null; type2.refCount++; } @@ -8875,7 +8960,7 @@ void ProcessExpressionType(Expression exp) } } // ADDED THESE TWO FROM OUTSIDE useSideType CHECK - else if(!boolResult && (!useSideUnit /*|| exp.destType*/) && type2 && type1 && type2.kind == classType && type1.kind != classType && type2._class && type2._class.registered && type2._class.registered.type == unitClass) + else if(!boolResult && !useSideUnit && c2 && c2.type == unitClass && type1 && type1.kind != classType) { if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType); // Convert e.g. / 4 into / 4.0 @@ -8886,7 +8971,7 @@ void ProcessExpressionType(Expression exp) exp.expType = type2; if(type2) type2.refCount++; } - else if(!boolResult && (!useSideUnit /*|| exp.destType*/) && type1 && type2 && type1.kind == classType && type2.kind != classType && type1._class && type1._class.registered && type1._class.registered.type == unitClass) + else if(!boolResult && !useSideUnit && c1 && c1.type == unitClass && type2 && type2.kind != classType) { if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType); // Convert e.g. / 4 into / 4.0 @@ -8901,36 +8986,34 @@ void ProcessExpressionType(Expression exp) { bool valid = false; - if(!boolResult && useSideUnit && type1 && type1.kind == classType && type1._class.registered && type1._class.registered.type == unitClass && type2 && type2.kind != classType) + if(!boolResult && useSideUnit && c1 && c1.type == unitClass && type2 && type2.kind != classType) { if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType); - if(!type1._class.registered.dataType) - type1._class.registered.dataType = ProcessTypeString(type1._class.registered.dataTypeString, false); - exp.op.exp2.destType = type1._class.registered.dataType; + exp.op.exp2.destType = c1.dataType; exp.op.exp2.destType.refCount++; CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false); if(type2) FreeType(type2); type2 = exp.op.exp2.destType; + c2 = type2 && type2.kind == classType && type2._class ? type2._class.registered : null; if(type2) type2.refCount++; exp.expType = type2; type2.refCount++; } - if(!boolResult && useSideUnit && type2 && type2.kind == classType && type2._class.registered && type2._class.registered.type == unitClass && type1 && type1.kind != classType) + if(!boolResult && useSideUnit && c2 && c2.type == unitClass && type1 && type1.kind != classType) { if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType); - if(!type2._class.registered.dataType) - type2._class.registered.dataType = ProcessTypeString(type2._class.registered.dataTypeString, false); - exp.op.exp1.destType = type2._class.registered.dataType; + exp.op.exp1.destType = c2.dataType; exp.op.exp1.destType.refCount++; CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false); type1 = exp.op.exp1.destType; + c1 = type1 && type1.kind == classType && type1._class ? type1._class.registered : null; exp.expType = type1; type1.refCount++; } @@ -8938,8 +9021,8 @@ void ProcessExpressionType(Expression exp) // TESTING THIS NEW CODE if(!boolResult || exp.op.op == '>' || exp.op.op == '<' || exp.op.op == GE_OP || exp.op.op == LE_OP) { - bool op1IsEnum = type1 && type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass; - bool op2IsEnum = type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass; + bool op1IsEnum = c1 && c1.type == enumClass; + bool op2IsEnum = c2 && c2.type == enumClass; if(exp.op.op == '*' || exp.op.op == '/' || exp.op.op == '-' || exp.op.op == '|' || exp.op.op == '^') { // Convert the enum to an int instead for these operators @@ -8992,8 +9075,7 @@ void ProcessExpressionType(Expression exp) if(!valid) { // Added this first part of the if here to handle 5 + Degrees { 5 } with either a base unit dest or not a unit dest type - if(type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == unitClass && - (type1.kind != classType || !type1._class || !type1._class.registered || type1._class.registered.type != unitClass)) + if(c2 && c2.type == unitClass && (!c1 || c1.type != unitClass)) { if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType); exp.op.exp1.destType = type2; @@ -9080,12 +9162,12 @@ void ProcessExpressionType(Expression exp) Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String); - if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass) + if(c1 && c1.type == enumClass) { exp.expType = exp.op.exp1.expType; if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++; } - else if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass) + else if(c2 && c2.type == enumClass) { exp.expType = exp.op.exp2.expType; if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++; @@ -9097,7 +9179,7 @@ void ProcessExpressionType(Expression exp) else if(type2) { // Maybe this was meant to be an enum... - if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass) + if(c2 && c2.type == enumClass) { Type oldType = exp.op.exp1.expType; exp.op.exp1.expType = null; @@ -9140,7 +9222,7 @@ void ProcessExpressionType(Expression exp) } else if(type2 && (!type1 || (type2.kind == classType && type1.kind != classType))) { - if(type1 && type2._class && type2._class.registered && type2._class.registered.type == unitClass) + if(type1 && c2 && c2.type == unitClass) { if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType); // Convert e.g. / 4 into / 4.0 @@ -9162,7 +9244,7 @@ void ProcessExpressionType(Expression exp) } else if(type1 && (!type2 || (type1.kind == classType && type2.kind != classType))) { - if(type2 && type1._class && type1._class.registered && type1._class.registered.type == unitClass) + if(c2 && c2.type == unitClass) { if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType); // Convert e.g. / 4 into / 4.0 @@ -9240,10 +9322,14 @@ void ProcessExpressionType(Expression exp) { FreeType(e.destType); e.opDestType = exp.opDestType; + e.usedInComparison = exp.usedInComparison; + e.parentOpDestType = exp.parentOpDestType; e.destType = exp.destType; if(e.destType) { exp.destType.refCount++; /*e.destType.count++; inced = true;*/ } } ProcessExpressionType(e); + if(e.ambiguousUnits) + exp.ambiguousUnits = true; /*if(inced) exp.destType.count--;*/ if(!exp.expType && !e.next) diff --git a/ecere/src/sys/units.ec b/ecere/src/sys/units.ec index ad01f5b..f9999ab 100644 --- a/ecere/src/sys/units.ec +++ b/ecere/src/sys/units.ec @@ -119,7 +119,7 @@ public class Degrees : Angle //get { return (Angle)this * Pi / 180; } //set { return (Angle)(value * 180 / Pi); } get { return this * (double)Pi / 180; } - set { return (double)value * 180 / Pi; } + set { return Angle { value * 180 / Pi }; } } }