mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-13 15:01:28 +00:00
More built-in constants; Get/set parsing fixes; I64.toF64 fixes
This commit is contained in:
@ -125,12 +125,18 @@ export function initialize(program: Program): void {
|
||||
[ "MAX_VALUE", new Global(program, "MAX_VALUE", "bool.MAX_VALUE", null, Type.bool).withConstantIntegerValue(1, 0) ]
|
||||
]);
|
||||
addFunction(program, "f32").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "MIN_VALUE", "f32.MIN_VALUE", null, Type.f32).withConstantFloatValue(-3.40282347e+38) ],
|
||||
[ "MAX_VALUE", new Global(program, "MAX_VALUE", "f32.MAX_VALUE", null, Type.f32).withConstantFloatValue(3.40282347e+38) ],
|
||||
[ "MIN_SAFE_INTEGER", new Global(program, "MIN_SAFE_INTEGER", "f32.MIN_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(-16777215) ],
|
||||
[ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f32.MAX_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(16777215) ]
|
||||
[ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f32.MAX_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(16777215) ],
|
||||
[ "EPSILON", new Global(program, "EPSILON", "f32.EPSILON", null, Type.f32).withConstantFloatValue(1.19209290e-07) ]
|
||||
]);
|
||||
addFunction(program, "f64").members = new Map([
|
||||
[ "MIN_VALUE", new Global(program, "MIN_VALUE", "f64.MIN_VALUE", null, Type.f64).withConstantFloatValue(-1.7976931348623157e+308) ],
|
||||
[ "MAX_VALUE", new Global(program, "MAX_VALUE", "f64.MAX_VALUE", null, Type.f64).withConstantFloatValue(1.7976931348623157e+308) ],
|
||||
[ "MIN_SAFE_INTEGER", new Global(program, "MIN_SAFE_INTEGER", "f64.MIN_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(-9007199254740991) ],
|
||||
[ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f64.MAX_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(9007199254740991) ]
|
||||
[ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f64.MAX_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(9007199254740991) ],
|
||||
[ "EPSILON", new Global(program, "EPSILON", "f64.EPSILON", null, Type.f64).withConstantFloatValue(2.2204460492503131e-16) ]
|
||||
]);
|
||||
if (program.target == Target.WASM64) {
|
||||
program.elements.set("isize", i64Func);
|
||||
@ -694,7 +700,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
|
||||
if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode))
|
||||
return module.createUnreachable();
|
||||
arg0 = compiler.compileExpression(operands[0], Type.void, ConversionKind.NONE);
|
||||
if ((compiler.currentType == usizeType && (<Type[]>typeArguments)[0].classType) || (compiler.currentType.classType && (<Type[]>typeArguments)[0] == usizeType)) {
|
||||
if (compiler.currentType != Type.void && compiler.currentType.kind == (<Type[]>typeArguments)[0].kind) {
|
||||
compiler.currentType = (<Type[]>typeArguments)[0];
|
||||
return arg0;
|
||||
}
|
||||
|
@ -2362,6 +2362,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
target = this.program.resolvePropertyAccess(<PropertyAccessExpression>targetExpression, this.currentFunction);
|
||||
break;
|
||||
|
||||
// case NodeKind.ELEMENTACCESS:
|
||||
|
||||
default:
|
||||
this.error(DiagnosticCode.Operation_not_supported, expression.range);
|
||||
}
|
||||
@ -2409,34 +2411,36 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (!element)
|
||||
return this.module.createUnreachable();
|
||||
|
||||
// local
|
||||
if (element.kind == ElementKind.LOCAL) {
|
||||
assert((<Local>element).type != null);
|
||||
this.currentType = <Type>(<Local>element).type;
|
||||
if ((<Local>element).hasConstantValue)
|
||||
return makeInlineConstant(<Local>element, this.module);
|
||||
assert((<Local>element).index >= 0);
|
||||
return this.module.createGetLocal((<Local>element).index, this.currentType.toNativeType());
|
||||
}
|
||||
switch (element.kind) {
|
||||
|
||||
// global
|
||||
if (element.kind == ElementKind.GLOBAL) {
|
||||
if (element.isBuiltIn)
|
||||
return compileBuiltinGetConstant(this, <Global>element);
|
||||
case ElementKind.LOCAL:
|
||||
assert((<Local>element).type != null);
|
||||
this.currentType = <Type>(<Local>element).type;
|
||||
if ((<Local>element).hasConstantValue)
|
||||
return makeInlineConstant(<Local>element, this.module);
|
||||
assert((<Local>element).index >= 0);
|
||||
return this.module.createGetLocal((<Local>element).index, this.currentType.toNativeType());
|
||||
|
||||
var global = <Global>element;
|
||||
if (!this.compileGlobal(global)) // reports
|
||||
case ElementKind.GLOBAL:
|
||||
if (element.isBuiltIn)
|
||||
return compileBuiltinGetConstant(this, <Global>element);
|
||||
|
||||
var global = <Global>element;
|
||||
if (!this.compileGlobal(global)) // reports
|
||||
return this.module.createUnreachable();
|
||||
assert(global.type != null); // has been resolved when compileGlobal succeeds
|
||||
this.currentType = <Type>global.type;
|
||||
if (global.hasConstantValue)
|
||||
return makeInlineConstant(global, this.module);
|
||||
else
|
||||
return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType());
|
||||
|
||||
// case ElementKind.FIELD
|
||||
|
||||
default:
|
||||
this.error(DiagnosticCode.Operation_not_supported, expression.range);
|
||||
return this.module.createUnreachable();
|
||||
assert(global.type != null);
|
||||
this.currentType = <Type>global.type;
|
||||
if (global.hasConstantValue)
|
||||
return makeInlineConstant(global, this.module);
|
||||
else
|
||||
return this.module.createGetGlobal((<Global>element).internalName, this.currentType.toNativeType());
|
||||
}
|
||||
|
||||
this.error(DiagnosticCode.Operation_not_supported, expression.range);
|
||||
return this.module.createUnreachable();
|
||||
}
|
||||
|
||||
compileLiteralExpression(expression: LiteralExpression, contextualType: Type): ExpressionRef {
|
||||
@ -2456,13 +2460,17 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (contextualType == Type.bool && (intValue.isZero || intValue.isOne))
|
||||
return this.module.createI32(intValue.isZero ? 0 : 1);
|
||||
if (contextualType == Type.f64)
|
||||
return this.module.createF64((<f64>intValue.lo) + (<f64>intValue.hi) * 0xffffffff);
|
||||
return this.module.createF64(intValue.toF64());
|
||||
if (contextualType == Type.f32)
|
||||
return this.module.createF32((<f32>intValue.lo) + (<f32>intValue.hi) * 0xffffffff);
|
||||
return this.module.createF32(<f32>intValue.toF64());
|
||||
if (contextualType.isLongInteger)
|
||||
return this.module.createI64(intValue.lo, intValue.hi);
|
||||
if (contextualType.isSmallInteger)
|
||||
return this.module.createI32(intValue.toI32());
|
||||
if (contextualType.isSmallInteger) {
|
||||
var smallIntValue: i32 = contextualType.isSignedInteger
|
||||
? intValue.lo << contextualType.smallIntegerShift >> contextualType.smallIntegerShift
|
||||
: intValue.lo & contextualType.smallIntegerMask;
|
||||
return this.module.createI32(smallIntValue);
|
||||
}
|
||||
if (contextualType == Type.void && !intValue.fitsInI32) {
|
||||
this.currentType = Type.i64;
|
||||
return this.module.createI64(intValue.lo, intValue.hi);
|
||||
|
@ -717,12 +717,25 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (tn.skip(Token.READONLY))
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.READONLY, tn.range()), modifiers);
|
||||
|
||||
// check if accessor: ('get' | 'set') ^\n Identifier
|
||||
tn.mark();
|
||||
var isGetter = false;
|
||||
var isSetter = false;
|
||||
if (isGetter = tn.skip(Token.GET))
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.GET, tn.range()), modifiers);
|
||||
else if (isSetter = tn.skip(Token.SET)) // can't be both
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.SET, tn.range()), modifiers);
|
||||
if (isGetter = tn.skip(Token.GET)) {
|
||||
if (tn.peek(true, true) == Token.IDENTIFIER && !tn.nextTokenOnNewLine)
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.GET, tn.range()), modifiers);
|
||||
else {
|
||||
tn.reset();
|
||||
isGetter = false;
|
||||
}
|
||||
} else if (isSetter = tn.skip(Token.SET)) { // can't be both
|
||||
if (tn.peek(true, true) == Token.IDENTIFIER && !tn.nextTokenOnNewLine)
|
||||
modifiers = addModifier(Node.createModifier(ModifierKind.SET, tn.range()), modifiers);
|
||||
else {
|
||||
tn.reset();
|
||||
isSetter = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (tn.skip(Token.CONSTRUCTOR) || tn.skip(Token.IDENTIFIER)) { // order is important
|
||||
var identifier: IdentifierExpression = tn.token == Token.CONSTRUCTOR
|
||||
|
@ -939,8 +939,10 @@ export class Program extends DiagnosticEmitter {
|
||||
target = this.resolvePropertyAccess(<PropertyAccessExpression>expression, contextualFunction);
|
||||
break;
|
||||
|
||||
// case NodeKind.ELEMENTACCESS:
|
||||
|
||||
default:
|
||||
throw new Error("target must be an identifier or property access");
|
||||
throw new Error("property target expected");
|
||||
}
|
||||
if (!target)
|
||||
return null;
|
||||
|
@ -730,13 +730,13 @@ export class Tokenizer extends DiagnosticEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
peek(checkOnNewLine: bool = false): Token {
|
||||
peek(checkOnNewLine: bool = false, preferIdentifier: bool = false, maxCompoundLength: i32 = i32.MAX_VALUE): Token {
|
||||
var text = this.source.text;
|
||||
if (this.nextToken < 0) {
|
||||
var posBefore = this.pos;
|
||||
var tokenBefore = this.token;
|
||||
var tokenPosBefore = this.tokenPos;
|
||||
this.nextToken = this.unsafeNext();
|
||||
this.nextToken = this.unsafeNext(preferIdentifier, maxCompoundLength);
|
||||
if (checkOnNewLine) {
|
||||
this.nextTokenOnNewLine = false;
|
||||
while (--this.tokenPos > posBefore) {
|
||||
@ -1096,7 +1096,7 @@ export class Tokenizer extends DiagnosticEmitter {
|
||||
if (this.pos < this.end) {
|
||||
var c = text.charCodeAt(this.pos);
|
||||
if (c == CharCode.E || c == CharCode.e) {
|
||||
if (++this.pos < this.end && text.charCodeAt(this.pos) == CharCode.MINUS)
|
||||
if (++this.pos < this.end && (text.charCodeAt(this.pos) == CharCode.MINUS || text.charCodeAt(this.pos) == CharCode.PLUS) && isDecimalDigit(text.charCodeAt(this.pos + 1)))
|
||||
++this.pos;
|
||||
while (this.pos < this.end && isDecimalDigit(text.charCodeAt(this.pos)))
|
||||
++this.pos;
|
||||
|
@ -60,6 +60,10 @@ export class I64 {
|
||||
return this.lo;
|
||||
}
|
||||
|
||||
toF64(): f64 {
|
||||
return <f64>this.hi * 0x100000000 + <f64>(this.lo >>> 0);
|
||||
}
|
||||
|
||||
eq(other: I64): bool {
|
||||
return this.eq32(other.lo, other.hi);
|
||||
}
|
||||
|
Reference in New Issue
Block a user