Retain wrap state in parenthesized expressions; Void statements fwiw

This commit is contained in:
dcodeIO
2018-03-04 18:52:12 +01:00
parent 00c4f6fa52
commit d81ce5f907
10 changed files with 166 additions and 95 deletions

View File

@ -66,6 +66,7 @@ export enum NodeKind {
THROW,
TRY,
VARIABLE,
VOID,
WHILE,
// declaration statements
@ -897,6 +898,16 @@ export abstract class Node {
return elem;
}
static createVoidStatement(
expression: Expression,
range: Range
): VoidStatement {
var stmt = new VoidStatement();
stmt.range = range;
stmt.expression = expression;
return stmt;
}
static createWhileStatement(
condition: Expression,
statement: Statement,
@ -1668,6 +1679,14 @@ export class VariableStatement extends Statement {
declarations: VariableDeclaration[];
}
/** Represents a void statement dropping an expression's value. */
export class VoidStatement extends Statement {
kind = NodeKind.VOID;
/** Expression being dropped. */
expression: Expression;
}
/** Represents a `while` statement. */
export class WhileStatement extends Statement {
kind = NodeKind.WHILE;

View File

@ -79,6 +79,7 @@ import {
TryStatement,
VariableDeclaration,
VariableStatement,
VoidStatement,
WhileStatement,
Expression,
@ -1195,9 +1196,14 @@ export class Compiler extends DiagnosticEmitter {
expr = this.compileTryStatement(<TryStatement>statement);
break;
case NodeKind.VARIABLE:
var variableInit = this.compileVariableStatement(<VariableStatement>statement);
expr = variableInit ? variableInit : this.module.createNop();
case NodeKind.VARIABLE: {
let initializer = this.compileVariableStatement(<VariableStatement>statement);
expr = initializer ? initializer : this.module.createNop();
break;
}
case NodeKind.VOID:
expr = this.compileVoidStatement(<VoidStatement>statement);
break;
case NodeKind.WHILE:
@ -1646,6 +1652,10 @@ export class Compiler extends DiagnosticEmitter {
: 0;
}
compileVoidStatement(statement: VoidStatement): ExpressionRef {
return this.compileExpression(statement.expression, Type.void, ConversionKind.EXPLICIT, false);
}
compileWhileStatement(statement: WhileStatement): ExpressionRef {
// The condition does not yet initialize a branch
@ -1826,7 +1836,11 @@ export class Compiler extends DiagnosticEmitter {
break;
case NodeKind.PARENTHESIZED:
expr = this.compileParenthesizedExpression(<ParenthesizedExpression>expression, contextualType);
expr = this.compileParenthesizedExpression(
<ParenthesizedExpression>expression,
contextualType,
wrapSmallIntegers
);
break;
case NodeKind.PROPERTYACCESS:
@ -4507,9 +4521,18 @@ export class Compiler extends DiagnosticEmitter {
return this.module.createUnreachable();
}
compileParenthesizedExpression(expression: ParenthesizedExpression, contextualType: Type): ExpressionRef {
compileParenthesizedExpression(
expression: ParenthesizedExpression,
contextualType: Type,
wrapSmallIntegers: bool = true
): ExpressionRef {
// does not change types, just order
return this.compileExpression(expression.expression, contextualType, ConversionKind.NONE);
return this.compileExpression(
expression.expression,
contextualType,
ConversionKind.NONE,
wrapSmallIntegers
);
}
/**

View File

@ -75,6 +75,7 @@ import {
TypeParameter,
VariableStatement,
VariableDeclaration,
VoidStatement,
WhileStatement,
addModifier,
@ -1724,6 +1725,9 @@ export class Parser extends DiagnosticEmitter {
case Token.TYPE:
return this.parseTypeDeclaration(tn, null);
case Token.VOID:
return this.parseVoidStatement(tn);
case Token.WHILE:
return this.parseWhileStatement(tn);
@ -2196,6 +2200,20 @@ export class Parser extends DiagnosticEmitter {
return null;
}
parseVoidStatement(
tn: Tokenizer
): VoidStatement | null {
// at 'void': Expression ';'?
var startPos = tn.tokenPos;
var expression = this.parseExpression(tn, Precedence.GROUPING);
if (!expression) return null;
var ret = Node.createVoidStatement(expression, tn.range(startPos, tn.pos));
tn.skip(Token.SEMICOLON);
return ret;
}
parseWhileStatement(
tn: Tokenizer
): WhileStatement | null {
@ -2209,7 +2227,7 @@ export class Parser extends DiagnosticEmitter {
if (tn.skip(Token.CLOSEPAREN)) {
var statement = this.parseStatement(tn);
if (!statement) return null;
var ret = Node.createWhileStatement(<Expression>expression, <Statement>statement, tn.range(startPos, tn.pos));
var ret = Node.createWhileStatement(expression, statement, tn.range(startPos, tn.pos));
tn.skip(Token.SEMICOLON);
return ret;
} else {