move JSON and parsing logic to compiler project, decouple JSON and parser from engine logic
This commit is contained in:
@@ -2,10 +2,10 @@ package me.topchetoeu.j2s.runtime;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.topchetoeu.j2s.common.Filename;
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.environment.Key;
|
||||
import me.topchetoeu.j2s.common.parsing.Filename;
|
||||
import me.topchetoeu.j2s.common.parsing.Location;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.functions.FunctionValue;
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ package me.topchetoeu.j2s.runtime;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import me.topchetoeu.j2s.common.Filename;
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.environment.Key;
|
||||
import me.topchetoeu.j2s.common.parsing.Filename;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
import me.topchetoeu.j2s.runtime.values.functions.FunctionValue;
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
package me.topchetoeu.j2s.runtime;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.json.JSONElement;
|
||||
import me.topchetoeu.j2s.common.json.JSONList;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
import me.topchetoeu.j2s.runtime.values.objects.ArrayValue;
|
||||
import me.topchetoeu.j2s.runtime.values.objects.ObjectValue;
|
||||
import me.topchetoeu.j2s.runtime.values.primitives.BoolValue;
|
||||
import me.topchetoeu.j2s.runtime.values.primitives.StringValue;
|
||||
import me.topchetoeu.j2s.runtime.values.primitives.VoidValue;
|
||||
import me.topchetoeu.j2s.runtime.values.primitives.numbers.NumberValue;
|
||||
|
||||
public class JSONConverter {
|
||||
public static Value toJs(JSONElement val) {
|
||||
if (val.isBoolean()) return BoolValue.of(val.bool());
|
||||
if (val.isString()) return StringValue.of(val.string());
|
||||
if (val.isNumber()) return NumberValue.of(val.number());
|
||||
if (val.isList()) return ArrayValue.of(val.list().stream().map(JSONConverter::toJs).collect(Collectors.toList()));
|
||||
if (val.isMap()) {
|
||||
var res = new ObjectValue();
|
||||
|
||||
for (var el : val.map().entrySet()) {
|
||||
res.defineOwnField(null, el.getKey(), toJs(el.getValue()));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
if (val.isNull()) return Value.NULL;
|
||||
return Value.UNDEFINED;
|
||||
}
|
||||
|
||||
public static JSONElement fromJs(Environment ext, Value val) {
|
||||
var res = JSONConverter.fromJs(ext, val, new HashSet<>());
|
||||
if (res == null) return JSONElement.NULL;
|
||||
else return res;
|
||||
}
|
||||
|
||||
public static JSONElement fromJs(Environment env, Value val, HashSet<Object> prev) {
|
||||
if (val instanceof BoolValue) return JSONElement.bool(((BoolValue)val).value);
|
||||
if (val instanceof NumberValue) return JSONElement.number(((NumberValue)val).getDouble());
|
||||
if (val instanceof StringValue) return JSONElement.string(((StringValue)val).value);
|
||||
if (val == Value.NULL) return JSONElement.NULL;
|
||||
if (val instanceof VoidValue) return null;
|
||||
|
||||
if (val instanceof ArrayValue) {
|
||||
if (prev.contains(val)) throw EngineException.ofError("Circular dependency in JSON.");
|
||||
prev.add(val);
|
||||
|
||||
var res = new JSONList();
|
||||
|
||||
for (var el : ((ArrayValue)val).toArray()) {
|
||||
var jsonEl = fromJs(env, el, prev);
|
||||
if (jsonEl == null) continue;
|
||||
res.add(jsonEl);
|
||||
}
|
||||
|
||||
prev.remove(val);
|
||||
return JSONElement.of(res);
|
||||
}
|
||||
if (val instanceof ObjectValue) {
|
||||
if (prev.contains(val)) throw EngineException.ofError("Circular dependency in JSON.");
|
||||
prev.add(val);
|
||||
|
||||
var res = new JSONMap();
|
||||
|
||||
for (var key : val.getOwnMembers(env, true)) {
|
||||
var el = fromJs(env, val.getMember(env, key), prev);
|
||||
if (el == null) continue;
|
||||
|
||||
res.put(key, el);
|
||||
}
|
||||
|
||||
prev.remove(val);
|
||||
return JSONElement.of(res);
|
||||
}
|
||||
if (val == null) return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,12 +3,12 @@ package me.topchetoeu.j2s.runtime.debug;
|
||||
import java.util.HashMap;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import me.topchetoeu.j2s.common.Filename;
|
||||
import me.topchetoeu.j2s.common.FunctionBody;
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.environment.Key;
|
||||
import me.topchetoeu.j2s.common.mapping.FunctionMap;
|
||||
import me.topchetoeu.j2s.common.parsing.Filename;
|
||||
import me.topchetoeu.j2s.runtime.Frame;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package me.topchetoeu.j2s.runtime.debug;
|
||||
|
||||
import me.topchetoeu.j2s.common.Filename;
|
||||
import me.topchetoeu.j2s.common.FunctionBody;
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.mapping.FunctionMap;
|
||||
import me.topchetoeu.j2s.common.parsing.Filename;
|
||||
import me.topchetoeu.j2s.runtime.Frame;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
|
||||
@@ -3,8 +3,8 @@ package me.topchetoeu.j2s.runtime.exceptions;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.parsing.Location;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
import me.topchetoeu.j2s.runtime.values.objects.ObjectValue;
|
||||
import me.topchetoeu.j2s.runtime.values.objects.ObjectValue.PrototypeProvider;
|
||||
|
||||
@@ -7,11 +7,8 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import me.topchetoeu.j2s.common.StringifyUtils;
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONElement;
|
||||
import me.topchetoeu.j2s.common.parsing.Parsing;
|
||||
import me.topchetoeu.j2s.common.parsing.Source;
|
||||
import me.topchetoeu.j2s.runtime.values.KeyCache;
|
||||
import me.topchetoeu.j2s.runtime.values.Member;
|
||||
import me.topchetoeu.j2s.runtime.values.Member.FieldMember;
|
||||
@@ -29,10 +26,7 @@ public final class StringValue extends PrimitiveValue {
|
||||
@Override public NumberValue toNumber(Environment ext) {
|
||||
var val = value.trim();
|
||||
if (val.equals("")) return NumberValue.of(0);
|
||||
var res = Parsing.parseNumber(new Source(val), 0, true);
|
||||
|
||||
if (res.isSuccess() && res.n == val.length()) return NumberValue.of(res.result);
|
||||
else return NumberValue.NAN;
|
||||
return NumberValue.of(StringifyUtils.unqoteNumber(val));
|
||||
}
|
||||
@Override public String toString(Environment ext) { return value; }
|
||||
|
||||
@@ -79,7 +73,7 @@ public final class StringValue extends PrimitiveValue {
|
||||
}
|
||||
|
||||
@Override public List<String> toReadableLines(Environment env, HashSet<ObjectValue> passed) {
|
||||
return Arrays.asList(JSON.stringify(JSONElement.string(value)));
|
||||
return Arrays.asList(StringifyUtils.quoteString(value));
|
||||
}
|
||||
|
||||
private StringValue(String value) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package me.topchetoeu.j2s.runtime.values.primitives.numbers;
|
||||
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONElement;
|
||||
import me.topchetoeu.j2s.common.StringifyUtils;
|
||||
|
||||
public final class DoubleValue extends NumberValue {
|
||||
public final double value;
|
||||
@@ -22,7 +21,7 @@ public final class DoubleValue extends NumberValue {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override public String toString() { return JSON.stringify(JSONElement.number(value)); }
|
||||
@Override public String toString() { return StringifyUtils.quoteNumber(value); }
|
||||
|
||||
@Override public int hashCode() {
|
||||
return Double.hashCode(value);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package me.topchetoeu.j2s.runtime.values.primitives.numbers;
|
||||
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.parsing.Parsing;
|
||||
import me.topchetoeu.j2s.common.parsing.Source;
|
||||
import me.topchetoeu.j2s.runtime.values.objects.ObjectValue;
|
||||
import me.topchetoeu.j2s.runtime.values.primitives.PrimitiveValue;
|
||||
import me.topchetoeu.j2s.runtime.values.primitives.StringValue;
|
||||
@@ -31,25 +29,6 @@ public abstract class NumberValue extends PrimitiveValue {
|
||||
return env.get(NUMBER_PROTO);
|
||||
}
|
||||
|
||||
public static NumberValue parseInt(String str, int radix, boolean relaxed) {
|
||||
if (radix < 2 || radix > 36) return NumberValue.NAN;
|
||||
|
||||
str = str.trim();
|
||||
var res = Parsing.parseInt(new Source(str), 0, "0123456789abcdefghijklmnopqrstuvwxyz".substring(0, radix), true);
|
||||
if (res.isSuccess()) {
|
||||
if (relaxed || res.n == str.length()) return of(res.result);
|
||||
}
|
||||
return NumberValue.NAN;
|
||||
}
|
||||
public static NumberValue parseFloat(String str, boolean relaxed) {
|
||||
str = str.trim();
|
||||
var res = Parsing.parseFloat(new Source(str), 0, true);
|
||||
if (res.isSuccess()) {
|
||||
if (relaxed || res.n == str.length()) return of(res.result);
|
||||
}
|
||||
return NumberValue.NAN;
|
||||
}
|
||||
|
||||
public static NumberValue of(double value) {
|
||||
if (Double.isNaN(value)) return NAN;
|
||||
else if ((int)value == value) return new IntValue((int)value);
|
||||
|
||||
Reference in New Issue
Block a user