Skip to content

Commit

Permalink
fix: improve null comarasion
Browse files Browse the repository at this point in the history
  • Loading branch information
HerrCai0907 committed Oct 7, 2023
1 parent e3e4166 commit 7457a31
Show file tree
Hide file tree
Showing 6 changed files with 909 additions and 23 deletions.
36 changes: 13 additions & 23 deletions src/compiler.ts
Expand Up @@ -111,7 +111,6 @@ import {

import {
Token,
operatorTokenToString
} from "./tokenizer";

import {
Expand Down Expand Up @@ -3946,7 +3945,10 @@ export class Compiler extends DiagnosticEmitter {

case Token.Equals_Equals_Equals:
case Token.Equals_Equals: {
leftExpr = this.compileExpression(left, contextualType);
commonType = this.resolver.resolveCompareExpressionCommonType(expression, this.currentFlow);
if (!commonType) return module.unreachable();

leftExpr = this.compileExpression(left, commonType);
leftType = this.currentType;

// check operator overload
Expand All @@ -3959,17 +3961,9 @@ export class Compiler extends DiagnosticEmitter {
}
}

rightExpr = this.compileExpression(right, leftType);
rightExpr = this.compileExpression(right, commonType);
rightType = this.currentType;
commonType = Type.commonType(leftType, rightType, contextualType);
if (!commonType) {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, operatorTokenToString(expression.operator), leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return module.unreachable();
}

if (commonType.isFloatValue) {
if (
isConstExpressionNaN(module, rightExpr) ||
Expand Down Expand Up @@ -3998,9 +3992,13 @@ export class Compiler extends DiagnosticEmitter {
}
case Token.Exclamation_Equals_Equals:
case Token.Exclamation_Equals: {
leftExpr = this.compileExpression(left, contextualType);
commonType = this.resolver.resolveCompareExpressionCommonType(expression, this.currentFlow);
if (!commonType) return module.unreachable();

leftExpr = this.compileExpression(left, commonType);
leftType = this.currentType;


// check operator overload
let classReference = leftType.getClass();
if (classReference) {
Expand All @@ -4011,17 +4009,9 @@ export class Compiler extends DiagnosticEmitter {
}
}

rightExpr = this.compileExpression(right, leftType);
rightExpr = this.compileExpression(right, commonType);
rightType = this.currentType;
commonType = Type.commonType(leftType, rightType, contextualType);
if (!commonType) {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, operatorTokenToString(expression.operator), leftType.toString(), rightType.toString()
);
this.currentType = contextualType;
return module.unreachable();
}

if (commonType.isFloatValue) {
if (
isConstExpressionNaN(module, rightExpr) ||
Expand Down
31 changes: 31 additions & 0 deletions src/resolver.ts
Expand Up @@ -1061,6 +1061,37 @@ export class Resolver extends DiagnosticEmitter {
return null;
}

resolveCompareExpressionCommonType(
/** The expression to resolve. */
expression: BinaryExpression,
/** Contextual flow. */
ctxFlow: Flow
): Type | null {
const left = expression.left;
const right = expression.right;

const leftType = this.resolveExpression(left, ctxFlow, Type.auto, ReportMode.Report);
if (!leftType) return null;
const rightType = this.resolveExpression(right, ctxFlow, Type.auto, ReportMode.Report);
if (!rightType) return null;

if (left.kind == NodeKind.Null && rightType.isReference) {
return rightType.asNullable();
}
if (right.kind == NodeKind.Null && leftType.isReference) {
return leftType.asNullable();
}

const commonType = Type.commonType(leftType, rightType, Type.auto);
if (!commonType) {
this.error(
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
expression.range, operatorTokenToString(expression.operator), leftType.toString(), rightType.toString()
);
}
return commonType;
}

/** resolving expressions */
private resolvingExpressions: Set<Expression> = new Set();

Expand Down

0 comments on commit 7457a31

Please sign in to comment.