mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-26 15:32:16 +00:00
More tests and fixes (unary, binary, globals)
This commit is contained in:
parent
ef859937a8
commit
b9edfb5185
@ -925,12 +925,13 @@ export abstract class Statement extends Node {
|
|||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static createVariableDeclaration(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, range: Range): VariableDeclaration {
|
static createVariableDeclaration(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, modifiers: Modifier[] | null, range: Range): VariableDeclaration {
|
||||||
const elem: VariableDeclaration = new VariableDeclaration();
|
const elem: VariableDeclaration = new VariableDeclaration();
|
||||||
elem.range = range;
|
elem.range = range;
|
||||||
(elem.identifier = identifier).parent = elem;
|
(elem.identifier = identifier).parent = elem;
|
||||||
if (elem.type = type) (<TypeNode>type).parent = elem;
|
if (elem.type = type) (<TypeNode>type).parent = elem;
|
||||||
if (elem.initializer = initializer) (<Expression>initializer).parent = elem;
|
if (elem.initializer = initializer) (<Expression>initializer).parent = elem;
|
||||||
|
elem.modifiers = modifiers;
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1681,7 +1682,7 @@ export class TryStatement extends Statement {
|
|||||||
export class VariableDeclaration extends VariableLikeDeclarationStatement {
|
export class VariableDeclaration extends VariableLikeDeclarationStatement {
|
||||||
|
|
||||||
kind = NodeKind.VARIABLEDECLARATION;
|
kind = NodeKind.VARIABLEDECLARATION;
|
||||||
modifiers = null;
|
modifiers: Modifier[] | null;
|
||||||
|
|
||||||
serialize(sb: string[]): void {
|
serialize(sb: string[]): void {
|
||||||
this.identifier.serialize(sb);
|
this.identifier.serialize(sb);
|
||||||
|
172
src/compiler.ts
172
src/compiler.ts
@ -90,6 +90,15 @@ export class Options {
|
|||||||
noTreeShaking: bool = false;
|
noTreeShaking: bool = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enum ConversionKind {
|
||||||
|
/** No conversion. */
|
||||||
|
NONE,
|
||||||
|
/** Implicit conversion. */
|
||||||
|
IMPLICIT,
|
||||||
|
/** Explicit conversion. */
|
||||||
|
EXPLICIT
|
||||||
|
}
|
||||||
|
|
||||||
export class Compiler extends DiagnosticEmitter {
|
export class Compiler extends DiagnosticEmitter {
|
||||||
|
|
||||||
/** Program reference. */
|
/** Program reference. */
|
||||||
@ -141,7 +150,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
compile(): Module {
|
compile(): Module {
|
||||||
const program: Program = this.program;
|
const program: Program = this.program;
|
||||||
|
|
||||||
// initialize lookup maps
|
// initialize lookup maps, builtins, imports, exports, etc.
|
||||||
program.initialize(this.options.target);
|
program.initialize(this.options.target);
|
||||||
|
|
||||||
// compile entry file (exactly one, usually)
|
// compile entry file (exactly one, usually)
|
||||||
@ -181,7 +190,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
heapStartBuffer[7] = (initial.hi >>> 24) as u8;
|
heapStartBuffer[7] = (initial.hi >>> 24) as u8;
|
||||||
} else {
|
} else {
|
||||||
if (!initial.fitsInU32)
|
if (!initial.fitsInU32)
|
||||||
throw new Error("memory size overflow");
|
throw new Error("static memory size overflows 32 bits");
|
||||||
heapStartBuffer = new Uint8Array(4);
|
heapStartBuffer = new Uint8Array(4);
|
||||||
heapStartOffset = 4;
|
heapStartOffset = 4;
|
||||||
heapStartBuffer[0] = (initial.lo ) as u8;
|
heapStartBuffer[0] = (initial.lo ) as u8;
|
||||||
@ -299,6 +308,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return false;
|
return false;
|
||||||
element.type = type;
|
element.type = type;
|
||||||
}
|
}
|
||||||
|
if (this.module.noEmit)
|
||||||
|
return true;
|
||||||
const nativeType: NativeType = typeToNativeType(<Type>type);
|
const nativeType: NativeType = typeToNativeType(<Type>type);
|
||||||
let initializer: ExpressionRef;
|
let initializer: ExpressionRef;
|
||||||
let initializeInStart: bool;
|
let initializeInStart: bool;
|
||||||
@ -331,10 +342,10 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
throw new Error("unexpected missing declaration or constant value");
|
throw new Error("unexpected missing declaration or constant value");
|
||||||
const internalName: string = element.internalName;
|
const internalName: string = element.internalName;
|
||||||
if (initializeInStart) {
|
if (initializeInStart) {
|
||||||
this.module.addGlobal(internalName, NativeType.I32, true, this.module.createI32(-1));
|
this.module.addGlobal(internalName, nativeType, true, this.module.createI32(-1));
|
||||||
this.startFunctionBody.push(this.module.createSetGlobal(internalName, initializer));
|
this.startFunctionBody.push(this.module.createSetGlobal(internalName, initializer));
|
||||||
} else
|
} else
|
||||||
this.module.addGlobal(internalName, NativeType.I32, element.isMutable, initializer);
|
this.module.addGlobal(internalName, nativeType, element.isMutable, initializer);
|
||||||
return element.isCompiled = true;
|
return element.isCompiled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +361,6 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
compileEnum(element: Enum): void {
|
compileEnum(element: Enum): void {
|
||||||
if (element.isCompiled)
|
if (element.isCompiled)
|
||||||
return;
|
return;
|
||||||
element.isCompiled = true;
|
|
||||||
let previousInternalName: string | null = null;
|
let previousInternalName: string | null = null;
|
||||||
for (let [key, val] of element.members) {
|
for (let [key, val] of element.members) {
|
||||||
if (val.hasConstantValue) {
|
if (val.hasConstantValue) {
|
||||||
@ -381,6 +391,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
throw new Error("unexpected missing declaration or constant value");
|
throw new Error("unexpected missing declaration or constant value");
|
||||||
previousInternalName = val.internalName;
|
previousInternalName = val.internalName;
|
||||||
}
|
}
|
||||||
|
element.isCompiled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
@ -405,8 +416,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const declaration: FunctionDeclaration | null = instance.template.declaration;
|
const declaration: FunctionDeclaration | null = instance.template.declaration;
|
||||||
if (!declaration) // TODO: compile builtins
|
if (!declaration)
|
||||||
throw new Error("not implemented");
|
throw new Error("unexpected missing declaration");
|
||||||
|
|
||||||
if (!declaration.statements) {
|
if (!declaration.statements) {
|
||||||
this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, declaration.identifier.range);
|
this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, declaration.identifier.range);
|
||||||
@ -588,7 +599,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
const previousType: Type = this.currentType;
|
const previousType: Type = this.currentType;
|
||||||
const previousNoEmit: bool = this.module.noEmit;
|
const previousNoEmit: bool = this.module.noEmit;
|
||||||
this.module.noEmit = true;
|
this.module.noEmit = true;
|
||||||
this.compileExpression(expression, contextualType, false); // now performs a dry run
|
this.compileExpression(expression, contextualType, ConversionKind.NONE); // now performs a dry run
|
||||||
const type: Type = this.currentType;
|
const type: Type = this.currentType;
|
||||||
this.currentType = previousType;
|
this.currentType = previousType;
|
||||||
this.module.noEmit = previousNoEmit;
|
this.module.noEmit = previousNoEmit;
|
||||||
@ -698,7 +709,12 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileExpressionStatement(statement: ExpressionStatement): ExpressionRef {
|
compileExpressionStatement(statement: ExpressionStatement): ExpressionRef {
|
||||||
return this.compileExpression(statement.expression, Type.void);
|
let expr: ExpressionRef = this.compileExpression(statement.expression, Type.void, ConversionKind.NONE);
|
||||||
|
if (this.currentType != Type.void) {
|
||||||
|
expr = this.module.createDrop(expr);
|
||||||
|
this.currentType = Type.void;
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
compileForStatement(statement: ForStatement): ExpressionRef {
|
compileForStatement(statement: ForStatement): ExpressionRef {
|
||||||
@ -850,7 +866,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// expressions
|
// expressions
|
||||||
|
|
||||||
compileExpression(expression: Expression, contextualType: Type, convert: bool = true): ExpressionRef {
|
compileExpression(expression: Expression, contextualType: Type, conversionKind: ConversionKind = ConversionKind.IMPLICIT): ExpressionRef {
|
||||||
this.currentType = contextualType;
|
this.currentType = contextualType;
|
||||||
|
|
||||||
let expr: ExpressionRef;
|
let expr: ExpressionRef;
|
||||||
@ -912,19 +928,22 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
throw new Error("unexpected expression kind");
|
throw new Error("unexpected expression kind");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convert && this.currentType != contextualType) {
|
if (conversionKind != ConversionKind.NONE) {
|
||||||
expr = this.convertExpression(expr, this.currentType, contextualType);
|
expr = this.convertExpression(expr, this.currentType, contextualType, conversionKind, expression);
|
||||||
this.currentType = contextualType;
|
this.currentType = contextualType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
convertExpression(expr: ExpressionRef, fromType: Type, toType: Type): ExpressionRef {
|
convertExpression(expr: ExpressionRef, fromType: Type, toType: Type, conversionKind: ConversionKind, reportNode: Node): ExpressionRef {
|
||||||
|
if (conversionKind == ConversionKind.NONE)
|
||||||
|
return expr;
|
||||||
|
|
||||||
// void to any
|
// void to any
|
||||||
if (fromType.kind == TypeKind.VOID)
|
if (fromType.kind == TypeKind.VOID) {
|
||||||
|
this.error(DiagnosticCode.Operation_not_supported, reportNode.range);
|
||||||
throw new Error("unexpected conversion from void");
|
throw new Error("unexpected conversion from void");
|
||||||
|
}
|
||||||
|
|
||||||
// any to void
|
// any to void
|
||||||
if (toType.kind == TypeKind.VOID)
|
if (toType.kind == TypeKind.VOID)
|
||||||
@ -1070,16 +1089,17 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (losesInformation && conversionKind == ConversionKind.IMPLICIT)
|
||||||
|
this.error(DiagnosticCode.Conversion_from_type_0_to_1_requires_an_explicit_cast, reportNode.range, fromType.toString(), toType.toString());
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef {
|
compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef {
|
||||||
const toType: Type | null = this.program.resolveType(expression.toType, this.currentFunction.contextualTypeArguments); // reports
|
const toType: Type | null = this.program.resolveType(expression.toType, this.currentFunction.contextualTypeArguments); // reports
|
||||||
if (toType && toType != contextualType) {
|
return toType && toType != contextualType
|
||||||
const expr: ExpressionRef = this.compileExpression(expression.expression, <Type>toType, false);
|
? this.compileExpression(expression.expression, <Type>toType, ConversionKind.EXPLICIT)
|
||||||
return this.convertExpression(expr, this.currentType, <Type>toType);
|
: this.compileExpression(expression.expression, contextualType);
|
||||||
}
|
|
||||||
return this.compileExpression(expression.expression, contextualType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileBinaryExpression(expression: BinaryExpression, contextualType: Type): ExpressionRef {
|
compileBinaryExpression(expression: BinaryExpression, contextualType: Type): ExpressionRef {
|
||||||
@ -1091,7 +1111,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
switch (expression.operator) {
|
switch (expression.operator) {
|
||||||
|
|
||||||
case Token.LESSTHAN:
|
case Token.LESSTHAN:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.LtF32
|
? BinaryOp.LtF32
|
||||||
@ -1104,7 +1124,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.GREATERTHAN:
|
case Token.GREATERTHAN:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.GtF32
|
? BinaryOp.GtF32
|
||||||
@ -1117,7 +1137,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.LESSTHAN_EQUALS:
|
case Token.LESSTHAN_EQUALS:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.LeF32
|
? BinaryOp.LeF32
|
||||||
@ -1130,7 +1150,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.GREATERTHAN_EQUALS:
|
case Token.GREATERTHAN_EQUALS:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.GeF32
|
? BinaryOp.GeF32
|
||||||
@ -1144,7 +1164,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
case Token.EQUALS_EQUALS:
|
case Token.EQUALS_EQUALS:
|
||||||
case Token.EQUALS_EQUALS_EQUALS:
|
case Token.EQUALS_EQUALS_EQUALS:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.EqF32
|
? BinaryOp.EqF32
|
||||||
@ -1162,7 +1182,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.PLUS_EQUALS:
|
case Token.PLUS_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.PLUS:
|
case Token.PLUS:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.AddF32
|
? BinaryOp.AddF32
|
||||||
@ -1176,7 +1196,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.MINUS_EQUALS:
|
case Token.MINUS_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.MINUS:
|
case Token.MINUS:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.SubF32
|
? BinaryOp.SubF32
|
||||||
@ -1190,7 +1210,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.ASTERISK_EQUALS:
|
case Token.ASTERISK_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.ASTERISK:
|
case Token.ASTERISK:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.MulF32
|
? BinaryOp.MulF32
|
||||||
@ -1204,7 +1224,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.SLASH_EQUALS:
|
case Token.SLASH_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.SLASH:
|
case Token.SLASH:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType == Type.f32
|
op = this.currentType == Type.f32
|
||||||
? BinaryOp.DivF32
|
? BinaryOp.DivF32
|
||||||
@ -1218,7 +1238,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.PERCENT_EQUALS:
|
case Token.PERCENT_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.PERCENT:
|
case Token.PERCENT:
|
||||||
left = this.compileExpression(expression.left, contextualType, false);
|
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
if (this.currentType.isAnyFloat)
|
if (this.currentType.isAnyFloat)
|
||||||
throw new Error("not implemented"); // TODO: internal fmod, possibly simply imported from JS
|
throw new Error("not implemented"); // TODO: internal fmod, possibly simply imported from JS
|
||||||
@ -1230,7 +1250,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.LESSTHAN_LESSTHAN_EQUALS:
|
case Token.LESSTHAN_LESSTHAN_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.LESSTHAN_LESSTHAN:
|
case Token.LESSTHAN_LESSTHAN:
|
||||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType);
|
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType.isLongInteger
|
op = this.currentType.isLongInteger
|
||||||
? BinaryOp.ShlI64
|
? BinaryOp.ShlI64
|
||||||
@ -1240,7 +1260,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.GREATERTHAN_GREATERTHAN_EQUALS:
|
case Token.GREATERTHAN_GREATERTHAN_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.GREATERTHAN_GREATERTHAN:
|
case Token.GREATERTHAN_GREATERTHAN:
|
||||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType);
|
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType.isSignedInteger
|
op = this.currentType.isSignedInteger
|
||||||
? this.currentType.isLongInteger
|
? this.currentType.isLongInteger
|
||||||
@ -1254,7 +1274,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN_EQUALS:
|
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN:
|
case Token.GREATERTHAN_GREATERTHAN_GREATERTHAN:
|
||||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.u64 : contextualType);
|
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.u64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType.isLongInteger
|
op = this.currentType.isLongInteger
|
||||||
? BinaryOp.ShrU64
|
? BinaryOp.ShrU64
|
||||||
@ -1264,7 +1284,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.AMPERSAND_EQUALS:
|
case Token.AMPERSAND_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.AMPERSAND:
|
case Token.AMPERSAND:
|
||||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType);
|
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType.isLongInteger
|
op = this.currentType.isLongInteger
|
||||||
? BinaryOp.AndI64
|
? BinaryOp.AndI64
|
||||||
@ -1274,7 +1294,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.BAR_EQUALS:
|
case Token.BAR_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.BAR:
|
case Token.BAR:
|
||||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType);
|
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType.isLongInteger
|
op = this.currentType.isLongInteger
|
||||||
? BinaryOp.OrI64
|
? BinaryOp.OrI64
|
||||||
@ -1284,7 +1304,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case Token.CARET_EQUALS:
|
case Token.CARET_EQUALS:
|
||||||
compound = Token.EQUALS;
|
compound = Token.EQUALS;
|
||||||
case Token.CARET:
|
case Token.CARET:
|
||||||
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType);
|
left = this.compileExpression(expression.left, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
right = this.compileExpression(expression.right, this.currentType);
|
right = this.compileExpression(expression.right, this.currentType);
|
||||||
op = this.currentType.isLongInteger
|
op = this.currentType.isLongInteger
|
||||||
? BinaryOp.XorI64
|
? BinaryOp.XorI64
|
||||||
@ -1316,11 +1336,17 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
this.currentType = (<Local>element).type;
|
this.currentType = (<Local>element).type;
|
||||||
return this.module.createTeeLocal((<Local>element).index, valueWithCorrectType);
|
return this.module.createTeeLocal((<Local>element).index, valueWithCorrectType);
|
||||||
}
|
}
|
||||||
|
this.currentType = Type.void;
|
||||||
return this.module.createSetLocal((<Local>element).index, valueWithCorrectType);
|
return this.module.createSetLocal((<Local>element).index, valueWithCorrectType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.kind == ElementKind.GLOBAL && (<Global>element).type) {
|
if (element.kind == ElementKind.GLOBAL) {
|
||||||
|
this.compileGlobal(<Global>element);
|
||||||
|
if (!(<Global>element).isMutable)
|
||||||
|
this.error(DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, expression.range, element.internalName);
|
||||||
if (tee) {
|
if (tee) {
|
||||||
|
if (!(<Global>element).type)
|
||||||
|
return this.module.createUnreachable();
|
||||||
const globalNativeType: NativeType = typeToNativeType(<Type>(<Global>element).type);
|
const globalNativeType: NativeType = typeToNativeType(<Type>(<Global>element).type);
|
||||||
this.currentType = <Type>(<Global>element).type;
|
this.currentType = <Type>(<Global>element).type;
|
||||||
return this.module.createBlock(null, [ // teeGlobal
|
return this.module.createBlock(null, [ // teeGlobal
|
||||||
@ -1328,6 +1354,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
this.module.createGetGlobal((<Global>element).internalName, globalNativeType)
|
this.module.createGetGlobal((<Global>element).internalName, globalNativeType)
|
||||||
], globalNativeType);
|
], globalNativeType);
|
||||||
}
|
}
|
||||||
|
this.currentType = Type.void;
|
||||||
return this.module.createSetGlobal((<Global>element).internalName, valueWithCorrectType);
|
return this.module.createSetGlobal((<Global>element).internalName, valueWithCorrectType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1384,7 +1411,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
const operands: ExpressionRef[] = new Array(parameterCount);
|
const operands: ExpressionRef[] = new Array(parameterCount);
|
||||||
for (let i: i32 = 0; i < parameterCount; ++i) {
|
for (let i: i32 = 0; i < parameterCount; ++i) {
|
||||||
if (argumentExpressions.length > i) {
|
if (argumentExpressions.length > i) {
|
||||||
operands[i] = this.compileExpression(argumentExpressions[i], parameters[i].type, true);
|
operands[i] = this.compileExpression(argumentExpressions[i], parameters[i].type);
|
||||||
} else {
|
} else {
|
||||||
const initializer: Expression | null = parameters[i].initializer;
|
const initializer: Expression | null = parameters[i].initializer;
|
||||||
if (initializer) { // omitted, uses initializer
|
if (initializer) { // omitted, uses initializer
|
||||||
@ -1621,47 +1648,52 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
} else if (expression.kind == NodeKind.THIS) {
|
} else if (expression.kind == NodeKind.THIS) {
|
||||||
if (this.currentFunction.instanceMethodOf) {
|
if (this.currentFunction.instanceMethodOf) {
|
||||||
this.currentType = this.currentFunction.instanceMethodOf.type;
|
this.currentType = this.currentFunction.instanceMethodOf.type;
|
||||||
return this.module.createGetLocal(0, typeToNativeType(this.currentType));
|
return this.module.createGetLocal(0, this.options.target == Target.WASM64 ? NativeType.I64 : NativeType.I32);
|
||||||
}
|
}
|
||||||
this.error(DiagnosticCode._this_cannot_be_referenced_in_current_location, expression.range);
|
this.error(DiagnosticCode._this_cannot_be_referenced_in_current_location, expression.range);
|
||||||
this.currentType = this.options.target == Target.WASM64 ? Type.u64 : Type.u32;
|
this.currentType = this.options.target == Target.WASM64 ? Type.u64 : Type.u32;
|
||||||
return this.module.createUnreachable();
|
return this.module.createUnreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
const element: Element | null = this.program.resolveElement(expression, this.currentFunction); // reports
|
if (expression.kind == NodeKind.IDENTIFIER) {
|
||||||
if (!element) {
|
|
||||||
if (expression.kind == NodeKind.IDENTIFIER) {
|
|
||||||
|
|
||||||
// NaN
|
// NaN
|
||||||
if ((<IdentifierExpression>expression).name == "NaN")
|
if ((<IdentifierExpression>expression).name == "NaN")
|
||||||
if (this.currentType.kind == TypeKind.F32)
|
if (this.currentType.kind == TypeKind.F32)
|
||||||
return this.module.createF32(NaN);
|
return this.module.createF32(NaN);
|
||||||
else {
|
else {
|
||||||
this.currentType = Type.f64;
|
this.currentType = Type.f64;
|
||||||
return this.module.createF64(NaN);
|
return this.module.createF64(NaN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infinity
|
// Infinity
|
||||||
if ((<IdentifierExpression>expression).name == "Infinity")
|
if ((<IdentifierExpression>expression).name == "Infinity")
|
||||||
if (this.currentType.kind == TypeKind.F32)
|
if (this.currentType.kind == TypeKind.F32)
|
||||||
return this.module.createF32(Infinity);
|
return this.module.createF32(Infinity);
|
||||||
else {
|
else {
|
||||||
this.currentType = Type.f64;
|
this.currentType = Type.f64;
|
||||||
return this.module.createF64(Infinity);
|
return this.module.createF64(Infinity);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return this.module.createUnreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const element: Element | null = this.program.resolveElement(expression, this.currentFunction); // reports
|
||||||
|
if (!element)
|
||||||
|
return this.module.createUnreachable();
|
||||||
|
|
||||||
// local
|
// local
|
||||||
if (element.kind == ElementKind.LOCAL)
|
if (element.kind == ElementKind.LOCAL) {
|
||||||
|
this.currentType = (<Local>element).type;
|
||||||
return this.module.createGetLocal((<Local>element).index, typeToNativeType(this.currentType = (<Local>element).type));
|
return this.module.createGetLocal((<Local>element).index, typeToNativeType(this.currentType = (<Local>element).type));
|
||||||
|
}
|
||||||
|
|
||||||
// global
|
// global
|
||||||
if (element.kind == ElementKind.GLOBAL)
|
if (element.kind == ElementKind.GLOBAL) {
|
||||||
|
if ((<Global>element).type)
|
||||||
|
this.currentType = <Type>(<Global>element).type;
|
||||||
return this.compileGlobal(<Global>element) // reports
|
return this.compileGlobal(<Global>element) // reports
|
||||||
? this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType = <Type>(<Global>element).type))
|
? this.module.createGetGlobal((<Global>element).internalName, typeToNativeType(this.currentType = <Type>(<Global>element).type))
|
||||||
: this.module.createUnreachable();
|
: this.module.createUnreachable();
|
||||||
|
}
|
||||||
|
|
||||||
// field
|
// field
|
||||||
// if (element.kind == ElementKind.FIELD)
|
// if (element.kind == ElementKind.FIELD)
|
||||||
@ -1691,6 +1723,10 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
const intValue: I64 = (<IntegerLiteralExpression>expression).value;
|
const intValue: I64 = (<IntegerLiteralExpression>expression).value;
|
||||||
if (contextualType == Type.bool && (intValue.isZero || intValue.isOne))
|
if (contextualType == Type.bool && (intValue.isZero || intValue.isOne))
|
||||||
return this.module.createI32(intValue.isZero ? 0 : 1);
|
return this.module.createI32(intValue.isZero ? 0 : 1);
|
||||||
|
if (contextualType == Type.f64)
|
||||||
|
return this.module.createF64((<f64>intValue.lo) + (<f64>intValue.hi) * 0xffffffff);
|
||||||
|
if (contextualType == Type.f32)
|
||||||
|
return this.module.createF32((<f32>intValue.lo) + (<f32>intValue.hi) * 0xffffffff);
|
||||||
if (contextualType.isLongInteger)
|
if (contextualType.isLongInteger)
|
||||||
return this.module.createI64(intValue.lo, intValue.hi);
|
return this.module.createI64(intValue.lo, intValue.hi);
|
||||||
if (!intValue.fitsInI32) {
|
if (!intValue.fitsInI32) {
|
||||||
@ -1769,10 +1805,10 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
switch (expression.operator) {
|
switch (expression.operator) {
|
||||||
|
|
||||||
case Token.PLUS:
|
case Token.PLUS:
|
||||||
return this.compileExpression(operandExpression, contextualType);
|
return this.compileExpression(operandExpression, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
|
|
||||||
case Token.MINUS:
|
case Token.MINUS:
|
||||||
operand = this.compileExpression(operandExpression, contextualType);
|
operand = this.compileExpression(operandExpression, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
if (this.currentType == Type.f32)
|
if (this.currentType == Type.f32)
|
||||||
op = UnaryOp.NegF32;
|
op = UnaryOp.NegF32;
|
||||||
else if (this.currentType == Type.f64)
|
else if (this.currentType == Type.f64)
|
||||||
@ -1784,7 +1820,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.PLUS_PLUS:
|
case Token.PLUS_PLUS:
|
||||||
operand = this.compileExpression(operandExpression, contextualType);
|
operand = this.compileExpression(operandExpression, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
return this.currentType == Type.f32
|
return this.currentType == Type.f32
|
||||||
? this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.AddF32, operand, this.module.createF32(1)), contextualType != Type.void)
|
? this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.AddF32, operand, this.module.createF32(1)), contextualType != Type.void)
|
||||||
: this.currentType == Type.f64
|
: this.currentType == Type.f64
|
||||||
@ -1794,7 +1830,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
: this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.AddI32, operand, this.module.createI32(1)), contextualType != Type.void);
|
: this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.AddI32, operand, this.module.createI32(1)), contextualType != Type.void);
|
||||||
|
|
||||||
case Token.MINUS_MINUS:
|
case Token.MINUS_MINUS:
|
||||||
operand = this.compileExpression(operandExpression, contextualType);
|
operand = this.compileExpression(operandExpression, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
return this.currentType == Type.f32
|
return this.currentType == Type.f32
|
||||||
? this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.SubF32, operand, this.module.createF32(1)), contextualType != Type.void)
|
? this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.SubF32, operand, this.module.createF32(1)), contextualType != Type.void)
|
||||||
: this.currentType == Type.f64
|
: this.currentType == Type.f64
|
||||||
@ -1804,7 +1840,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
: this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.SubI32, operand, this.module.createI32(1)), contextualType != Type.void);
|
: this.compileAssignmentWithValue(operandExpression, this.module.createBinary(BinaryOp.SubI32, operand, this.module.createI32(1)), contextualType != Type.void);
|
||||||
|
|
||||||
case Token.EXCLAMATION:
|
case Token.EXCLAMATION:
|
||||||
operand = this.compileExpression(operandExpression, Type.bool, false);
|
operand = this.compileExpression(operandExpression, Type.bool, ConversionKind.NONE);
|
||||||
if (this.currentType == Type.f32) {
|
if (this.currentType == Type.f32) {
|
||||||
this.currentType = Type.bool;
|
this.currentType = Type.bool;
|
||||||
return this.module.createBinary(BinaryOp.EqF32, operand, this.module.createF32(0));
|
return this.module.createBinary(BinaryOp.EqF32, operand, this.module.createF32(0));
|
||||||
@ -1820,7 +1856,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.TILDE:
|
case Token.TILDE:
|
||||||
operand = this.compileExpression(operandExpression, contextualType.isAnyFloat ? Type.i64 : contextualType);
|
operand = this.compileExpression(operandExpression, contextualType.isAnyFloat ? Type.i64 : contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
|
||||||
return this.currentType.isLongInteger
|
return this.currentType.isLongInteger
|
||||||
? this.module.createBinary(BinaryOp.XorI64, operand, this.module.createI64(-1, -1))
|
? this.module.createBinary(BinaryOp.XorI64, operand, this.module.createI64(-1, -1))
|
||||||
: this.module.createBinary(BinaryOp.XorI32, operand, this.module.createI32(-1));
|
: this.module.createBinary(BinaryOp.XorI32, operand, this.module.createI32(-1));
|
||||||
|
@ -60,6 +60,7 @@ export enum DiagnosticCode {
|
|||||||
Function_implementation_is_missing_or_not_immediately_following_the_declaration = 2391,
|
Function_implementation_is_missing_or_not_immediately_following_the_declaration = 2391,
|
||||||
Duplicate_function_implementation = 2393,
|
Duplicate_function_implementation = 2393,
|
||||||
Export_declaration_conflicts_with_exported_declaration_of_0 = 2484,
|
Export_declaration_conflicts_with_exported_declaration_of_0 = 2484,
|
||||||
|
Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property = 2540,
|
||||||
The_target_of_an_assignment_must_be_a_variable_or_a_property_access = 2541,
|
The_target_of_an_assignment_must_be_a_variable_or_a_property_access = 2541,
|
||||||
Expected_0_arguments_but_got_1 = 2554,
|
Expected_0_arguments_but_got_1 = 2554,
|
||||||
Expected_at_least_0_arguments_but_got_1 = 2555,
|
Expected_at_least_0_arguments_but_got_1 = 2555,
|
||||||
@ -128,6 +129,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
case 2391: return "Function implementation is missing or not immediately following the declaration.";
|
case 2391: return "Function implementation is missing or not immediately following the declaration.";
|
||||||
case 2393: return "Duplicate function implementation.";
|
case 2393: return "Duplicate function implementation.";
|
||||||
case 2484: return "Export declaration conflicts with exported declaration of '{0}'.";
|
case 2484: return "Export declaration conflicts with exported declaration of '{0}'.";
|
||||||
|
case 2540: return "Cannot assign to '{0}' because it is a constant or a read-only property.";
|
||||||
case 2541: return "The target of an assignment must be a variable or a property access.";
|
case 2541: return "The target of an assignment must be a variable or a property access.";
|
||||||
case 2554: return "Expected {0} arguments, but got {1}.";
|
case 2554: return "Expected {0} arguments, but got {1}.";
|
||||||
case 2555: return "Expected at least {0} arguments, but got {1}.";
|
case 2555: return "Expected at least {0} arguments, but got {1}.";
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
"Function implementation is missing or not immediately following the declaration.": 2391,
|
"Function implementation is missing or not immediately following the declaration.": 2391,
|
||||||
"Duplicate function implementation.": 2393,
|
"Duplicate function implementation.": 2393,
|
||||||
"Export declaration conflicts with exported declaration of '{0}'.": 2484,
|
"Export declaration conflicts with exported declaration of '{0}'.": 2484,
|
||||||
|
"Cannot assign to '{0}' because it is a constant or a read-only property.": 2540,
|
||||||
"The target of an assignment must be a variable or a property access.": 2541,
|
"The target of an assignment must be a variable or a property access.": 2541,
|
||||||
"Expected {0} arguments, but got {1}.": 2554,
|
"Expected {0} arguments, but got {1}.": 2554,
|
||||||
"Expected at least {0} arguments, but got {1}.": 2555,
|
"Expected at least {0} arguments, but got {1}.": 2555,
|
||||||
|
@ -350,7 +350,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
const members: VariableDeclaration[] = new Array();
|
const members: VariableDeclaration[] = new Array();
|
||||||
const isDeclare = hasModifier(ModifierKind.DECLARE, modifiers);
|
const isDeclare = hasModifier(ModifierKind.DECLARE, modifiers);
|
||||||
do {
|
do {
|
||||||
const member: VariableDeclaration | null = this.parseVariableDeclaration(tn, isDeclare);
|
const member: VariableDeclaration | null = this.parseVariableDeclaration(tn, isDeclare, modifiers);
|
||||||
if (!member)
|
if (!member)
|
||||||
return null;
|
return null;
|
||||||
members.push(<VariableDeclaration>member);
|
members.push(<VariableDeclaration>member);
|
||||||
@ -361,7 +361,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseVariableDeclaration(tn: Tokenizer, isDeclare: bool = false): VariableDeclaration | null {
|
parseVariableDeclaration(tn: Tokenizer, isDeclare: bool = false, parentModifiers: Modifier[]): VariableDeclaration | null {
|
||||||
// Identifier (':' Type)? ('=' Expression)?
|
// Identifier (':' Type)? ('=' Expression)?
|
||||||
if (!tn.skip(Token.IDENTIFIER)) {
|
if (!tn.skip(Token.IDENTIFIER)) {
|
||||||
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
this.error(DiagnosticCode.Identifier_expected, tn.range());
|
||||||
@ -383,7 +383,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
if (!initializer)
|
if (!initializer)
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Statement.createVariableDeclaration(identifier, type, initializer, Range.join(identifier.range, tn.range()));
|
return Statement.createVariableDeclaration(identifier, type, initializer, parentModifiers, Range.join(identifier.range, tn.range()));
|
||||||
}
|
}
|
||||||
|
|
||||||
parseEnum(tn: Tokenizer, modifiers: Modifier[]): EnumDeclaration | null {
|
parseEnum(tn: Tokenizer, modifiers: Modifier[]): EnumDeclaration | null {
|
||||||
|
@ -764,7 +764,7 @@ export class Global extends Element {
|
|||||||
|
|
||||||
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : /* internals aren't exports */ false; }
|
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : /* internals aren't exports */ false; }
|
||||||
get isGlobalExport(): bool { return this.globalExportName != null; }
|
get isGlobalExport(): bool { return this.globalExportName != null; }
|
||||||
get isMutable(): bool { return this.declaration ? hasModifier(ModifierKind.CONST, this.declaration.modifiers) : /* internals are immutable */ false; }
|
get isMutable(): bool { return this.declaration ? !hasModifier(ModifierKind.CONST, this.declaration.modifiers) : /* internals are immutable */ false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A function parameter. */
|
/** A function parameter. */
|
||||||
|
@ -49,9 +49,12 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
|
|||||||
const actual = module.toText() + "(;\n[program.elements]\n " + iterate(program.elements.keys()).join("\n ") + "\n[program.exports]\n " + iterate(program.exports.keys()).join("\n ") + "\n;)\n";
|
const actual = module.toText() + "(;\n[program.elements]\n " + iterate(program.elements.keys()).join("\n ") + "\n[program.exports]\n " + iterate(program.exports.keys()).join("\n ") + "\n;)\n";
|
||||||
const fixture = path.basename(filename, ".ts") + ".wast";
|
const fixture = path.basename(filename, ".ts") + ".wast";
|
||||||
|
|
||||||
|
if (module.validate())
|
||||||
|
console.log("Validates");
|
||||||
|
|
||||||
if (isCreate) {
|
if (isCreate) {
|
||||||
fs.writeFileSync(__dirname + "/compiler/" + fixture, actual, { encoding: "utf8" });
|
fs.writeFileSync(__dirname + "/compiler/" + fixture, actual, { encoding: "utf8" });
|
||||||
console.log("Created\n");
|
console.log("Created");
|
||||||
} else {
|
} else {
|
||||||
const expected = fs.readFileSync(__dirname + "/compiler/" + fixture, { encoding: "utf8" });
|
const expected = fs.readFileSync(__dirname + "/compiler/" + fixture, { encoding: "utf8" });
|
||||||
const diffs = diff("compiler/" + fixture, expected, actual);
|
const diffs = diff("compiler/" + fixture, expected, actual);
|
||||||
@ -59,9 +62,11 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
|
|||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
console.log(diffs);
|
console.log(diffs);
|
||||||
} else {
|
} else {
|
||||||
console.log("No changes\n");
|
console.log("No changes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log();
|
||||||
});
|
});
|
||||||
|
|
||||||
function iterate<T>(it: IterableIterator<T>): T[] {
|
function iterate<T>(it: IterableIterator<T>): T[] {
|
||||||
|
161
tests/compiler/binary.ts
Normal file
161
tests/compiler/binary.ts
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
let b: bool = false;
|
||||||
|
|
||||||
|
let i: i32 = 0;
|
||||||
|
|
||||||
|
i < 1;
|
||||||
|
i > 1;
|
||||||
|
i <= 1;
|
||||||
|
i >= 1;
|
||||||
|
i == 1;
|
||||||
|
i === 1;
|
||||||
|
i + 1;
|
||||||
|
i - 1;
|
||||||
|
i * 1;
|
||||||
|
i / 1;
|
||||||
|
i % 1;
|
||||||
|
i << 1;
|
||||||
|
i >> 1;
|
||||||
|
i >>> 1;
|
||||||
|
i & 1;
|
||||||
|
i | 1;
|
||||||
|
i ^ 1;
|
||||||
|
|
||||||
|
b = i < 1;
|
||||||
|
b = i > 1;
|
||||||
|
b = i <= 1;
|
||||||
|
b = i >= 1;
|
||||||
|
b = i == 1;
|
||||||
|
b = i === 1;
|
||||||
|
i = i + 1;
|
||||||
|
i = i - 1;
|
||||||
|
i = i * 1;
|
||||||
|
i = i / 1;
|
||||||
|
i = i % 1;
|
||||||
|
i = i << 1;
|
||||||
|
i = i >> 1;
|
||||||
|
i = i >>> 1;
|
||||||
|
i = i & 1;
|
||||||
|
i = i | 1;
|
||||||
|
i = i ^ 1;
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
i -= 1;
|
||||||
|
i *= 1;
|
||||||
|
i %= 1;
|
||||||
|
i <<= 1;
|
||||||
|
i >>= 1;
|
||||||
|
i >>>= 1;
|
||||||
|
i &= 1;
|
||||||
|
i |= 1;
|
||||||
|
i ^= 1;
|
||||||
|
|
||||||
|
let I: i64 = 0;
|
||||||
|
|
||||||
|
I < 1;
|
||||||
|
I > 1;
|
||||||
|
I <= 1;
|
||||||
|
I >= 1;
|
||||||
|
I == 1;
|
||||||
|
I === 1;
|
||||||
|
I + 1;
|
||||||
|
I - 1;
|
||||||
|
I * 1;
|
||||||
|
I / 1;
|
||||||
|
I % 1;
|
||||||
|
I << 1;
|
||||||
|
I >> 1;
|
||||||
|
I >>> 1;
|
||||||
|
I & 1;
|
||||||
|
I | 1;
|
||||||
|
I ^ 1;
|
||||||
|
|
||||||
|
b = I < 1;
|
||||||
|
b = I > 1;
|
||||||
|
b = I <= 1;
|
||||||
|
b = I >= 1;
|
||||||
|
b = I == 1;
|
||||||
|
b = I === 1;
|
||||||
|
I = I + 1;
|
||||||
|
I = I - 1;
|
||||||
|
I = I * 1;
|
||||||
|
I = I / 1;
|
||||||
|
I = I % 1;
|
||||||
|
I = I << 1;
|
||||||
|
I = I >> 1;
|
||||||
|
I = I >>> 1;
|
||||||
|
I = I & 1;
|
||||||
|
I = I | 1;
|
||||||
|
I = I ^ 1;
|
||||||
|
|
||||||
|
I += 1;
|
||||||
|
I -= 1;
|
||||||
|
I *= 1;
|
||||||
|
I %= 1;
|
||||||
|
I <<= 1;
|
||||||
|
I >>= 1;
|
||||||
|
I >>>= 1;
|
||||||
|
I &= 1;
|
||||||
|
I |= 1;
|
||||||
|
I ^= 1;
|
||||||
|
|
||||||
|
let f: f32 = 0;
|
||||||
|
|
||||||
|
f < 1;
|
||||||
|
f > 1;
|
||||||
|
f <= 1;
|
||||||
|
f >= 1;
|
||||||
|
f == 1;
|
||||||
|
f === 1;
|
||||||
|
f + 1;
|
||||||
|
f - 1;
|
||||||
|
f * 1;
|
||||||
|
f / 1;
|
||||||
|
// f % 1;
|
||||||
|
|
||||||
|
b = f < 1;
|
||||||
|
b = f > 1;
|
||||||
|
b = f <= 1;
|
||||||
|
b = f >= 1;
|
||||||
|
b = f == 1;
|
||||||
|
b = f === 1;
|
||||||
|
f = f + 1;
|
||||||
|
f = f - 1;
|
||||||
|
f = f * 1;
|
||||||
|
f = f / 1;
|
||||||
|
// f = f % 1;
|
||||||
|
|
||||||
|
f += 1;
|
||||||
|
f -= 1;
|
||||||
|
f *= 1;
|
||||||
|
// f %= 1;
|
||||||
|
|
||||||
|
let F: f64 = 0;
|
||||||
|
|
||||||
|
F < 1;
|
||||||
|
F > 1;
|
||||||
|
F <= 1;
|
||||||
|
F >= 1;
|
||||||
|
F == 1;
|
||||||
|
F === 1;
|
||||||
|
F + 1;
|
||||||
|
F - 1;
|
||||||
|
F * 1;
|
||||||
|
F / 1;
|
||||||
|
// f % 1;
|
||||||
|
|
||||||
|
b = F < 1;
|
||||||
|
b = F > 1;
|
||||||
|
b = F <= 1;
|
||||||
|
b = F >= 1;
|
||||||
|
b = F == 1;
|
||||||
|
b = F === 1;
|
||||||
|
F = F + 1;
|
||||||
|
F = F - 1;
|
||||||
|
F = F * 1;
|
||||||
|
F = F / 1;
|
||||||
|
// F = F % 1;
|
||||||
|
|
||||||
|
F += 1;
|
||||||
|
F -= 1;
|
||||||
|
F *= 1;
|
||||||
|
// F %= 1;
|
847
tests/compiler/binary.wast
Normal file
847
tests/compiler/binary.wast
Normal file
@ -0,0 +1,847 @@
|
|||||||
|
(module
|
||||||
|
(type $v (func))
|
||||||
|
(global $binary/i (mut i32) (i32.const 0))
|
||||||
|
(global $binary/b (mut i32) (i32.const -1))
|
||||||
|
(global $binary/I (mut i64) (i64.const 0))
|
||||||
|
(global $binary/f (mut f32) (f32.const 0))
|
||||||
|
(global $binary/F (mut f64) (f64.const 0))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $start (; 0 ;) (type $v)
|
||||||
|
(drop
|
||||||
|
(i32.lt_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.gt_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.le_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.ge_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.eq
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.eq
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.add
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.sub
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.mul
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.div_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.rem_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.shl
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.shr_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.shr_u
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.and
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.or
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.xor
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i32.lt_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i32.gt_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i32.le_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i32.ge_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i32.eq
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i32.eq
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.add
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.mul
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.div_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.rem_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.shl
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.shr_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.shr_u
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.and
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.or
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.xor
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.add
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.mul
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.rem_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.shl
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.shr_s
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.shr_u
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.and
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.or
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/i
|
||||||
|
(i32.xor
|
||||||
|
(get_global $binary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.lt_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.gt_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.le_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.ge_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.eq
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.eq
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.add
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.sub
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.mul
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.div_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.rem_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.shl
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.shr_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.shr_u
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.and
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.or
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.xor
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i64.lt_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i64.gt_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i64.le_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i64.ge_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i64.eq
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(i64.eq
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.add
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.sub
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.mul
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.div_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.rem_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.shl
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.shr_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.shr_u
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.and
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.or
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.xor
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.add
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.sub
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.mul
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.rem_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.shl
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.shr_s
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.shr_u
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.and
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.or
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/I
|
||||||
|
(i64.xor
|
||||||
|
(get_global $binary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.lt
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.gt
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.le
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.ge
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.eq
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.eq
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.add
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.sub
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.mul
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.div
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f32.lt
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f32.gt
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f32.le
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f32.ge
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f32.eq
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f32.eq
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/f
|
||||||
|
(f32.add
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/f
|
||||||
|
(f32.sub
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/f
|
||||||
|
(f32.mul
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/f
|
||||||
|
(f32.div
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/f
|
||||||
|
(f32.add
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/f
|
||||||
|
(f32.sub
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/f
|
||||||
|
(f32.mul
|
||||||
|
(get_global $binary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.lt
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.gt
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.le
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.ge
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.eq
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.eq
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.add
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.sub
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.mul
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.div
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f64.lt
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f64.gt
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f64.le
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f64.ge
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f64.eq
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/b
|
||||||
|
(f64.eq
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/F
|
||||||
|
(f64.add
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/F
|
||||||
|
(f64.sub
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/F
|
||||||
|
(f64.mul
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/F
|
||||||
|
(f64.div
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/F
|
||||||
|
(f64.add
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/F
|
||||||
|
(f64.sub
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $binary/F
|
||||||
|
(f64.mul
|
||||||
|
(get_global $binary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
clz
|
||||||
|
ctz
|
||||||
|
popcnt
|
||||||
|
rotl
|
||||||
|
rotr
|
||||||
|
abs
|
||||||
|
ceil
|
||||||
|
copysign
|
||||||
|
floor
|
||||||
|
max
|
||||||
|
min
|
||||||
|
nearest
|
||||||
|
sqrt
|
||||||
|
trunc
|
||||||
|
isNaN
|
||||||
|
isFinite
|
||||||
|
binary/b
|
||||||
|
binary/i
|
||||||
|
binary/I
|
||||||
|
binary/f
|
||||||
|
binary/F
|
||||||
|
[program.exports]
|
||||||
|
|
||||||
|
;)
|
14
tests/compiler/do.ts
Normal file
14
tests/compiler/do.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export function loopDo(n: i32): void {
|
||||||
|
do {
|
||||||
|
n = n - 1;
|
||||||
|
} while (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loopDoInDo(n: i32): void {
|
||||||
|
do {
|
||||||
|
n = n - 1;
|
||||||
|
do {
|
||||||
|
n = n - 1;
|
||||||
|
} while (n);
|
||||||
|
} while (n);
|
||||||
|
}
|
79
tests/compiler/do.wast
Normal file
79
tests/compiler/do.wast
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
(module
|
||||||
|
(type $iv (func (param i32)))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(func $do/loopDo (; 0 ;) (type $iv) (param $0 i32)
|
||||||
|
(block $break$1.1
|
||||||
|
(loop $continue$1.1
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.sub
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br_if $continue$1.1
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $do/loopDoInDo (; 1 ;) (type $iv) (param $0 i32)
|
||||||
|
(block $break$1.1
|
||||||
|
(loop $continue$1.1
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.sub
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block $break$1.2
|
||||||
|
(loop $continue$1.2
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.sub
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br_if $continue$1.2
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br_if $continue$1.1
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
clz
|
||||||
|
ctz
|
||||||
|
popcnt
|
||||||
|
rotl
|
||||||
|
rotr
|
||||||
|
abs
|
||||||
|
ceil
|
||||||
|
copysign
|
||||||
|
floor
|
||||||
|
max
|
||||||
|
min
|
||||||
|
nearest
|
||||||
|
sqrt
|
||||||
|
trunc
|
||||||
|
isNaN
|
||||||
|
isFinite
|
||||||
|
do/loopDo
|
||||||
|
do/loopDoInDo
|
||||||
|
[program.exports]
|
||||||
|
do/loopDo
|
||||||
|
do/loopDoInDo
|
||||||
|
;)
|
@ -1,7 +1,7 @@
|
|||||||
(module
|
(module
|
||||||
(type $iii (func (param i32 i32) (result i32)))
|
(type $iii (func (param i32 i32) (result i32)))
|
||||||
(global $export/a i32 (i32.const 1))
|
(global $export/a (mut i32) (i32.const 1))
|
||||||
(global $export/b i32 (i32.const 2))
|
(global $export/b (mut i32) (i32.const 2))
|
||||||
(memory $0 1)
|
(memory $0 1)
|
||||||
(data (i32.const 4) "\08\00\00\00")
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
(export "memory" (memory $0))
|
(export "memory" (memory $0))
|
||||||
|
22
tests/compiler/if.ts
Normal file
22
tests/compiler/if.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export function ifThenElse(n: i32): bool {
|
||||||
|
if (n)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ifThen(n: i32): bool {
|
||||||
|
if (n)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ifThenElseBlock(n: i32): bool {
|
||||||
|
if (n) {
|
||||||
|
; // nop
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
; // nop
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
71
tests/compiler/if.wast
Normal file
71
tests/compiler/if.wast
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
(module
|
||||||
|
(type $ii (func (param i32) (result i32)))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(func $if/ifThenElse (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(return
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $if/ifThen (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(return
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $if/ifThenElseBlock (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(block
|
||||||
|
(nop)
|
||||||
|
(return
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(nop)
|
||||||
|
(return
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
clz
|
||||||
|
ctz
|
||||||
|
popcnt
|
||||||
|
rotl
|
||||||
|
rotr
|
||||||
|
abs
|
||||||
|
ceil
|
||||||
|
copysign
|
||||||
|
floor
|
||||||
|
max
|
||||||
|
min
|
||||||
|
nearest
|
||||||
|
sqrt
|
||||||
|
trunc
|
||||||
|
isNaN
|
||||||
|
isFinite
|
||||||
|
if/ifThenElse
|
||||||
|
if/ifThen
|
||||||
|
if/ifThenElseBlock
|
||||||
|
[program.exports]
|
||||||
|
if/ifThenElse
|
||||||
|
if/ifThen
|
||||||
|
if/ifThenElseBlock
|
||||||
|
;)
|
@ -1,8 +1,8 @@
|
|||||||
(module
|
(module
|
||||||
(type $iii (func (param i32 i32) (result i32)))
|
(type $iii (func (param i32 i32) (result i32)))
|
||||||
(type $v (func))
|
(type $v (func))
|
||||||
(global $export/a i32 (i32.const 1))
|
(global $export/a (mut i32) (i32.const 1))
|
||||||
(global $export/b i32 (i32.const 2))
|
(global $export/b (mut i32) (i32.const 2))
|
||||||
(memory $0 1)
|
(memory $0 1)
|
||||||
(data (i32.const 4) "\08\00\00\00")
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
(export "memory" (memory $0))
|
(export "memory" (memory $0))
|
||||||
|
46
tests/compiler/literals.ts
Normal file
46
tests/compiler/literals.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
0;
|
||||||
|
1;
|
||||||
|
2;
|
||||||
|
3;
|
||||||
|
4;
|
||||||
|
5;
|
||||||
|
6;
|
||||||
|
7;
|
||||||
|
8;
|
||||||
|
9;
|
||||||
|
0x0;
|
||||||
|
0x1;
|
||||||
|
0x2;
|
||||||
|
0x3;
|
||||||
|
0x4;
|
||||||
|
0x5;
|
||||||
|
0x6;
|
||||||
|
0x7;
|
||||||
|
0x8;
|
||||||
|
0x9;
|
||||||
|
0xA;
|
||||||
|
0xB;
|
||||||
|
0xC;
|
||||||
|
0xD;
|
||||||
|
0xE;
|
||||||
|
0xF;
|
||||||
|
0xa;
|
||||||
|
0xb;
|
||||||
|
0xc;
|
||||||
|
0xd;
|
||||||
|
0xe;
|
||||||
|
0xf;
|
||||||
|
0o0;
|
||||||
|
0o1;
|
||||||
|
0o2;
|
||||||
|
0o3;
|
||||||
|
0o4;
|
||||||
|
0o5;
|
||||||
|
0o6;
|
||||||
|
0o7;
|
||||||
|
0b0;
|
||||||
|
0b1;
|
||||||
|
true;
|
||||||
|
false;
|
||||||
|
NaN;
|
||||||
|
Infinity;
|
168
tests/compiler/literals.wast
Normal file
168
tests/compiler/literals.wast
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
(module
|
||||||
|
(type $v (func))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $start (; 0 ;) (type $v)
|
||||||
|
(drop
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 3)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 5)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 6)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 7)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 9)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 3)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 5)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 6)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 7)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 9)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 10)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 11)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 12)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 13)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 14)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 15)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 10)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 11)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 12)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 13)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 14)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 15)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 3)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 4)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 5)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 6)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 7)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.const nan:0x8000000000000)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.const inf)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
clz
|
||||||
|
ctz
|
||||||
|
popcnt
|
||||||
|
rotl
|
||||||
|
rotr
|
||||||
|
abs
|
||||||
|
ceil
|
||||||
|
copysign
|
||||||
|
floor
|
||||||
|
max
|
||||||
|
min
|
||||||
|
nearest
|
||||||
|
sqrt
|
||||||
|
trunc
|
||||||
|
isNaN
|
||||||
|
isFinite
|
||||||
|
[program.exports]
|
||||||
|
|
||||||
|
;)
|
88
tests/compiler/unary.ts
Normal file
88
tests/compiler/unary.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
+1;
|
||||||
|
-1;
|
||||||
|
!1;
|
||||||
|
~1;
|
||||||
|
+1.25;
|
||||||
|
-1.25;
|
||||||
|
!1.25;
|
||||||
|
// ~1.25;
|
||||||
|
|
||||||
|
let i: i32 = 0;
|
||||||
|
|
||||||
|
+i;
|
||||||
|
-i;
|
||||||
|
!i;
|
||||||
|
~i;
|
||||||
|
++i;
|
||||||
|
--i;
|
||||||
|
|
||||||
|
i = +1;
|
||||||
|
i = -1;
|
||||||
|
i = !1;
|
||||||
|
i = ~1;
|
||||||
|
i = +i;
|
||||||
|
i = -i;
|
||||||
|
i = !i;
|
||||||
|
i = ~i;
|
||||||
|
i = ++i;
|
||||||
|
i = --i;
|
||||||
|
|
||||||
|
let I: i64 = 0;
|
||||||
|
|
||||||
|
+I;
|
||||||
|
-I;
|
||||||
|
!I;
|
||||||
|
~I;
|
||||||
|
++I;
|
||||||
|
--I;
|
||||||
|
|
||||||
|
I = +1;
|
||||||
|
I = -1;
|
||||||
|
I = !1;
|
||||||
|
I = ~1;
|
||||||
|
I = +I;
|
||||||
|
I = -I;
|
||||||
|
I = !I;
|
||||||
|
I = ~I;
|
||||||
|
I = ++I;
|
||||||
|
I = --I;
|
||||||
|
|
||||||
|
let f: f32 = 0;
|
||||||
|
|
||||||
|
+f;
|
||||||
|
-f;
|
||||||
|
!f;
|
||||||
|
// ~f;
|
||||||
|
++f;
|
||||||
|
--f;
|
||||||
|
|
||||||
|
f = +1.25;
|
||||||
|
f = -1.25;
|
||||||
|
i = !1.25;
|
||||||
|
// i = ~1.25;
|
||||||
|
f = +f;
|
||||||
|
f = -f;
|
||||||
|
i = !f;
|
||||||
|
// i = ~f;
|
||||||
|
f = ++f;
|
||||||
|
f = --f;
|
||||||
|
|
||||||
|
let F: f64 = 0;
|
||||||
|
|
||||||
|
+F;
|
||||||
|
-F;
|
||||||
|
!F;
|
||||||
|
// ~F;
|
||||||
|
++F;
|
||||||
|
--F;
|
||||||
|
|
||||||
|
F = +1.25;
|
||||||
|
F = -1.25;
|
||||||
|
I = !1.25;
|
||||||
|
// I = ~1.25;
|
||||||
|
F = +F;
|
||||||
|
F = -F;
|
||||||
|
I = !F;
|
||||||
|
// I = ~F;
|
||||||
|
F = ++F;
|
||||||
|
F = --F;
|
420
tests/compiler/unary.wast
Normal file
420
tests/compiler/unary.wast
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
(module
|
||||||
|
(type $v (func))
|
||||||
|
(global $unary/i (mut i32) (i32.const 0))
|
||||||
|
(global $unary/I (mut i64) (i64.const 0))
|
||||||
|
(global $unary/f (mut f32) (f32.const 0))
|
||||||
|
(global $unary/F (mut f64) (f64.const 0))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $start (; 0 ;) (type $v)
|
||||||
|
(drop
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.sub
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.eqz
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.xor
|
||||||
|
(i32.const 1)
|
||||||
|
(i32.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.const 1.25)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.neg
|
||||||
|
(f64.const 1.25)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.eq
|
||||||
|
(f64.const 1.25)
|
||||||
|
(f64.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.sub
|
||||||
|
(i32.const 0)
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.eqz
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i32.xor
|
||||||
|
(get_global $unary/i)
|
||||||
|
(i32.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.add
|
||||||
|
(get_global $unary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $unary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.sub
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.eqz
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.xor
|
||||||
|
(i32.const 1)
|
||||||
|
(i32.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.sub
|
||||||
|
(i32.const 0)
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.eqz
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.xor
|
||||||
|
(get_global $unary/i)
|
||||||
|
(i32.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(block (result i32)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.add
|
||||||
|
(get_global $unary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(block (result i32)
|
||||||
|
(set_global $unary/i
|
||||||
|
(i32.sub
|
||||||
|
(get_global $unary/i)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/i)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.sub
|
||||||
|
(i64.const 0)
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.eqz
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(i64.xor
|
||||||
|
(get_global $unary/I)
|
||||||
|
(i64.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.add
|
||||||
|
(get_global $unary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.sub
|
||||||
|
(get_global $unary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.sub
|
||||||
|
(i64.const 0)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.extend_s/i32
|
||||||
|
(i32.eqz
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.xor
|
||||||
|
(i64.const 1)
|
||||||
|
(i64.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.sub
|
||||||
|
(i64.const 0)
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.extend_s/i32
|
||||||
|
(i64.eqz
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.xor
|
||||||
|
(get_global $unary/I)
|
||||||
|
(i64.const -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(block (result i64)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.add
|
||||||
|
(get_global $unary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(block (result i64)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.sub
|
||||||
|
(get_global $unary/I)
|
||||||
|
(i64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/I)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(get_global $unary/f)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.neg
|
||||||
|
(get_global $unary/f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f32.eq
|
||||||
|
(get_global $unary/f)
|
||||||
|
(f32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(f32.add
|
||||||
|
(get_global $unary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(f32.sub
|
||||||
|
(get_global $unary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(f32.const 1.25)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(f32.neg
|
||||||
|
(f32.const 1.25)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(f64.eq
|
||||||
|
(f64.const 1.25)
|
||||||
|
(f64.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(get_global $unary/f)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(f32.neg
|
||||||
|
(get_global $unary/f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/i
|
||||||
|
(f32.eq
|
||||||
|
(get_global $unary/f)
|
||||||
|
(f32.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(block (result f32)
|
||||||
|
(set_global $unary/f
|
||||||
|
(f32.add
|
||||||
|
(get_global $unary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/f
|
||||||
|
(block (result f32)
|
||||||
|
(set_global $unary/f
|
||||||
|
(f32.sub
|
||||||
|
(get_global $unary/f)
|
||||||
|
(f32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/f)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(get_global $unary/F)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.neg
|
||||||
|
(get_global $unary/F)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(f64.eq
|
||||||
|
(get_global $unary/F)
|
||||||
|
(f64.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(f64.add
|
||||||
|
(get_global $unary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(f64.sub
|
||||||
|
(get_global $unary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(f64.const 1.25)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(f64.neg
|
||||||
|
(f64.const 1.25)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.extend_s/i32
|
||||||
|
(f64.eq
|
||||||
|
(f64.const 1.25)
|
||||||
|
(f64.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(get_global $unary/F)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(f64.neg
|
||||||
|
(get_global $unary/F)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/I
|
||||||
|
(i64.extend_s/i32
|
||||||
|
(f64.eq
|
||||||
|
(get_global $unary/F)
|
||||||
|
(f64.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(block (result f64)
|
||||||
|
(set_global $unary/F
|
||||||
|
(f64.add
|
||||||
|
(get_global $unary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/F)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $unary/F
|
||||||
|
(block (result f64)
|
||||||
|
(set_global $unary/F
|
||||||
|
(f64.sub
|
||||||
|
(get_global $unary/F)
|
||||||
|
(f64.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_global $unary/F)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
clz
|
||||||
|
ctz
|
||||||
|
popcnt
|
||||||
|
rotl
|
||||||
|
rotr
|
||||||
|
abs
|
||||||
|
ceil
|
||||||
|
copysign
|
||||||
|
floor
|
||||||
|
max
|
||||||
|
min
|
||||||
|
nearest
|
||||||
|
sqrt
|
||||||
|
trunc
|
||||||
|
isNaN
|
||||||
|
isFinite
|
||||||
|
unary/i
|
||||||
|
unary/I
|
||||||
|
unary/f
|
||||||
|
unary/F
|
||||||
|
[program.exports]
|
||||||
|
|
||||||
|
;)
|
14
tests/compiler/while.ts
Normal file
14
tests/compiler/while.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export function loopWhile(n: i32): void {
|
||||||
|
while (n) {
|
||||||
|
n = n - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loopWhileInWhile(n: i32): void {
|
||||||
|
while (n) {
|
||||||
|
n = n - 1;
|
||||||
|
while (n) {
|
||||||
|
n = n - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
tests/compiler/while.wast
Normal file
88
tests/compiler/while.wast
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
(module
|
||||||
|
(type $iv (func (param i32)))
|
||||||
|
(memory $0 1)
|
||||||
|
(data (i32.const 4) "\08\00\00\00")
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(func $while/loopWhile (; 0 ;) (type $iv) (param $0 i32)
|
||||||
|
(block $break$1.1
|
||||||
|
(loop $continue$1.1
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(block
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.sub
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$1.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $while/loopWhileInWhile (; 1 ;) (type $iv) (param $0 i32)
|
||||||
|
(block $break$1.1
|
||||||
|
(loop $continue$1.1
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(block
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.sub
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block $break$1.2
|
||||||
|
(loop $continue$1.2
|
||||||
|
(if
|
||||||
|
(get_local $0)
|
||||||
|
(block
|
||||||
|
(block
|
||||||
|
(set_local $0
|
||||||
|
(i32.sub
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$1.2)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(br $continue$1.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(;
|
||||||
|
[program.elements]
|
||||||
|
clz
|
||||||
|
ctz
|
||||||
|
popcnt
|
||||||
|
rotl
|
||||||
|
rotr
|
||||||
|
abs
|
||||||
|
ceil
|
||||||
|
copysign
|
||||||
|
floor
|
||||||
|
max
|
||||||
|
min
|
||||||
|
nearest
|
||||||
|
sqrt
|
||||||
|
trunc
|
||||||
|
isNaN
|
||||||
|
isFinite
|
||||||
|
while/loopWhile
|
||||||
|
while/loopWhileInWhile
|
||||||
|
[program.exports]
|
||||||
|
while/loopWhile
|
||||||
|
while/loopWhileInWhile
|
||||||
|
;)
|
16
tests/set_global-immutable.js
Normal file
16
tests/set_global-immutable.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
var binaryen = require("binaryen");
|
||||||
|
|
||||||
|
// "It is a validation error for a set_global to index an immutable global variable."
|
||||||
|
|
||||||
|
var mod = new binaryen.Module();
|
||||||
|
mod.addGlobal("a", binaryen.i32, false, mod.i32.const(0));
|
||||||
|
|
||||||
|
var funcType = mod.addFunctionType("v", binaryen.none, []);
|
||||||
|
var func = mod.addFunction("start", funcType, [], mod.block("", [
|
||||||
|
mod.setGlobal("a", mod.i32.const(1))
|
||||||
|
]));
|
||||||
|
mod.setStart(func);
|
||||||
|
|
||||||
|
console.log(mod.emitText());
|
||||||
|
if (mod.validate())
|
||||||
|
console.log("-> validates");
|
Loading…
x
Reference in New Issue
Block a user