Core library reprogramming #5

Merged
TopchetoEU merged 23 commits from TopchetoEU/corelib-reprogramming into master 2023-10-04 05:50:26 +00:00
7 changed files with 87 additions and 11 deletions
Showing only changes of commit 6c7fe6deaf - Show all commits

View File

@ -102,7 +102,7 @@ public class Main {
var raw = in.readLine(); var raw = in.readLine();
if (raw == null) break; if (raw == null) break;
engine.pushMsg(false, new Context(env, new Message(engine)), "<stdio>", raw, null).toObservable().once(valuePrinter); engine.pushMsg(false, env.context(new Message(engine)), "<stdio>", raw, null).toObservable().once(valuePrinter);
} }
catch (EngineException e) { catch (EngineException e) {
try { try {

View File

@ -0,0 +1,58 @@
package me.topchetoeu.jscript.engine;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
@SuppressWarnings("unchecked")
public class Data implements Iterable<Entry<DataKey<?>, ?>> {
private HashMap<DataKey<Object>, Object> data = new HashMap<>();
public Data copy() {
return new Data().addAll(this);
}
public Data addAll(Iterable<Entry<DataKey<?>, ?>> data) {
for (var el : data) {
add((DataKey<Object>)el.getKey(), (Object)el.getValue());
}
return this;
}
public <T> Data set(DataKey<T> key, T val) {
if (val == null) data.remove(key);
else data.put((DataKey<Object>)key, (Object)val);
return this;
}
public <T> T add(DataKey<T> key, T val) {
if (data.containsKey(key)) return (T)data.get(key);
else {
if (val == null) data.remove(key);
else data.put((DataKey<Object>)key, (Object)val);
return val;
}
}
public <T> T get(DataKey<T> key) {
return get(key, null);
}
public <T> T get(DataKey<T> key, T defaultVal) {
if (!has(key)) return defaultVal;
else return (T)data.get(key);
}
public boolean has(DataKey<?> key) { return data.containsKey(key); }
public Data increase(DataKey<Integer> key, int n, int start) {
return set(key, get(key, start) + n);
}
public Data increase(DataKey<Integer> key, int n) {
return increase(key, n, 0);
}
public Data increase(DataKey<Integer> key) {
return increase(key, 1, 0);
}
@Override
public Iterator<Entry<DataKey<?>, ?>> iterator() {
return (Iterator<Entry<DataKey<?>, ?>>)data.entrySet();
}
}

View File

@ -0,0 +1,3 @@
package me.topchetoeu.jscript.engine;
public class DataKey<T> { }

View File

@ -11,19 +11,19 @@ public class Engine {
private class UncompiledFunction extends FunctionValue { private class UncompiledFunction extends FunctionValue {
public final String filename; public final String filename;
public final String raw; public final String raw;
public final Environment ctx; public final Environment env;
@Override @Override
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
ctx = new Context(this.ctx, ctx.message); ctx = ctx.setEnv(env);
return ctx.compile(filename, raw).call(ctx, thisArg, args); return ctx.compile(filename, raw).call(ctx, thisArg, args);
} }
public UncompiledFunction(Environment ctx, String filename, String raw) { public UncompiledFunction(Environment env, String filename, String raw) {
super(filename, 0); super(filename, 0);
this.filename = filename; this.filename = filename;
this.raw = raw; this.raw = raw;
this.ctx = ctx; this.env = env;
} }
} }
@ -32,10 +32,10 @@ public class Engine {
public final Object thisArg; public final Object thisArg;
public final Object[] args; public final Object[] args;
public final DataNotifier<Object> notifier = new DataNotifier<>(); public final DataNotifier<Object> notifier = new DataNotifier<>();
public final Message ctx; public final Message msg;
public Task(Message ctx, FunctionValue func, Object thisArg, Object[] args) { public Task(Message ctx, FunctionValue func, Object thisArg, Object[] args) {
this.ctx = ctx; this.msg = ctx;
this.func = func; this.func = func;
this.thisArg = thisArg; this.thisArg = thisArg;
this.args = args; this.args = args;
@ -52,7 +52,7 @@ public class Engine {
private void runTask(Task task) throws InterruptedException { private void runTask(Task task) throws InterruptedException {
try { try {
task.notifier.next(task.func.call(new Context(null, task.ctx), task.thisArg, task.args)); task.notifier.next(task.func.call(task.msg.context(null), task.thisArg, task.args));
} }
catch (InterruptedException e) { catch (InterruptedException e) {
task.notifier.error(new RuntimeException(e)); task.notifier.error(new RuntimeException(e));

View File

@ -15,15 +15,23 @@ import me.topchetoeu.jscript.interop.NativeWrapperProvider;
public class Environment { public class Environment {
private HashMap<String, ObjectValue> prototypes = new HashMap<>(); private HashMap<String, ObjectValue> prototypes = new HashMap<>();
public final Data data = new Data();
public final HashMap<String, Symbol> symbols = new HashMap<>();
public GlobalScope global; public GlobalScope global;
public WrappersProvider wrappersProvider; public WrappersProvider wrappersProvider;
/** NOTE: This is not the register for Symbol.for, but for the symbols like Symbol.iterator */
public HashMap<String, Symbol> symbols = new HashMap<>();
@Native public FunctionValue compile; @Native public FunctionValue compile;
@Native public FunctionValue regexConstructor = new NativeFunction("RegExp", (ctx, thisArg, args) -> { @Native public FunctionValue regexConstructor = new NativeFunction("RegExp", (ctx, thisArg, args) -> {
throw EngineException.ofError("Regular expressions not supported.").setContext(ctx); throw EngineException.ofError("Regular expressions not supported.").setContext(ctx);
}); });
public Environment addData(Data data) {
this.data.addAll(data);
return this;
}
@Native public ObjectValue proto(String name) { @Native public ObjectValue proto(String name) {
return prototypes.get(name); return prototypes.get(name);
} }

View File

@ -13,8 +13,15 @@ public class Message {
private final ArrayList<CodeFrame> frames = new ArrayList<>(); private final ArrayList<CodeFrame> frames = new ArrayList<>();
public int maxStackFrames = 1000; public int maxStackFrames = 1000;
public final Data data = new Data();
public List<CodeFrame> frames() { return Collections.unmodifiableList(frames); } public List<CodeFrame> frames() { return Collections.unmodifiableList(frames); }
public Message addData(Data data) {
this.data.addAll(data);
return this;
}
public Message pushFrame(Context ctx, CodeFrame frame) throws InterruptedException { public Message pushFrame(Context ctx, CodeFrame frame) throws InterruptedException {
this.frames.add(frame); this.frames.add(frame);
if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!"); if (this.frames.size() > maxStackFrames) throw EngineException.ofRange("Stack overflow!");

View File

@ -29,7 +29,7 @@ public class CodeFunction extends FunctionValue {
@Override @Override
public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException { public Object call(Context ctx, Object thisArg, Object ...args) throws InterruptedException {
return new CodeFrame(ctx, thisArg, args, this).run(new Context(environment, ctx.message)); return new CodeFrame(ctx, thisArg, args, this).run(ctx.setEnv(environment));
} }
public CodeFunction(Environment environment, String name, int localsN, int length, ValueVariable[] captures, Instruction[] body) { public CodeFunction(Environment environment, String name, int localsN, int length, ValueVariable[] captures, Instruction[] body) {