Try-catch fix for interruptible code #2

Merged
TopchetoEU merged 5 commits from TopchetoEU/fix-try-catch into master 2023-08-25 14:07:32 +00:00
5 changed files with 60 additions and 28 deletions
Showing only changes of commit bef35ebb1b - Show all commits

View File

@@ -54,7 +54,7 @@ public class Main {
public static void main(String args[]) { public static void main(String args[]) {
var in = new BufferedReader(new InputStreamReader(System.in)); var in = new BufferedReader(new InputStreamReader(System.in));
engine = new PolyfillEngine(new File(".")); engine = new TypescriptEngine(new File("."));
var scope = engine.global().globalChild(); var scope = engine.global().globalChild();
var exited = new boolean[1]; var exited = new boolean[1];

View File

@@ -2,7 +2,7 @@
var ts = require('./ts__'); var ts = require('./ts__');
log("Loaded typescript!"); log("Loaded typescript!");
var src = '', lib = libs.join(''), decls = '', version = 0; var src = '', lib = libs.concat([ 'declare const exit: never;' ]).join(''), decls = '', version = 0;
var libSnapshot = ts.ScriptSnapshot.fromString(lib); var libSnapshot = ts.ScriptSnapshot.fromString(lib);
var settings = { var settings = {

View File

@@ -10,31 +10,17 @@ import me.topchetoeu.jscript.parsing.Token;
public class JSON { public class JSON {
public static ParseRes<String> parseIdentifier(List<Token> tokens, int i) { public static ParseRes<String> parseIdentifier(List<Token> tokens, int i) {
try { return Parsing.parseIdentifier(tokens, i);
if (tokens.get(i).isIdentifier()) return ParseRes.res(tokens.get(i).identifier(), 1);
else return ParseRes.failed();
}
catch (IndexOutOfBoundsException e) {
return ParseRes.failed();
}
} }
public static ParseRes<String> parseString(String filename, List<Token> tokens, int i) { public static ParseRes<String> parseString(String filename, List<Token> tokens, int i) {
try { var res = Parsing.parseString(filename, tokens, i);
if (tokens.get(i).isString()) return ParseRes.res(tokens.get(i).string(), 1); if (res.isSuccess()) return ParseRes.res((String)res.result.value, res.n);
else return ParseRes.failed(); else return res.transform();
}
catch (IndexOutOfBoundsException e) {
return ParseRes.failed();
}
} }
public static ParseRes<Double> parseNumber(String filename, List<Token> tokens, int i) { public static ParseRes<Double> parseNumber(String filename, List<Token> tokens, int i) {
try { var res = Parsing.parseNumber(filename, tokens, i);
if (tokens.get(i).isNumber()) return ParseRes.res(tokens.get(i).number(), 1); if (res.isSuccess()) return ParseRes.res((Double)res.result.value, res.n);
else return ParseRes.failed(); else return res.transform();
}
catch (IndexOutOfBoundsException e) {
return ParseRes.failed();
}
} }
public static ParseRes<Boolean> parseBool(String filename, List<Token> tokens, int i) { public static ParseRes<Boolean> parseBool(String filename, List<Token> tokens, int i) {
var id = parseIdentifier(tokens, i); var id = parseIdentifier(tokens, i);

View File

@@ -10,7 +10,7 @@ public class JSONElement {
MAP, MAP,
} }
public static JSONElement NULL = new JSONElement(Type.NULL, null); public static final JSONElement NULL = new JSONElement(Type.NULL, null);
public static JSONElement map(JSONMap val) { public static JSONElement map(JSONMap val) {
return new JSONElement(Type.MAP, val); return new JSONElement(Type.MAP, val);

View File

@@ -1,5 +1,7 @@
package me.topchetoeu.jscript.polyfills; package me.topchetoeu.jscript.polyfills;
import java.util.HashSet;
import me.topchetoeu.jscript.engine.CallContext; import me.topchetoeu.jscript.engine.CallContext;
import me.topchetoeu.jscript.engine.values.ArrayValue; import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.ObjectValue; import me.topchetoeu.jscript.engine.values.ObjectValue;
@@ -8,31 +10,75 @@ import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.exceptions.SyntaxException; import me.topchetoeu.jscript.exceptions.SyntaxException;
import me.topchetoeu.jscript.interop.Native; import me.topchetoeu.jscript.interop.Native;
import me.topchetoeu.jscript.json.JSONElement; import me.topchetoeu.jscript.json.JSONElement;
import me.topchetoeu.jscript.json.JSONList;
import me.topchetoeu.jscript.json.JSONMap;
public class JSON { public class JSON {
private static Object convert(JSONElement val) { private static Object toJS(JSONElement val) {
if (val.isBoolean()) return val.bool(); if (val.isBoolean()) return val.bool();
if (val.isString()) return val.string(); if (val.isString()) return val.string();
if (val.isNumber()) return val.number(); if (val.isNumber()) return val.number();
if (val.isList()) return ArrayValue.of(val.list().stream().map(JSON::convert).toList()); if (val.isList()) return ArrayValue.of(val.list().stream().map(JSON::toJS).toList());
if (val.isMap()) { if (val.isMap()) {
var res = new ObjectValue(); var res = new ObjectValue();
for (var el : val.map().entrySet()) { for (var el : val.map().entrySet()) {
res.defineProperty(el.getKey(), convert(el.getValue())); res.defineProperty(el.getKey(), toJS(el.getValue()));
} }
return res; return res;
} }
if (val.isNull()) return Values.NULL; if (val.isNull()) return Values.NULL;
return null; return null;
} }
private static JSONElement toJSON(CallContext ctx, Object val, HashSet<Object> prev) throws InterruptedException {
if (val instanceof Boolean) return JSONElement.bool((boolean)val);
if (val instanceof Number) return JSONElement.number(((Number)val).doubleValue());
if (val instanceof String) return JSONElement.string((String)val);
if (val == Values.NULL) return JSONElement.NULL;
if (val instanceof ObjectValue) {
if (prev.contains(val)) throw new EngineException("Circular dependency in JSON.");
prev.add(val);
var res = new JSONMap();
for (var el : ((ObjectValue)val).keys(false)) {
var jsonEl = toJSON(ctx, ((ObjectValue)val).getMember(ctx, el), prev);
if (jsonEl == null) continue;
if (el instanceof String || el instanceof Number) res.put(el.toString(), jsonEl);
}
prev.remove(val);
return JSONElement.of(res);
}
if (val instanceof ArrayValue) {
if (prev.contains(val)) throw new EngineException("Circular dependency in JSON.");
prev.add(val);
var res = new JSONList();
for (var el : ((ArrayValue)val).toArray()) {
var jsonEl = toJSON(ctx, el, prev);
if (jsonEl == null) jsonEl = JSONElement.NULL;
res.add(jsonEl);
}
prev.remove(val);
return JSONElement.of(res);
}
if (val == null) return null;
return null;
}
@Native @Native
public static Object parse(CallContext ctx, String val) throws InterruptedException { public static Object parse(CallContext ctx, String val) throws InterruptedException {
try { try {
return convert(me.topchetoeu.jscript.json.JSON.parse("<value>", val)); return toJS(me.topchetoeu.jscript.json.JSON.parse("<value>", val));
} }
catch (SyntaxException e) { catch (SyntaxException e) {
throw EngineException.ofSyntax(e.msg); throw EngineException.ofSyntax(e.msg);
} }
} }
@Native
public static String stringify(CallContext ctx, Object val) throws InterruptedException {
return me.topchetoeu.jscript.json.JSON.stringify(toJSON(ctx, val, new HashSet<>()));
}
} }