src/values/PrimitiveValue.js
'use strict';
/* @flow */
const Value = require('../Value');
const CompletionRecord = require('../CompletionRecord');
let StringValue;
/**
* Represents a primitive value.
*/
class PrimitiveValue extends Value {
constructor(value) {
super(null);
this.native = value;
//Object.defineProperty(this, 'native', {
// 'value': value,
// 'enumerable': true
//});
}
ref(name, realm) {
var that = this;
let out = Object.create(null);
out.getValue = function *() { return yield * that.get(name, realm); };
out.setValue = function *(to) { yield * that.set(name, to, realm); };
return out;
}
*get(name, realm) {
return yield * this.derivePrototype(realm).get(name, realm, this);
}
*set(name, to, realm) {
//Can't set primative properties.
}
derivePrototype(realm) {
switch ( typeof this.native ) {
case 'string': return realm.StringPrototype;
case 'number': return realm.NumberPrototype;
case 'boolean': return realm.BooleanPrototype;
}
}
toNative() {
return this.native;
}
get debugString() {
if ( typeof this.native === 'object' ) return '[native object]';
else if ( typeof this.native === 'function' ) return '[native function]';
else if ( typeof this.native === 'string' ) return JSON.stringify(this.native);
else return '' + this.native;
}
*asString() {
return this.native.toString();
}
*doubleEquals(other) {
let native = this.native;
if ( other instanceof PrimitiveValue) {
return Value.fromNative(this.native == other.native);
} else if ( typeof native === 'number' ) {
if ( other instanceof StringValue ) {
let num = yield * other.toNumberValue();
return Value.from(native === num.toNative());
} else {
return Value.false;
}
} else if ( typeof native == 'boolean' ) {
let num = yield * this.toNumberValue();
return yield * num.doubleEquals(other);
}
return Value.false;
}
*tripleEquals(other) { return this.native === other.toNative() ? Value.true : Value.false; }
*add(other) { return this.fromNative(this.native + (yield * other.toPrimitiveNative())); }
*instanceOf(other) { return Value.false; }
*unaryPlus() { return this.fromNative(+this.native); }
*unaryMinus() { return this.fromNative(-this.native); }
*not() { return this.fromNative(!this.native); }
*observableProperties(realm) {
yield * this.derivePrototype(realm).observableProperties(realm);
}
*makeThisForNew() {
throw new Error('primative value is not a constructor');
}
getPrototype(realm) {
return this.derivePrototype(realm);
}
get truthy() {
return !!this.native;
}
get jsTypeName() {
return typeof this.native;
}
*toPrimitiveValue(preferedType) { return this; }
*toStringValue() {
if ( typeof this.native === 'string' ) return this;
return this.fromNative(String(this.native));
}
*toNumberValue() {
if ( typeof this.native === 'number' ) return this;
return this.fromNative(Number(this.native));
}
}
module.exports = PrimitiveValue;
StringValue = require('./StringValue');