move JSON and parsing logic to compiler project, decouple JSON and parser from engine logic

This commit is contained in:
2025-01-12 04:27:43 +02:00
parent a115843351
commit cacffd01e8
89 changed files with 495 additions and 370 deletions

View 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;
}
}

View File

@@ -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())));

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;