From 3f5e1a5fd875ad068f1d90ca1d16c99373bcc31e Mon Sep 17 00:00:00 2001 From: TopchetoEU <36534413+TopchetoEU@users.noreply.github.com> Date: Mon, 9 Dec 2024 23:38:53 +0200 Subject: [PATCH] feat: implement user values --- .../runtime/values/functions/Arguments.java | 6 ++ .../runtime/values/primitives/UserValue.java | 69 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/main/java/me/topchetoeu/jscript/runtime/values/primitives/UserValue.java diff --git a/src/main/java/me/topchetoeu/jscript/runtime/values/functions/Arguments.java b/src/main/java/me/topchetoeu/jscript/runtime/values/functions/Arguments.java index 1a7f276..7b280c4 100644 --- a/src/main/java/me/topchetoeu/jscript/runtime/values/functions/Arguments.java +++ b/src/main/java/me/topchetoeu/jscript/runtime/values/functions/Arguments.java @@ -3,6 +3,7 @@ package me.topchetoeu.jscript.runtime.values.functions; import me.topchetoeu.jscript.common.environment.Environment; import me.topchetoeu.jscript.runtime.values.Value; +import me.topchetoeu.jscript.runtime.values.primitives.UserValue; public class Arguments { public final Value self; @@ -21,6 +22,11 @@ public class Arguments { public Value self() { return get(-1); } + @SuppressWarnings("unchecked") + public T self(Class clazz) { + if (self instanceof UserValue user && clazz.isInstance(user.value)) return (T)user.value; + else return null; + } public Value get(int i) { if (i >= args.length || i < -1) return Value.UNDEFINED; else if (i == -1) return self; diff --git a/src/main/java/me/topchetoeu/jscript/runtime/values/primitives/UserValue.java b/src/main/java/me/topchetoeu/jscript/runtime/values/primitives/UserValue.java new file mode 100644 index 0000000..33985d8 --- /dev/null +++ b/src/main/java/me/topchetoeu/jscript/runtime/values/primitives/UserValue.java @@ -0,0 +1,69 @@ +package me.topchetoeu.jscript.runtime.values.primitives; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import me.topchetoeu.jscript.common.environment.Environment; +import me.topchetoeu.jscript.runtime.values.KeyCache; +import me.topchetoeu.jscript.runtime.values.Member; +import me.topchetoeu.jscript.runtime.values.Value; +import me.topchetoeu.jscript.runtime.values.objects.ObjectValue; +import me.topchetoeu.jscript.runtime.values.primitives.numbers.NumberValue; + +public final class UserValue extends Value { + public final T value; + public final ObjectValue prototype; + + @Override public StringValue type() { return StringValue.of("object"); } + + @Override public boolean toBoolean() { return true; } + @Override public NumberValue toNumber(Environment ext) { return NumberValue.NAN; } + @Override public String toString(Environment ext) { return "[user value]"; } + + @Override public final boolean defineOwnMember(Environment env, KeyCache key, Member member) { return false; } + @Override public final boolean deleteOwnMember(Environment env, KeyCache key) { return false; } + @Override public final boolean isPrimitive() { return false; } + @Override public final Value toPrimitive(Environment env) { return NumberValue.NAN; } + + @Override public final boolean setPrototype(Environment env, ObjectValue val) { return false; } + + @Override public Member getOwnMember(Environment env, KeyCache key) { return null; } + @Override public Set getOwnMembers(Environment env, boolean onlyEnumerable) { return new HashSet<>(); } + @Override public Set getOwnSymbolMembers(Environment env, boolean onlyEnumerable) { return new HashSet<>(); } + + @Override public State getState() { return State.FROZEN; } + + @Override public void preventExtensions() {} + @Override public void seal() {} + @Override public void freeze() {} + + @Override public int hashCode() { + return value.hashCode(); + } + @Override public boolean equals(Object other) { + if (this == other) return true; + else if (other instanceof UserValue val) return Objects.equals(value, val.value); + else return false; + } + + @Override public ObjectValue getPrototype(Environment env) { return prototype; } + + @Override public List toReadableLines(Environment env, HashSet passed) { + return Arrays.asList(value.toString()); + } + + private UserValue(T value, ObjectValue prototype) { + this.value = value; + this.prototype = prototype; + } + + public static UserValue of(T value) { + return new UserValue(value, null); + } + public static UserValue of(T value, ObjectValue prototype) { + return new UserValue(value, prototype); + } +}