Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Jan 24, 2025
1 parent e4ff7de commit e04a7ac
Show file tree
Hide file tree
Showing 14 changed files with 303 additions and 27 deletions.
7 changes: 7 additions & 0 deletions src/web/vaev-script/lang/expression.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace Vaev::Script {

struct Expression {};

} // namespace Vaev::Script
7 changes: 7 additions & 0 deletions src/web/vaev-script/lang/identifier.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace Vaev::Script {

struct Identifier {};

} // namespace Vaev::Script
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions src/web/vaev-script/lang/module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace Vaev::Script {

struct Module {};

} // namespace Vaev::Script
7 changes: 7 additions & 0 deletions src/web/vaev-script/lang/script.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace Vaev::Script {

struct Script {};

} // namespace Vaev::Script
7 changes: 7 additions & 0 deletions src/web/vaev-script/lang/statement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace Vaev::Script {

struct Statement {};

} // namespace Vaev::Script
36 changes: 24 additions & 12 deletions src/web/vaev-script/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ static Except<Boolean> _validateAndApplyPropertyDescriptor(Gc::Ptr<Object> self,
return Ok(true);

// c. If IsAccessorDescriptor(Desc) is true, then
// i. Create an own accessor property named P of object O whose [[Get]], [[Set]], [[Enumerable]], and [[Configurable]] attributes are set to the value of the corresponding field in Desc if Desc has that field, or to the attribute's default value otherwise.
// d. Else,
// i. Create an own data property named P of object O whose [[Value]], [[Writable]], [[Enumerable]], and [[Configurable]] attributes are set to the value of the corresponding field in Desc if Desc has that field, or to the attribute's default value otherwise.
if (desc.isAccessorDescriptor()) {
// i. Create an own accessor property named P of object O whose [[Get]], [[Set]], [[Enumerable]], and [[Configurable]] attributes are set to the value of the corresponding field in Desc if Desc has that field, or to the attribute's default value otherwise.
// d. Else,
} else {
// i. Create an own data property named P of object O whose [[Value]], [[Writable]], [[Enumerable]], and [[Configurable]] attributes are set to the value of the corresponding field in Desc if Desc has that field, or to the attribute's default value otherwise.
}
// e. Return true.
return Ok(true);
}
Expand All @@ -45,13 +48,22 @@ static Except<Boolean> _validateAndApplyPropertyDescriptor(Gc::Ptr<Object> self,
return Ok(false);

// c. If IsGenericDescriptor(Desc) is false and IsAccessorDescriptor(Desc) is not IsAccessorDescriptor(current), return false.
if (not desc.isGenericDescriptor() and desc.isAccessorDescriptor() != current->isAccessorDescriptor())
return Ok(false);

// d. If IsAccessorDescriptor(current) is true, then
// i. If Desc has a [[Get]] field and SameValue(Desc.[[Get]], current.[[Get]]) is false, return false.
// ii. If Desc has a [[Set]] field and SameValue(Desc.[[Set]], current.[[Set]]) is false, return false.
// e. Else if current.[[Writable]] is false, then
// i. If Desc has a [[Writable]] field and Desc.[[Writable]] is true, return false.
// ii. NOTE: SameValue returns true for NaN values which may be distinguishable by other means. Returning here ensures that any existing property of O remains unmodified.
// iii. If Desc has a [[Value]] field, return SameValue(Desc.[[Value]], current.[[Value]]).
if (current->isGenericDescriptor()) {

// i. If Desc has a [[Get]] field and SameValue(Desc.[[Get]], current.[[Get]]) is false, return false.
// ii. If Desc has a [[Set]] field and SameValue(Desc.[[Set]], current.[[Set]]) is false, return false.
// e. Else if current.[[Writable]] is false, then
} else if (current->writable == false) {
// i. If Desc has a [[Writable]] field and Desc.[[Writable]] is true, return false.
if (desc.writable != NONE and desc.writable == true)
return Ok(false);
// ii. NOTE: SameValue returns true for NaN values which may be distinguishable by other means. Returning here ensures that any existing property of O remains unmodified.
// iii. If Desc has a [[Value]] field, return SameValue(Desc.[[Value]], current.[[Value]]).
}
}

// 6. If O is not undefined, then
Expand Down Expand Up @@ -87,7 +99,7 @@ Except<Boolean> ordinaryDefineOwnProperty(Object& self, PropertyKey key, Propert
auto extensible = try$(self.isExtensible());

// 3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current).
return _validateAndApplyPropertyDescriptor(self, key, extensible, desc, current);
return _validateAndApplyPropertyDescriptor(&self, key, extensible, desc, current);
}

// https://tc39.es/ecma262/#sec-ordinaryget
Expand All @@ -108,7 +120,7 @@ Except<Value> ordinaryGet(Object& self, PropertyKey key, Value receiver) {
return parent->get(key, receiver);
}

auto& desc = maybeDesc.unwrap<PropertyDescriptor>();
auto& desc = maybeDesc.unwrap();

// 3. If IsDataDescriptor(desc) is true, return desc.[[Value]].
if (desc.isDataDescriptor())
Expand Down Expand Up @@ -156,7 +168,7 @@ Except<Boolean> Object::preventExtensions() {
return internalMethods.preventExtensions(*this);
}

Except<Union<PropertyDescriptor, Undefined>> Object::getOwnProperty(PropertyKey key) {
Except<Opt<PropertyDescriptor>> Object::getOwnProperty(PropertyKey key) {
if (not internalMethods.getOwnProperty)
return throwException(createException(agent, ExceptionType::TYPE_ERROR));
return internalMethods.getOwnProperty(*this, key);
Expand Down
4 changes: 2 additions & 2 deletions src/web/vaev-script/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct InternalMethods {
Except<Boolean> (*preventExtensions)(Object& self) = nullptr;

// https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getownproperty-p
Except<Union<PropertyDescriptor, Undefined>> (*getOwnProperty)(Object& self, PropertyKey key) = nullptr;
Except<Opt<PropertyDescriptor>> (*getOwnProperty)(Object& self, PropertyKey key) = nullptr;

// https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
Except<Boolean> (*defineOwnProperty)(Object& self, PropertyKey key, PropertyDescriptor desc) = ordinaryDefineOwnProperty;
Expand Down Expand Up @@ -83,7 +83,7 @@ struct Object {

Except<Boolean> preventExtensions();

Except<Union<PropertyDescriptor, Undefined>> getOwnProperty(PropertyKey key);
Except<Opt<PropertyDescriptor>> getOwnProperty(PropertyKey key);

Except<Boolean> defineOwnProperty(PropertyKey key, PropertyDescriptor desc);

Expand Down
43 changes: 43 additions & 0 deletions src/web/vaev-script/ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,34 @@ namespace Vaev::Script {

// MARK: Type Conversion -------------------------------------------------------

// https://tc39.es/ecma262/#sec-ordinarytoprimitive
Except<Value> ordinaryToPrimitive(Object& o, PreferedType hint) {
Array methodNames = {
u"toString"_s16,
u"valueOf"_s16,
};
// 1. If hint is string, then
if (hint == PreferedType::STRING) {
// a. Let methodNames be « "toString", "valueOf" ».
methodNames = {
u"toString"_s16,
u"valueOf"_s16,
};
}
// 2. Else,
// a. Let methodNames be « "valueOf", "toString" ».

// 3. For each element name of methodNames, do
for (auto name : methodNames) {
// a. Let method be ? Get(O, name).
// b. If IsCallable(method) is true, then
// i. Let result be ? Call(method, O).
// ii. If result is not an Object, return result.
}
// 4. Throw a TypeError exception.
return throwException(createException(o.agent, ExceptionType::TYPE_ERROR));
}

// MARK: Testing and Comparison Operations -------------------------------------

// https://tc39.es/ecma262/#sec-iscallable
Expand All @@ -18,11 +46,26 @@ bool isCallable(Value v) {
return false;

// 2. If argument has a [[Call]] internal method, return true.
if (v.asObject()->internalMethods.call)
return true;

// 3. Return false.
return false;
}

// https://tc39.es/ecma262/#sec-samevalue
bool sameValue(Value x, Value y) {
// 1. If SameType(x, y) is false, return false.
if (not sameType(x, y))
return false;

// 2. If x is a Number, then
// a. Return Number::sameValue(x, y).

// 3. Return SameValueNonNumber(x, y).
return sameValueNonNumber(x, y);
}

// MARK: Operations on Objects -------------------------------------------------

// https://tc39.es/ecma262/#sec-call
Expand Down
18 changes: 16 additions & 2 deletions src/web/vaev-script/ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ namespace Vaev::Script {

// MARK: Type Conversion -------------------------------------------------------

// https://tc39.es/ecma262/#sec-toprimitive
enum struct PreferedType {
DEFALT,
STRING,
NUMBER,
};
Except<Value> toPrimitive(Value v, PreferedType preferredType = PreferedType::DEFALT);

// https://tc39.es/ecma262/#sec-ordinarytoprimitive
Except<Value> ordinaryToPrimitive(Object& o, PreferedType hint = PreferedType::DEFALT);

// MARK: Testing and Comparison Operations -------------------------------------

// https://tc39.es/ecma262/#sec-iscallable
bool isCallable(Value v);

// https://tc39.es/ecma262/#sec-samevalue
bool sameValue(Value x, Value y);

// MARK: Operations on Objects -------------------------------------------------

// https://tc39.es/ecma262/#sec-call
Except<Value> call(Agent &agent, Value f, Value v, Slice<Value> args = {});
Except<Value> call(Agent& agent, Value f, Value v, Slice<Value> args = {});

// MARK: Operations on Iterator Objects ----------------------------------------

Expand All @@ -36,7 +50,7 @@ enum struct ExceptionType {
_LEN,
};

Gc::Ref<Object> createException(Agent &agent, ExceptionType type);
Gc::Ref<Object> createException(Agent& agent, ExceptionType type);

// https://tc39.es/ecma262/#sec-throw-an-exception
Completion throwException(Value exception);
Expand Down
13 changes: 13 additions & 0 deletions src/web/vaev-script/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ struct PropertyDescriptor {
// 4. Return false.
return false;
}

// https://tc39.es/ecma262/#sec-isgenericdescriptor
bool isGenericDescriptor() const {
// 1. If Desc is undefined, return false.

// 2. If IsAccessorDescriptor(Desc) is true, return false.
// 3. If IsDataDescriptor(Desc) is true, return false.
if (isAccessorDescriptor() or isDataDescriptor())
return false;

// 4. Return true.
return true;
}
};

struct PropertyStorage {
Expand Down
93 changes: 93 additions & 0 deletions src/web/vaev-script/value.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <karm-math/funcs.h>

#include "value.h"

namespace Vaev::Script {

// MARK: Numeric Types ---------------------------------------------------------
// https://tc39.es/ecma262/#sec-ecmascript-language-types-number-type

// https://tc39.es/ecma262/#sec-numeric-types-number-unaryMinus
Number Number::unaryMinus() {
if (Math::isNan(_val))
return Math::NAN;
return -_val;
}

// https://tc39.es/ecma262/#sec-numeric-types-number-bitwiseNOT
Number Number::bitwiseNot() {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-exponentiate
Number Number::exponentiate(Number exp) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-multiply
Number Number::multiply(Number multiplicand) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-divide
Number Number::divide(Number divisor) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-remainder
Number Number::remainder(Number divisor) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-add
Number Number::add(Number augend) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-subtract
Number Number::subtract(Number subtrahend) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-leftShift
Number Number::leftShift(Number shiftCount) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-signedRightShift
Number Number::signedRightShift(Number shiftCount) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-unsignedRightShift
Number Number::unsignedRightShift(Number shiftCount) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-lessThan
Boolean Number::lessThan(Number y) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-equal
Boolean Number::equal(Number y) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-sameValue
Boolean Number::sameValue(Number y) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-sameValueZero
Boolean Number::sameValueZero(Number y) {
}

// https://tc39.es/ecma262/#sec-numberbitwiseop
Number Number::bitwiseOp(Number y, f64 op) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-bitwiseAND
Number Number::bitwiseAnd(Number y) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-bitwiseXOR
Number Number::bitwiseXor(Number y) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-bitwiseOR
Number Number::bitwiseOr(Number y) {
}

// https://tc39.es/ecma262/#sec-numeric-types-number-tostring
String Number::toString() {
}

} // namespace Vaev::Script
Loading

0 comments on commit e04a7ac

Please sign in to comment.