move JSON and parsing logic to compiler project, decouple JSON and parser from engine logic
This commit is contained in:
86
repl/src/main/java/me/topchetoeu/j2s/repl/JSONConverter.java
Normal file
86
repl/src/main/java/me/topchetoeu/j2s/repl/JSONConverter.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package me.topchetoeu.j2s.repl;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONElement;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONList;
|
||||
import me.topchetoeu.j2s.compilation.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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,14 +16,16 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import me.topchetoeu.j2s.common.Filename;
|
||||
import me.topchetoeu.j2s.common.Metadata;
|
||||
import me.topchetoeu.j2s.common.Reading;
|
||||
import me.topchetoeu.j2s.common.SyntaxException;
|
||||
import me.topchetoeu.j2s.common.environment.Environment;
|
||||
import me.topchetoeu.j2s.common.environment.Key;
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.parsing.Filename;
|
||||
import me.topchetoeu.j2s.compilation.JavaScript;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.parsing.Parsing;
|
||||
import me.topchetoeu.j2s.compilation.parsing.Source;
|
||||
import me.topchetoeu.j2s.repl.debug.DebugServer;
|
||||
import me.topchetoeu.j2s.repl.debug.Debugger;
|
||||
import me.topchetoeu.j2s.repl.debug.SimpleDebugger;
|
||||
@@ -33,7 +35,6 @@ import me.topchetoeu.j2s.runtime.Compiler;
|
||||
import me.topchetoeu.j2s.runtime.Engine;
|
||||
import me.topchetoeu.j2s.runtime.EventLoop;
|
||||
import me.topchetoeu.j2s.runtime.Frame;
|
||||
import me.topchetoeu.j2s.runtime.JSONConverter;
|
||||
import me.topchetoeu.j2s.runtime.debug.DebugContext;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
@@ -385,13 +386,29 @@ public class SimpleRepl {
|
||||
if (num.isInt()) return num;
|
||||
else return NumberValue.of(num.getDouble() - num.getDouble() % 1);
|
||||
}
|
||||
else return NumberValue.parseInt(args.get(0).toString(), radix, false);
|
||||
else {
|
||||
if (radix < 2 || radix > 36) return NumberValue.NAN;
|
||||
|
||||
var str = args.get(0).toString().trim();
|
||||
var numRes = Parsing.parseInt(new Source(str), 0, "0123456789abcdefghijklmnopqrstuvwxyz".substring(0, radix), true);
|
||||
if (numRes.isSuccess()) {
|
||||
if (numRes.n == str.length()) return NumberValue.of(numRes.result);
|
||||
}
|
||||
return NumberValue.NAN;
|
||||
}
|
||||
}));
|
||||
res.defineOwnField(env, "parseFloat", new NativeFunction(args -> {
|
||||
if (args.get(0) instanceof NumberValue) {
|
||||
return args.get(0);
|
||||
}
|
||||
else return NumberValue.parseFloat(args.get(0).toString(), false);
|
||||
else {
|
||||
var str = args.get(0).toString().trim();
|
||||
var numRes = Parsing.parseFloat(new Source(str), 0, true);
|
||||
if (numRes.isSuccess()) {
|
||||
if (numRes.n == str.length()) return NumberValue.of(numRes.result);
|
||||
}
|
||||
return NumberValue.NAN;
|
||||
}
|
||||
}));
|
||||
res.defineOwnField(env, "isNaN", new NativeFunction(args -> BoolValue.of(args.get(0).isNaN())));
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.topchetoeu.j2s.repl;
|
||||
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONMap;
|
||||
|
||||
public class V8Error {
|
||||
public final String message;
|
||||
|
||||
@@ -12,9 +12,9 @@ import java.util.HashMap;
|
||||
import me.topchetoeu.j2s.common.Metadata;
|
||||
import me.topchetoeu.j2s.common.Reading;
|
||||
import me.topchetoeu.j2s.common.SyntaxException;
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONList;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONList;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONMap;
|
||||
import me.topchetoeu.j2s.repl.debug.WebSocketMessage.Type;
|
||||
|
||||
public class DebugServer {
|
||||
|
||||
@@ -11,25 +11,25 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.topchetoeu.j2s.common.Filename;
|
||||
import me.topchetoeu.j2s.common.FunctionBody;
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.Metadata;
|
||||
import me.topchetoeu.j2s.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.j2s.common.Instruction.Type;
|
||||
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.json.JSONList;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.common.mapping.FunctionMap;
|
||||
import me.topchetoeu.j2s.common.parsing.Filename;
|
||||
import me.topchetoeu.j2s.common.parsing.Location;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONElement;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONList;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONMap;
|
||||
import me.topchetoeu.j2s.repl.JSONConverter;
|
||||
import me.topchetoeu.j2s.repl.SimpleRepl;
|
||||
import me.topchetoeu.j2s.runtime.Compiler;
|
||||
import me.topchetoeu.j2s.runtime.Engine;
|
||||
import me.topchetoeu.j2s.runtime.EventLoop;
|
||||
import me.topchetoeu.j2s.runtime.Frame;
|
||||
import me.topchetoeu.j2s.runtime.JSONConverter;
|
||||
import me.topchetoeu.j2s.runtime.debug.DebugContext;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.topchetoeu.j2s.repl.debug;
|
||||
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONMap;
|
||||
|
||||
public class V8Error {
|
||||
public final String message;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.topchetoeu.j2s.repl.debug;
|
||||
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONMap;
|
||||
|
||||
public class V8Event {
|
||||
public final String name;
|
||||
|
||||
@@ -2,9 +2,9 @@ package me.topchetoeu.j2s.repl.debug;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONElement;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONElement;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONMap;
|
||||
|
||||
public class V8Message {
|
||||
public final String name;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package me.topchetoeu.j2s.repl.debug;
|
||||
|
||||
import me.topchetoeu.j2s.common.json.JSON;
|
||||
import me.topchetoeu.j2s.common.json.JSONMap;
|
||||
import me.topchetoeu.j2s.compilation.json.JSON;
|
||||
import me.topchetoeu.j2s.compilation.json.JSONMap;
|
||||
|
||||
public class V8Result {
|
||||
public final int id;
|
||||
|
||||
@@ -2,9 +2,9 @@ package me.topchetoeu.j2s.repl.mapping;
|
||||
|
||||
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.parsing.Filename;
|
||||
import me.topchetoeu.j2s.common.parsing.Location;
|
||||
import me.topchetoeu.j2s.runtime.exceptions.EngineException;
|
||||
import me.topchetoeu.j2s.runtime.values.Value;
|
||||
import me.topchetoeu.j2s.runtime.values.functions.FunctionValue;
|
||||
|
||||
Reference in New Issue
Block a user