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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

@ -79,6 +79,7 @@ import {
TryStatement, TryStatement,
VariableDeclaration, VariableDeclaration,
VariableStatement, VariableStatement,
VoidStatement,
WhileStatement, WhileStatement,
Expression, Expression,
@ -1195,9 +1196,14 @@ export class Compiler extends DiagnosticEmitter {
expr = this.compileTryStatement(<TryStatement>statement); expr = this.compileTryStatement(<TryStatement>statement);
break; break;
case NodeKind.VARIABLE: case NodeKind.VARIABLE: {
var variableInit = this.compileVariableStatement(<VariableStatement>statement); let initializer = this.compileVariableStatement(<VariableStatement>statement);
expr = variableInit ? variableInit : this.module.createNop(); expr = initializer ? initializer : this.module.createNop();
break;
}
case NodeKind.VOID:
expr = this.compileVoidStatement(<VoidStatement>statement);
break; break;
case NodeKind.WHILE: case NodeKind.WHILE:
@ -1646,6 +1652,10 @@ export class Compiler extends DiagnosticEmitter {
: 0; : 0;
} }
compileVoidStatement(statement: VoidStatement): ExpressionRef {
return this.compileExpression(statement.expression, Type.void, ConversionKind.EXPLICIT, false);
}
compileWhileStatement(statement: WhileStatement): ExpressionRef { compileWhileStatement(statement: WhileStatement): ExpressionRef {
// The condition does not yet initialize a branch // The condition does not yet initialize a branch
@ -1826,7 +1836,11 @@ export class Compiler extends DiagnosticEmitter {
break; break;
case NodeKind.PARENTHESIZED: case NodeKind.PARENTHESIZED:
expr = this.compileParenthesizedExpression(<ParenthesizedExpression>expression, contextualType); expr = this.compileParenthesizedExpression(
<ParenthesizedExpression>expression,
contextualType,
wrapSmallIntegers
);
break; break;
case NodeKind.PROPERTYACCESS: case NodeKind.PROPERTYACCESS:
@ -4507,9 +4521,18 @@ export class Compiler extends DiagnosticEmitter {
return this.module.createUnreachable(); 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 // 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, TypeParameter,
VariableStatement, VariableStatement,
VariableDeclaration, VariableDeclaration,
VoidStatement,
WhileStatement, WhileStatement,
addModifier, addModifier,
@ -1724,6 +1725,9 @@ export class Parser extends DiagnosticEmitter {
case Token.TYPE: case Token.TYPE:
return this.parseTypeDeclaration(tn, null); return this.parseTypeDeclaration(tn, null);
case Token.VOID:
return this.parseVoidStatement(tn);
case Token.WHILE: case Token.WHILE:
return this.parseWhileStatement(tn); return this.parseWhileStatement(tn);
@ -2196,6 +2200,20 @@ export class Parser extends DiagnosticEmitter {
return null; 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( parseWhileStatement(
tn: Tokenizer tn: Tokenizer
): WhileStatement | null { ): WhileStatement | null {
@ -2209,7 +2227,7 @@ export class Parser extends DiagnosticEmitter {
if (tn.skip(Token.CLOSEPAREN)) { if (tn.skip(Token.CLOSEPAREN)) {
var statement = this.parseStatement(tn); var statement = this.parseStatement(tn);
if (!statement) return null; 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); tn.skip(Token.SEMICOLON);
return ret; return ret;
} else { } else {

View File

@ -153,21 +153,12 @@
(i32.shr_s (i32.shr_s
(i32.shl (i32.shl
(i32.or (i32.or
(i32.shr_s (i32.and
(i32.shl (i32.shl
(i32.and (get_local $0)
(i32.shr_s (i32.const 8)
(i32.shl
(get_local $0)
(i32.const 24)
)
(i32.const 16)
)
(i32.const -256)
)
(i32.const 16)
) )
(i32.const 16) (i32.const -256)
) )
(i32.and (i32.and
(i32.shr_s (i32.shr_s

View File

@ -75,40 +75,28 @@
(i32.or (i32.or
(i32.or (i32.or
(i32.and (i32.and
(i32.and (i32.shl
(i32.and (get_local $0)
(i32.shl (i32.const 8)
(get_local $0)
(i32.const 8)
)
(i32.const 65535)
)
(i32.const 65280)
) )
(i32.const 65535) (i32.const 65280)
) )
(i32.and (i32.and
(i32.and (i32.shr_u
(i32.shr_u (get_local $0)
(get_local $0) (i32.const 8)
(i32.const 8)
)
(i32.const 255)
) )
(i32.const 65535) (i32.const 255)
) )
) )
(i32.and (i32.and
(get_local $0)
(i32.and (i32.and
(get_local $0) (i32.wrap/i64
(i32.and (i64.const 4294901760)
(i32.wrap/i64
(i64.const 4294901760)
)
(i32.const 65535)
) )
(i32.const 65535)
) )
(i32.const 65535)
) )
) )
(i32.const 65535) (i32.const 65535)
@ -352,62 +340,38 @@
(i32.shl (i32.shl
(i32.or (i32.or
(i32.or (i32.or
(i32.shr_s (i32.and
(i32.shl (i32.shl
(i32.and
(i32.shr_s
(i32.shl
(i32.shl
(get_local $0)
(i32.const 8)
)
(i32.const 16)
)
(i32.const 16)
)
(i32.shr_s
(i32.shl
(i32.const 65280)
(i32.const 16)
)
(i32.const 16)
)
)
(i32.const 16)
)
(i32.const 16)
)
(i32.shr_s
(i32.shl
(i32.and
(i32.shr_s
(get_local $0)
(i32.const 8)
)
(i32.const 255)
)
(i32.const 16)
)
(i32.const 16)
)
)
(i32.shr_s
(i32.shl
(i32.and
(get_local $0) (get_local $0)
(i32.shr_s (i32.const 8)
(i32.shl )
(i32.wrap/i64 (i32.shr_s
(i64.const 4294901760) (i32.shl
) (i32.const 65280)
(i32.const 16)
)
(i32.const 16) (i32.const 16)
) )
(i32.const 16)
)
)
(i32.and
(i32.shr_s
(get_local $0)
(i32.const 8)
)
(i32.const 255)
)
)
(i32.and
(get_local $0)
(i32.shr_s
(i32.shl
(i32.wrap/i64
(i64.const 4294901760)
)
(i32.const 16)
) )
(i32.const 16) (i32.const 16)
) )
(i32.const 16)
) )
) )
(i32.const 16) (i32.const 16)

View File

@ -0,0 +1,15 @@
(module
(type $i (func (result i32)))
(type $v (func))
(memory $0 1)
(export "memory" (memory $0))
(start $start)
(func $void/anInt (; 0 ;) (type $i) (result i32)
(i32.const 2)
)
(func $start (; 1 ;) (type $v)
(drop
(call $void/anInt)
)
)
)

12
tests/compiler/void.ts Normal file
View File

@ -0,0 +1,12 @@
void 1;
function anInt(): i32 {
return 2;
}
void anInt();
var u8Val1: u8 = 1;
var u8Val2: u8 = 255;
void (u8Val1 + u8Val2); // can remain unwrapped

View File

@ -0,0 +1,29 @@
(module
(type $i (func (result i32)))
(type $v (func))
(global $void/u8Val1 (mut i32) (i32.const 1))
(global $void/u8Val2 (mut i32) (i32.const 255))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
(export "memory" (memory $0))
(start $start)
(func $void/anInt (; 0 ;) (type $i) (result i32)
(return
(i32.const 2)
)
)
(func $start (; 1 ;) (type $v)
(drop
(i32.const 1)
)
(drop
(call $void/anInt)
)
(drop
(i32.add
(get_global $void/u8Val1)
(get_global $void/u8Val2)
)
)
)
)