mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-22 11:11:43 +00:00
Initial implementation of 'instanceof'
Works like an assignability check for now / does not yet honor nullables.
This commit is contained in:
23
src/ast.ts
23
src/ast.ts
@ -45,6 +45,7 @@ export enum NodeKind {
|
||||
ELEMENTACCESS,
|
||||
FALSE,
|
||||
FUNCTION,
|
||||
INSTANCEOF,
|
||||
LITERAL,
|
||||
NEW,
|
||||
NULL,
|
||||
@ -346,6 +347,18 @@ export abstract class Node {
|
||||
return expr;
|
||||
}
|
||||
|
||||
static createInstanceOfExpression(
|
||||
expression: Expression,
|
||||
isType: CommonTypeNode,
|
||||
range: Range
|
||||
): InstanceOfExpression {
|
||||
var expr = new InstanceOfExpression();
|
||||
expr.range = range;
|
||||
expr.expression = expression; expression.parent = expr;
|
||||
expr.isType = isType; isType.parent = expr;
|
||||
return expr;
|
||||
}
|
||||
|
||||
static createIntegerLiteralExpression(
|
||||
value: I64,
|
||||
range: Range
|
||||
@ -1267,6 +1280,16 @@ export class FunctionExpression extends Expression {
|
||||
declaration: FunctionDeclaration;
|
||||
}
|
||||
|
||||
/** Represents an `instanceof` expression. */
|
||||
export class InstanceOfExpression extends Expression {
|
||||
kind = NodeKind.INSTANCEOF;
|
||||
|
||||
/** Expression being asserted. */
|
||||
expression: Expression;
|
||||
/** Type to test for. */
|
||||
isType: CommonTypeNode;
|
||||
}
|
||||
|
||||
/** Represents an integer literal expression. */
|
||||
export class IntegerLiteralExpression extends LiteralExpression {
|
||||
literalKind = LiteralKind.INTEGER;
|
||||
|
@ -94,6 +94,7 @@ import {
|
||||
ForStatement,
|
||||
IfStatement,
|
||||
ImportStatement,
|
||||
InstanceOfExpression,
|
||||
InterfaceDeclaration,
|
||||
NamespaceDeclaration,
|
||||
ReturnStatement,
|
||||
@ -2263,6 +2264,10 @@ export class Compiler extends DiagnosticEmitter {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case NodeKind.INSTANCEOF: {
|
||||
expr = this.compileInstanceOfExpression(<InstanceOfExpression>expression, contextualType);
|
||||
break;
|
||||
}
|
||||
case NodeKind.LITERAL: {
|
||||
expr = this.compileLiteralExpression(<LiteralExpression>expression, contextualType);
|
||||
break;
|
||||
@ -5873,6 +5878,18 @@ export class Compiler extends DiagnosticEmitter {
|
||||
return this.module.createUnreachable();
|
||||
}
|
||||
|
||||
compileInstanceOfExpression(
|
||||
expression: InstanceOfExpression,
|
||||
contextualType: Type
|
||||
): ExpressionRef {
|
||||
this.compileExpressionRetainType(expression.expression, this.options.usizeType, WrapMode.NONE);
|
||||
var type = this.currentType;
|
||||
var isType = this.program.resolveType(expression.isType);
|
||||
this.currentType = Type.bool;
|
||||
if (!isType) return this.module.createUnreachable();
|
||||
return this.module.createI32(type.isAssignableTo(isType, false) ? 1 : 0);
|
||||
}
|
||||
|
||||
compileLiteralExpression(
|
||||
expression: LiteralExpression,
|
||||
contextualType: Type,
|
||||
|
@ -52,6 +52,7 @@ import {
|
||||
ForStatement,
|
||||
IfStatement,
|
||||
ImportStatement,
|
||||
InstanceOfExpression,
|
||||
ReturnStatement,
|
||||
SwitchStatement,
|
||||
ThrowStatement,
|
||||
@ -160,6 +161,10 @@ export class ASTBuilder {
|
||||
this.visitFunctionExpression(<FunctionExpression>node);
|
||||
break;
|
||||
}
|
||||
case NodeKind.INSTANCEOF: {
|
||||
this.visitInstanceOfExpression(<InstanceOfExpression>node);
|
||||
break;
|
||||
}
|
||||
case NodeKind.LITERAL: {
|
||||
this.visitLiteralExpression(<LiteralExpression>node);
|
||||
break;
|
||||
@ -544,6 +549,12 @@ export class ASTBuilder {
|
||||
this.sb.push(node.value.toString(10));
|
||||
}
|
||||
|
||||
visitInstanceOfExpression(node: InstanceOfExpression): void {
|
||||
this.visitNode(node.expression);
|
||||
this.sb.push(" instanceof ");
|
||||
this.visitTypeNode(node.isType);
|
||||
}
|
||||
|
||||
visitIntegerLiteralExpression(node: IntegerLiteralExpression): void {
|
||||
this.sb.push(i64_to_string(node.value));
|
||||
}
|
||||
|
@ -3108,7 +3108,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
switch (token) {
|
||||
// AssertionExpression
|
||||
case Token.AS: {
|
||||
let toType = this.parseType(tn);
|
||||
let toType = this.parseType(tn); // reports
|
||||
if (!toType) return null;
|
||||
expr = Node.createAssertionExpression(
|
||||
AssertionKind.AS,
|
||||
@ -3118,9 +3118,20 @@ export class Parser extends DiagnosticEmitter {
|
||||
);
|
||||
break;
|
||||
}
|
||||
// InstanceOfExpression
|
||||
case Token.INSTANCEOF: {
|
||||
let isType = this.parseType(tn); // reports
|
||||
if (!isType) return null;
|
||||
expr = Node.createInstanceOfExpression(
|
||||
expr,
|
||||
isType,
|
||||
tn.range(startPos, tn.pos)
|
||||
);
|
||||
break;
|
||||
}
|
||||
// ElementAccessExpression
|
||||
case Token.OPENBRACKET: {
|
||||
next = this.parseExpression(tn);
|
||||
next = this.parseExpression(tn); // reports
|
||||
if (!next) return null;
|
||||
if (!tn.skip(Token.CLOSEBRACKET)) {
|
||||
this.error(
|
||||
|
Reference in New Issue
Block a user