Compare commits
6 Commits
45292990b1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
fd8b0b7cbe
|
|||
|
a4c09b6cd6
|
|||
|
892408d9dd
|
|||
|
ecfd80f36a
|
|||
|
a1a2293af4
|
|||
|
6e9250ffd1
|
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("common");
|
||||
id("j2s-common");
|
||||
}
|
||||
|
||||
java {
|
||||
@@ -22,26 +22,28 @@ dependencies {
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher");
|
||||
}
|
||||
|
||||
if (System.getenv("REPO_URL") != null) {
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "Gitea";
|
||||
url = uri(System.getenv("REPO_URL") ?: "");
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "Gitea";
|
||||
url = uri(System.getenv("REPO_URL") ?: "");
|
||||
credentials(HttpHeaderCredentials::class) {
|
||||
name = "Authorization";
|
||||
value = "token ${System.getenv("ACCESS_TOKEN")}";
|
||||
}
|
||||
|
||||
credentials(HttpHeaderCredentials::class) {
|
||||
name = "Authorization";
|
||||
value = "token ${System.getenv("ACCESS_TOKEN")}";
|
||||
}
|
||||
|
||||
authentication {
|
||||
create<HttpHeaderAuthentication>("header");
|
||||
authentication {
|
||||
create<HttpHeaderAuthentication>("header");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
from(components["java"]);
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
from(components["java"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("common-java");
|
||||
id("j2s-common-java");
|
||||
}
|
||||
|
||||
description = "A collection of utils and structures for the rest of the project";
|
||||
|
||||
@@ -6,55 +6,99 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* The class, used to keep track of important environment-wide values
|
||||
* Supports an inheritance mechanism via parents
|
||||
* In essence a simple hashmap of flag objects to values
|
||||
*/
|
||||
public class Environment {
|
||||
/**
|
||||
* The parent of this environment. Will act as a "fallback" when searching for elements.
|
||||
* Operations this environment won't write into the parent
|
||||
*/
|
||||
public final Environment parent;
|
||||
private final Map<Key<Object>, Object> map = new HashMap<>();
|
||||
private final Set<Key<Object>> hidden = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Gets the element, contained in this environment, signified by the given key
|
||||
* @return The element, or null if not found
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(Key<T> key) {
|
||||
if (map.containsKey(key)) return (T)map.get(key);
|
||||
else if (!hidden.contains(key) && parent != null) return parent.get(key);
|
||||
else return null;
|
||||
}
|
||||
/**
|
||||
* Checks if the environment has the given key
|
||||
*/
|
||||
public boolean has(Key<?> key) {
|
||||
if (map.containsKey(key)) return true;
|
||||
else if (!hidden.contains(key) && parent != null) return parent.has(key);
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the environment has the given key and if the value behind they key is not null
|
||||
*/
|
||||
public boolean hasNotNull(Key<?> key) {
|
||||
return get(key) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the element, contained in this environment, signified by the given key
|
||||
* @param defaultVal The value to return if the element is not found
|
||||
* @return The element, or "defaultVal" if not found
|
||||
*/
|
||||
public <T> T get(Key<T> key, T defaultVal) {
|
||||
if (has(key)) return get(key);
|
||||
else return defaultVal;
|
||||
}
|
||||
/**
|
||||
* Gets the element, contained in this environment, signified by the given key
|
||||
* @param defaultVal The supplier, from which to return if the element is not found
|
||||
* @return The element, or the result of "defaultVal" if not found
|
||||
*/
|
||||
public <T> T getWith(Key<T> key, Supplier<T> defaultVal) {
|
||||
if (has(key)) return get(key);
|
||||
else return defaultVal.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the given value for the given key, replacing any existing value
|
||||
* If a parent has a value with the same key, it isn't replaced, but instead - shadowed
|
||||
* @return The inserted element
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Environment add(Key<T> key, T val) {
|
||||
map.put((Key<Object>)key, val);
|
||||
hidden.remove(key);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Adds the flag key to the environment
|
||||
* @return The environment instance
|
||||
*/
|
||||
public Environment add(Key<Void> key) {
|
||||
return add(key, null);
|
||||
}
|
||||
/**
|
||||
* Executes Environment.add for each pair of the map
|
||||
* @return The environment instance
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public Environment addAll(Map<Key<?>, ?> map, boolean iterableAsMulti) {
|
||||
public Environment addAll(Map<Key<?>, ?> map) {
|
||||
map.putAll((Map)map);
|
||||
hidden.removeAll(map.keySet());
|
||||
return this;
|
||||
}
|
||||
public Environment addAll(Map<Key<?>, ?> map) {
|
||||
return addAll(map, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given key from the environment.
|
||||
* If a parent has the given key, it is instead just "hidden" by this environment
|
||||
* @return The environment instance
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Environment remove(Key<?> key) {
|
||||
map.remove(key);
|
||||
@@ -62,6 +106,9 @@ public class Environment {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the key exists in the environment, returns it. Otherwise, puts the given value and returns the value
|
||||
*/
|
||||
public <T> T init(Key<T> key, T val) {
|
||||
if (!has(key)) {
|
||||
this.add(key, val);
|
||||
@@ -69,6 +116,9 @@ public class Environment {
|
||||
}
|
||||
else return get(key);
|
||||
}
|
||||
/**
|
||||
* If the key exists in the environment, returns it. Otherwise, puts the given value from the supplier and returns it
|
||||
*/
|
||||
public <T> T initFrom(Key<T> key, Supplier<T> val) {
|
||||
if (!has(key)) {
|
||||
var res = val.get();
|
||||
@@ -78,6 +128,10 @@ public class Environment {
|
||||
else return get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an environment that is a child of this environment
|
||||
* @return
|
||||
*/
|
||||
public Environment child() {
|
||||
return new Environment(this);
|
||||
}
|
||||
@@ -85,15 +139,25 @@ public class Environment {
|
||||
public Environment(Environment parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
/**
|
||||
* Creates an empty environment
|
||||
*/
|
||||
public Environment() {
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the environment is null, returns an empty environment
|
||||
* Otherwise, returns the given value
|
||||
*/
|
||||
public static Environment wrap(Environment env) {
|
||||
if (env == null) return empty();
|
||||
else return env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a newly-created environment
|
||||
*/
|
||||
public static Environment empty() {
|
||||
return new Environment();
|
||||
}
|
||||
|
||||
@@ -2,8 +2,17 @@ package me.topchetoeu.j2s.common;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* The class that represents all filenames in J2S
|
||||
*/
|
||||
public class Filename {
|
||||
/**
|
||||
* The protocol of the filename (file://, http://, ftp://, etc...)
|
||||
*/
|
||||
public final String protocol;
|
||||
/**
|
||||
* The path to the file (/home/me/test.js, example.org/test.js, etc...)
|
||||
*/
|
||||
public final String path;
|
||||
|
||||
@Override public String toString() {
|
||||
@@ -42,11 +51,18 @@ public class Filename {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given string to a filename.
|
||||
* If a :// is not found, the protocol will default to "file"
|
||||
*/
|
||||
public static Filename parse(String val) {
|
||||
var i = val.indexOf("://");
|
||||
if (i >= 0) return new Filename(val.substring(0, i).trim(), val.substring(i + 3).trim());
|
||||
else return new Filename("file", val.trim());
|
||||
}
|
||||
/**
|
||||
* Will convert the File instance to a filename, with the protocol set to "file"
|
||||
*/
|
||||
public static Filename fromFile(File file) {
|
||||
return new Filename("file", file.getAbsolutePath());
|
||||
}
|
||||
|
||||
@@ -79,9 +79,9 @@ public class Reading {
|
||||
if (bytes == null) return null;
|
||||
else return new String(bytes);
|
||||
}
|
||||
|
||||
|
||||
public static InputStream resourceToStream(String name) {
|
||||
return Reading.class.getResourceAsStream("/" + name);
|
||||
return Reading.class.getResourceAsStream("/" + name.replaceAll("//", "/"));
|
||||
}
|
||||
public static String resourceToString(String name) {
|
||||
return streamToString(resourceToStream(name));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("common-java");
|
||||
id("j2s-common-java");
|
||||
}
|
||||
|
||||
description = "A compiler of EcmaScript 5 code to J2S bytecode";
|
||||
|
||||
@@ -1,168 +1,168 @@
|
||||
package me.topchetoeu.j2s.compilation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.topchetoeu.j2s.common.Environment;
|
||||
import me.topchetoeu.j2s.common.FunctionBody;
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.Key;
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.j2s.compilation.CompilationFunctionMap.FunctionMapBuilder;
|
||||
import me.topchetoeu.j2s.compilation.control.TryNode;
|
||||
import me.topchetoeu.j2s.compilation.scope.FunctionScope;
|
||||
import me.topchetoeu.j2s.compilation.scope.Variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public final class CompileResult {
|
||||
public static final Key<Void> DEBUG_LOG = new Key<>();
|
||||
|
||||
private FunctionBody body;
|
||||
public final List<Instruction> instructions;
|
||||
public final List<CompileResult> children;
|
||||
public final Map<FunctionNode, CompileResult> childrenMap = new HashMap<>();
|
||||
public final Map<FunctionNode, Integer> childrenIndices = new HashMap<>();
|
||||
public final FunctionMapBuilder map;
|
||||
public final Environment env;
|
||||
public int length;
|
||||
public final FunctionScope scope;
|
||||
public final Map<TryNode, Variable> catchBindings = new HashMap<>();
|
||||
|
||||
public int temp() {
|
||||
instructions.add(null);
|
||||
return instructions.size() - 1;
|
||||
}
|
||||
|
||||
public CompileResult add(Instruction instr) {
|
||||
instructions.add(instr);
|
||||
return this;
|
||||
}
|
||||
public CompileResult set(int i, Instruction instr) {
|
||||
instructions.set(i, instr);
|
||||
return this;
|
||||
}
|
||||
|
||||
public int size() { return instructions.size(); }
|
||||
|
||||
public void setDebug(Location loc, BreakpointType type) {
|
||||
map.setDebug(loc, type);
|
||||
}
|
||||
public void setLocation(int i, Location loc) {
|
||||
map.setLocation(i, loc);
|
||||
}
|
||||
public void setLocationAndDebug(int i, Location loc, BreakpointType type) {
|
||||
map.setLocationAndDebug(i, loc, type);
|
||||
}
|
||||
public void setDebug(BreakpointType type) {
|
||||
setDebug(map.last(), type);
|
||||
}
|
||||
public void setLocation(Location type) {
|
||||
setLocation(instructions.size() - 1, type);
|
||||
}
|
||||
|
||||
public void setLocationAndDebug(Location loc, BreakpointType type) {
|
||||
setLocationAndDebug(instructions.size() - 1, loc, type);
|
||||
}
|
||||
|
||||
public Iterable<CompileResult> all() {
|
||||
var stack = new Stack<CompileResult>();
|
||||
stack.push(this);
|
||||
|
||||
return () -> new Iterator<CompileResult>() {
|
||||
@Override public CompileResult next() {
|
||||
if (stack.empty()) return null;
|
||||
else {
|
||||
var res = stack.pop();
|
||||
for (var child : res.children) {
|
||||
stack.push(child);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@Override public boolean hasNext() {
|
||||
return !stack.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public CompileResult addChild(FunctionNode node, CompileResult res) {
|
||||
this.children.add(res);
|
||||
this.childrenMap.put(node, res);
|
||||
this.childrenIndices.put(node, this.children.size() - 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Instruction[] instructions() {
|
||||
return instructions.toArray(new Instruction[0]);
|
||||
}
|
||||
|
||||
public CompilationFunctionMap map(Function<Location, Location> mapper) {
|
||||
return map.map(mapper).build(scope.localNames(), scope.capturableNames(), scope.captureNames());
|
||||
}
|
||||
public CompilationFunctionMap map() {
|
||||
return map.build(scope.localNames(), scope.capturableNames(), scope.captureNames());
|
||||
}
|
||||
public FunctionBody body() {
|
||||
if (body != null) return body;
|
||||
|
||||
var builtChildren = new FunctionBody[children.size()];
|
||||
for (var i = 0; i < children.size(); i++) builtChildren[i] = children.get(i).body();
|
||||
|
||||
var instrRes = instructions();
|
||||
|
||||
if (env.has(DEBUG_LOG)) {
|
||||
System.out.println("================= BODY =================");
|
||||
System.out.println("LOCALS: " + scope.localsCount());
|
||||
System.out.println("CAPTURABLES: " + scope.capturablesCount());
|
||||
System.out.println("CAPTURES: " + scope.capturesCount());
|
||||
|
||||
for (var instr : instrRes) System.out.println(instr);
|
||||
}
|
||||
|
||||
return body = new FunctionBody(
|
||||
scope.localsCount(), scope.capturablesCount(), scope.capturesCount(),
|
||||
length, instrRes, builtChildren
|
||||
);
|
||||
}
|
||||
|
||||
public CompileResult subtarget() {
|
||||
return new CompileResult(env, new FunctionScope(scope), this);
|
||||
}
|
||||
|
||||
public CompileResult setEnvironment(Environment env) {
|
||||
return new CompileResult(env, scope, this);
|
||||
}
|
||||
/**
|
||||
* Returns a compile result with a child of the environment that relates to the given key.
|
||||
* In essence, this is used to create a compile result which is back at the root environment of the compilation
|
||||
*/
|
||||
public CompileResult rootEnvironment(Key<Environment> env) {
|
||||
return new CompileResult(this.env.get(env).child(), scope, this);
|
||||
}
|
||||
public CompileResult subEnvironment() {
|
||||
return new CompileResult(env.child(), scope, this);
|
||||
}
|
||||
|
||||
public CompileResult(Environment env, FunctionScope scope, int length) {
|
||||
this.scope = scope;
|
||||
this.instructions = new ArrayList<>();
|
||||
this.children = new LinkedList<>();
|
||||
this.map = CompilationFunctionMap.builder();
|
||||
this.env = env;
|
||||
this.length = length;
|
||||
}
|
||||
private CompileResult(Environment env, FunctionScope scope, CompileResult parent) {
|
||||
this.scope = scope;
|
||||
this.instructions = parent.instructions;
|
||||
this.children = parent.children;
|
||||
this.map = parent.map;
|
||||
this.env = env;
|
||||
}
|
||||
}
|
||||
package me.topchetoeu.j2s.compilation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.function.Function;
|
||||
|
||||
import me.topchetoeu.j2s.common.Environment;
|
||||
import me.topchetoeu.j2s.common.FunctionBody;
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.Key;
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.j2s.compilation.CompilationFunctionMap.FunctionMapBuilder;
|
||||
import me.topchetoeu.j2s.compilation.control.TryNode;
|
||||
import me.topchetoeu.j2s.compilation.scope.FunctionScope;
|
||||
import me.topchetoeu.j2s.compilation.scope.Variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public final class CompileResult {
|
||||
public static final Key<Void> DEBUG_LOG = new Key<>();
|
||||
|
||||
private FunctionBody body;
|
||||
public final List<Instruction> instructions;
|
||||
public final List<CompileResult> children;
|
||||
public final Map<FunctionNode, CompileResult> childrenMap = new HashMap<>();
|
||||
public final Map<FunctionNode, Integer> childrenIndices = new HashMap<>();
|
||||
public final FunctionMapBuilder map;
|
||||
public final Environment env;
|
||||
public int length;
|
||||
public final FunctionScope scope;
|
||||
public final Map<TryNode, Variable> catchBindings = new HashMap<>();
|
||||
|
||||
public int temp() {
|
||||
instructions.add(null);
|
||||
return instructions.size() - 1;
|
||||
}
|
||||
|
||||
public CompileResult add(Instruction instr) {
|
||||
instructions.add(instr);
|
||||
return this;
|
||||
}
|
||||
public CompileResult set(int i, Instruction instr) {
|
||||
instructions.set(i, instr);
|
||||
return this;
|
||||
}
|
||||
|
||||
public int size() { return instructions.size(); }
|
||||
|
||||
public void setDebug(Location loc, BreakpointType type) {
|
||||
map.setDebug(loc, type);
|
||||
}
|
||||
public void setLocation(int i, Location loc) {
|
||||
map.setLocation(i, loc);
|
||||
}
|
||||
public void setLocationAndDebug(int i, Location loc, BreakpointType type) {
|
||||
map.setLocationAndDebug(i, loc, type);
|
||||
}
|
||||
public void setDebug(BreakpointType type) {
|
||||
setDebug(map.last(), type);
|
||||
}
|
||||
public void setLocation(Location type) {
|
||||
setLocation(instructions.size() - 1, type);
|
||||
}
|
||||
|
||||
public void setLocationAndDebug(Location loc, BreakpointType type) {
|
||||
setLocationAndDebug(instructions.size() - 1, loc, type);
|
||||
}
|
||||
|
||||
public Iterable<CompileResult> all() {
|
||||
var stack = new Stack<CompileResult>();
|
||||
stack.push(this);
|
||||
|
||||
return () -> new Iterator<CompileResult>() {
|
||||
@Override public CompileResult next() {
|
||||
if (stack.empty()) return null;
|
||||
else {
|
||||
var res = stack.pop();
|
||||
for (var child : res.children) {
|
||||
stack.push(child);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@Override public boolean hasNext() {
|
||||
return !stack.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public CompileResult addChild(FunctionNode node, CompileResult res) {
|
||||
this.children.add(res);
|
||||
this.childrenMap.put(node, res);
|
||||
this.childrenIndices.put(node, this.children.size() - 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Instruction[] instructions() {
|
||||
return instructions.toArray(new Instruction[0]);
|
||||
}
|
||||
|
||||
public CompilationFunctionMap map(Function<Location, Location> mapper) {
|
||||
return map.map(mapper).build(scope.localNames(), scope.capturableNames(), scope.captureNames());
|
||||
}
|
||||
public CompilationFunctionMap map() {
|
||||
return map.build(scope.localNames(), scope.capturableNames(), scope.captureNames());
|
||||
}
|
||||
public FunctionBody body() {
|
||||
if (body != null) return body;
|
||||
|
||||
var builtChildren = new FunctionBody[children.size()];
|
||||
for (var i = 0; i < children.size(); i++) builtChildren[i] = children.get(i).body();
|
||||
|
||||
var instrRes = instructions();
|
||||
|
||||
if (env.has(DEBUG_LOG)) {
|
||||
System.out.println("================= BODY =================");
|
||||
System.out.println("LOCALS: " + scope.localsCount());
|
||||
System.out.println("CAPTURABLES: " + scope.capturablesCount());
|
||||
System.out.println("CAPTURES: " + scope.capturesCount());
|
||||
|
||||
for (var instr : instrRes) System.out.println(instr);
|
||||
}
|
||||
|
||||
return body = new FunctionBody(
|
||||
scope.localsCount(), scope.capturablesCount(), scope.capturesCount(),
|
||||
length, instrRes, builtChildren
|
||||
);
|
||||
}
|
||||
|
||||
public CompileResult subtarget() {
|
||||
return new CompileResult(env, new FunctionScope(scope), this);
|
||||
}
|
||||
|
||||
public CompileResult setEnvironment(Environment env) {
|
||||
return new CompileResult(env, scope, this);
|
||||
}
|
||||
/**
|
||||
* Returns a compile result with a child of the environment that relates to the given key.
|
||||
* In essence, this is used to create a compile result which is back at the root environment of the compilation
|
||||
*/
|
||||
public CompileResult rootEnvironment(Key<Environment> env) {
|
||||
return new CompileResult(this.env.get(env).child(), scope, this);
|
||||
}
|
||||
public CompileResult subEnvironment() {
|
||||
return new CompileResult(env.child(), scope, this);
|
||||
}
|
||||
|
||||
public CompileResult(Environment env, FunctionScope scope, int length) {
|
||||
this.scope = scope;
|
||||
this.instructions = new ArrayList<>();
|
||||
this.children = new LinkedList<>();
|
||||
this.map = CompilationFunctionMap.builder();
|
||||
this.env = env;
|
||||
this.length = length;
|
||||
}
|
||||
private CompileResult(Environment env, FunctionScope scope, CompileResult parent) {
|
||||
this.scope = scope;
|
||||
this.instructions = parent.instructions;
|
||||
this.children = parent.children;
|
||||
this.map = parent.map;
|
||||
this.env = env;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,112 +1,114 @@
|
||||
package me.topchetoeu.j2s.compilation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.j2s.compilation.parsing.ParseRes;
|
||||
import me.topchetoeu.j2s.compilation.parsing.Parsing;
|
||||
import me.topchetoeu.j2s.compilation.parsing.Source;
|
||||
|
||||
|
||||
public class CompoundNode extends Node {
|
||||
public final Node[] statements;
|
||||
public Location end;
|
||||
|
||||
@Override public void resolve(CompileResult target) {
|
||||
for (var stm : statements) stm.resolve(target);
|
||||
}
|
||||
@Override public void compileFunctions(CompileResult target) {
|
||||
for (var stm : statements) stm.compileFunctions(target);
|
||||
}
|
||||
|
||||
public void compile(CompileResult target, boolean pollute, BreakpointType type) {
|
||||
List<Node> statements = new ArrayList<Node>();
|
||||
|
||||
for (var stm : this.statements) {
|
||||
if (stm instanceof FunctionStatementNode func) {
|
||||
func.compile(target, false);
|
||||
}
|
||||
else statements.add(stm);
|
||||
}
|
||||
|
||||
var polluted = false;
|
||||
|
||||
for (var i = 0; i < statements.size(); i++) {
|
||||
var stm = statements.get(i);
|
||||
|
||||
if (i != statements.size() - 1) stm.compile(target, false, BreakpointType.STEP_OVER);
|
||||
else stm.compile(target, polluted = pollute, BreakpointType.STEP_OVER);
|
||||
}
|
||||
|
||||
if (!polluted && pollute) {
|
||||
target.add(Instruction.pushUndefined());
|
||||
}
|
||||
}
|
||||
|
||||
public CompoundNode setEnd(Location loc) {
|
||||
this.end = loc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompoundNode(Location loc, Node ...statements) {
|
||||
super(loc);
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
public static ParseRes<CompoundNode> parseComma(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 1) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, ",")) return ParseRes.failed();
|
||||
n++;
|
||||
|
||||
var curr = JavaScript.parseExpression(src, i + n, 2);
|
||||
if (!curr.isSuccess()) return curr.chainError(src.loc(i + n), "Expected a value after the comma");
|
||||
n += curr.n;
|
||||
|
||||
if (prev instanceof CompoundNode comp) {
|
||||
var children = new ArrayList<Node>();
|
||||
children.addAll(Arrays.asList(comp.statements));
|
||||
children.add(curr.result);
|
||||
|
||||
return ParseRes.res(new CompoundNode(loc, children.toArray(new Node[0])), n);
|
||||
}
|
||||
else return ParseRes.res(new CompoundNode(loc, prev, curr.result), n);
|
||||
}
|
||||
public static ParseRes<CompoundNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "{")) return ParseRes.failed();
|
||||
n++;
|
||||
|
||||
var statements = new ArrayList<Node>();
|
||||
|
||||
while (true) {
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
if (src.is(i + n, "}")) {
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
if (src.is(i + n, ";")) {
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var res = JavaScript.parseStatement(src, i + n);
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a statement");
|
||||
n += res.n;
|
||||
|
||||
statements.add(res.result);
|
||||
}
|
||||
|
||||
return ParseRes.res(new CompoundNode(loc, statements.toArray(new Node[0])).setEnd(src.loc(i + n - 1)), n);
|
||||
}
|
||||
}
|
||||
package me.topchetoeu.j2s.compilation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import me.topchetoeu.j2s.common.Instruction;
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.Instruction.BreakpointType;
|
||||
import me.topchetoeu.j2s.compilation.parsing.ParseRes;
|
||||
import me.topchetoeu.j2s.compilation.parsing.Parsing;
|
||||
import me.topchetoeu.j2s.compilation.parsing.Source;
|
||||
|
||||
|
||||
public class CompoundNode extends Node {
|
||||
public final Node[] statements;
|
||||
public Location end;
|
||||
|
||||
@Override public void resolve(CompileResult target) {
|
||||
for (var stm : statements) stm.resolve(target);
|
||||
}
|
||||
@Override public void compileFunctions(CompileResult target) {
|
||||
for (var stm : statements) stm.compileFunctions(target);
|
||||
}
|
||||
|
||||
public void compile(CompileResult target, boolean pollute, BreakpointType type) {
|
||||
List<Node> statements = new ArrayList<Node>();
|
||||
|
||||
for (var stm : this.statements) {
|
||||
if (stm instanceof FunctionStatementNode func) {
|
||||
func.compile(target, false);
|
||||
}
|
||||
else statements.add(stm);
|
||||
}
|
||||
|
||||
var polluted = false;
|
||||
|
||||
for (var i = 0; i < statements.size(); i++) {
|
||||
var stm = statements.get(i);
|
||||
|
||||
if (i != statements.size() - 1) stm.compileStatement(target, false, BreakpointType.STEP_OVER);
|
||||
else stm.compileStatement(target, polluted = pollute, BreakpointType.STEP_OVER);
|
||||
|
||||
target.setDebug(type);
|
||||
}
|
||||
|
||||
if (!polluted && pollute) {
|
||||
target.add(Instruction.pushUndefined());
|
||||
}
|
||||
}
|
||||
|
||||
public CompoundNode setEnd(Location loc) {
|
||||
this.end = loc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompoundNode(Location loc, Node ...statements) {
|
||||
super(loc);
|
||||
this.statements = statements;
|
||||
}
|
||||
|
||||
public static ParseRes<CompoundNode> parseComma(Source src, int i, Node prev, int precedence) {
|
||||
if (precedence > 1) return ParseRes.failed();
|
||||
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, ",")) return ParseRes.failed();
|
||||
n++;
|
||||
|
||||
var curr = JavaScript.parseExpression(src, i + n, 2);
|
||||
if (!curr.isSuccess()) return curr.chainError(src.loc(i + n), "Expected a value after the comma");
|
||||
n += curr.n;
|
||||
|
||||
if (prev instanceof CompoundNode comp) {
|
||||
var children = new ArrayList<Node>();
|
||||
children.addAll(Arrays.asList(comp.statements));
|
||||
children.add(curr.result);
|
||||
|
||||
return ParseRes.res(new CompoundNode(loc, children.toArray(new Node[0])), n);
|
||||
}
|
||||
else return ParseRes.res(new CompoundNode(loc, prev, curr.result), n);
|
||||
}
|
||||
public static ParseRes<CompoundNode> parse(Source src, int i) {
|
||||
var n = Parsing.skipEmpty(src, i);
|
||||
var loc = src.loc(i + n);
|
||||
|
||||
if (!src.is(i + n, "{")) return ParseRes.failed();
|
||||
n++;
|
||||
|
||||
var statements = new ArrayList<Node>();
|
||||
|
||||
while (true) {
|
||||
n += Parsing.skipEmpty(src, i + n);
|
||||
|
||||
if (src.is(i + n, "}")) {
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
if (src.is(i + n, ";")) {
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
|
||||
var res = JavaScript.parseStatement(src, i + n);
|
||||
if (!res.isSuccess()) return res.chainError(src.loc(i + n), "Expected a statement");
|
||||
n += res.n;
|
||||
|
||||
statements.add(res.result);
|
||||
}
|
||||
|
||||
return ParseRes.res(new CompoundNode(loc, statements.toArray(new Node[0])).setEnd(src.loc(i + n - 1)), n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
package me.topchetoeu.j2s.compilation;
|
||||
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.Instruction.BreakpointType;
|
||||
|
||||
public abstract class Node {
|
||||
private Location loc;
|
||||
|
||||
public void resolve(CompileResult target) {}
|
||||
|
||||
public void compile(CompileResult target, boolean pollute, BreakpointType type) {
|
||||
int start = target.size();
|
||||
compile(target, pollute);
|
||||
if (target.size() != start) target.setLocationAndDebug(start, loc(), type);
|
||||
}
|
||||
public void compile(CompileResult target, boolean pollute) {
|
||||
compile(target, pollute, BreakpointType.NONE);
|
||||
}
|
||||
|
||||
public abstract void compileFunctions(CompileResult target);
|
||||
|
||||
public Location loc() { return loc; }
|
||||
public void setLoc(Location loc) { this.loc = loc; }
|
||||
|
||||
protected Node(Location loc) {
|
||||
this.loc = loc;
|
||||
}
|
||||
}
|
||||
package me.topchetoeu.j2s.compilation;
|
||||
|
||||
import me.topchetoeu.j2s.common.Location;
|
||||
import me.topchetoeu.j2s.common.Instruction.BreakpointType;
|
||||
|
||||
public abstract class Node {
|
||||
private Location loc;
|
||||
|
||||
public void resolve(CompileResult target) {}
|
||||
|
||||
public void compile(CompileResult target, boolean pollute, BreakpointType type) {
|
||||
compileStatement(target, pollute, type);
|
||||
}
|
||||
public void compileStatement(CompileResult target, boolean pollute, BreakpointType type) {
|
||||
int start = target.size();
|
||||
compile(target, pollute);
|
||||
if (target.size() != start) {
|
||||
target.setLocationAndDebug(start, loc(), type);
|
||||
}
|
||||
}
|
||||
public void compile(CompileResult target, boolean pollute) {
|
||||
compile(target, pollute, BreakpointType.NONE);
|
||||
}
|
||||
|
||||
public abstract void compileFunctions(CompileResult target);
|
||||
|
||||
public Location loc() { return loc; }
|
||||
public void setLoc(Location loc) { this.loc = loc; }
|
||||
|
||||
protected Node(Location loc) {
|
||||
this.loc = loc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,16 +102,17 @@ local function parse_impl(str, pos, end_delim)
|
||||
local delim_found;
|
||||
|
||||
if c == "{" then
|
||||
pos = pos + 1;
|
||||
pos = str:find("%S", pos + 1) or pos;
|
||||
|
||||
local key;
|
||||
local obj = {};
|
||||
|
||||
c = string.sub(str, pos, pos);
|
||||
if c == "}" then
|
||||
return obj, pos
|
||||
return obj, pos;
|
||||
else
|
||||
while true do
|
||||
pos = skip_delim(str, pos);
|
||||
key, pos = parse_str_val(str, pos, true);
|
||||
if key == nil then error("Expected a string key") end
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
content: counter(page);
|
||||
}
|
||||
}
|
||||
@page scan-page {
|
||||
margin: 0;
|
||||
}
|
||||
h1 {
|
||||
break-before: page;
|
||||
}
|
||||
@@ -196,6 +199,13 @@
|
||||
break-after: page;
|
||||
}
|
||||
|
||||
.scan-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
align-items: stretch;
|
||||
page: scan-page;
|
||||
}
|
||||
.title-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -518,7 +528,15 @@
|
||||
<div class="title-end">СОФИЯ - {{year}}</div>
|
||||
</div>
|
||||
|
||||
<div class="page asm-page">
|
||||
<div class="page scan-page">
|
||||
<img src="./img-secret/scan0001.jpg"/>
|
||||
</div>
|
||||
|
||||
<div class="page scan-page">
|
||||
<img src="./img-secret/scan0003.jpg"/>
|
||||
</div>
|
||||
|
||||
<!-- <div class="page asm-page">
|
||||
<div class="school-header">
|
||||
<img class="school-img" src="{{school_img}}"/>
|
||||
<h4>{{school_name}}</h4>
|
||||
@@ -561,11 +579,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page">
|
||||
<div>prazna str</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
{{content}}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import com.github.gradle.node.npm.task.NpmTask;
|
||||
|
||||
plugins {
|
||||
id("common-java");
|
||||
id("j2s-common-java");
|
||||
id("com.github.node-gradle.node") version "5.0.0";
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,12 @@ public class Compilers {
|
||||
try {
|
||||
var res = JavaScript.compile(env, filename, raw, true);
|
||||
var body = res.body();
|
||||
|
||||
|
||||
DebugHandler.get(env).onSourceLoad(filename, raw);
|
||||
for (var el : res.all()) {
|
||||
DebugHandler.get(env).onFunctionLoad(el.body(), el.map(mapper));
|
||||
}
|
||||
|
||||
|
||||
return new CodeFunction(env, filename.toString(), body, new Value[0][]);
|
||||
}
|
||||
catch (SyntaxException e) {
|
||||
@@ -59,9 +59,6 @@ public class Compilers {
|
||||
|
||||
public static Compiler transpilerFromSource(Compiler prev, Environment target, Filename compilerName, String compilerSrc) {
|
||||
var env = StdLib.apply(null);
|
||||
// var handler = new SimpleDebugHandler();
|
||||
// env.add(DebugHandler.KEY, handler);
|
||||
|
||||
var glob = Value.global(env);
|
||||
var compilerFactory = new FunctionValue[1];
|
||||
|
||||
@@ -86,10 +83,6 @@ public class Compilers {
|
||||
|
||||
var compiled = JavaScript.compile(compilerName, compilerSrc, false);
|
||||
|
||||
// for (var el : compiled.all()) {
|
||||
// handler.onFunctionLoad(el.body(), el.map());
|
||||
// }
|
||||
|
||||
try {
|
||||
new CodeFunction(env, "intializer", compiled.body(), new Value[0][]).apply(env, Value.UNDEFINED);
|
||||
return wrap(prev, env, target, compilerFactory[0]);
|
||||
|
||||
@@ -423,7 +423,7 @@ public class SimpleDebugger implements Debugger {
|
||||
desc.append("...");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (arr.has(i)) {
|
||||
try {
|
||||
var curr = arr.get(i);
|
||||
@@ -442,7 +442,7 @@ public class SimpleDebugger implements Debugger {
|
||||
desc.append("<empty>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
desc.append("]");
|
||||
}
|
||||
|
||||
@@ -814,7 +814,6 @@ public class SimpleDebugger implements Debugger {
|
||||
var cond = msg.params.string("condition", "").trim();
|
||||
|
||||
if (cond.equals("")) cond = null;
|
||||
if (cond != null) cond = "(" + cond + ")";
|
||||
|
||||
Pattern regex;
|
||||
|
||||
@@ -1064,7 +1063,7 @@ public class SimpleDebugger implements Debugger {
|
||||
}
|
||||
mappings.put(body, map);
|
||||
}
|
||||
|
||||
|
||||
private boolean instructionLock;
|
||||
|
||||
@Override public boolean onInstruction(Environment env, Frame cf, Instruction instruction, Value returnVal, EngineException error, boolean caught) {
|
||||
@@ -1077,16 +1076,16 @@ public class SimpleDebugger implements Debugger {
|
||||
Location loc;
|
||||
DebugFrame frame;
|
||||
BreakpointType bptType;
|
||||
|
||||
|
||||
frame = getFrame(cf);
|
||||
|
||||
|
||||
var map = DebugHandler.get(env).getMapOrEmpty(env, frame.frame.function);
|
||||
|
||||
|
||||
frame.updateLoc(map.toLocation(frame.frame.codePtr));
|
||||
loc = frame.location;
|
||||
bptType = map.getBreakpoint(frame.frame.codePtr);
|
||||
isBreakpointable = loc != null && (bptType.shouldStepIn());
|
||||
|
||||
|
||||
if (error != null && (execptionType == CatchType.ALL || execptionType == CatchType.UNCAUGHT && !caught)) {
|
||||
pauseException(env, error);
|
||||
}
|
||||
@@ -1114,19 +1113,19 @@ public class SimpleDebugger implements Debugger {
|
||||
instruction.params.length == 1 &&
|
||||
instruction.get(0).equals("debug")
|
||||
) pauseDebug(env, null);
|
||||
|
||||
|
||||
synchronized (this) {
|
||||
}
|
||||
|
||||
|
||||
while (enabled) {
|
||||
synchronized (this) {
|
||||
switch (state) {
|
||||
case PAUSED_EXCEPTION:
|
||||
case PAUSED_NORMAL: break;
|
||||
|
||||
|
||||
case STEPPING_OUT:
|
||||
case RESUMED: return false;
|
||||
|
||||
|
||||
case STEPPING_IN:
|
||||
case STEPPING_OVER:
|
||||
if (stepOutFrame.frame == frame.frame) {
|
||||
@@ -1135,7 +1134,7 @@ public class SimpleDebugger implements Debugger {
|
||||
continue;
|
||||
}
|
||||
else if (stepOutPtr != frame.frame.codePtr) {
|
||||
|
||||
|
||||
if (state == State.STEPPING_IN && bptType.shouldStepIn()) {
|
||||
pauseDebug(env, null);
|
||||
break;
|
||||
@@ -1149,7 +1148,7 @@ public class SimpleDebugger implements Debugger {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
synchronized (updateNotifier) {
|
||||
updateNotifier.wait();
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
const map: number[] = [];
|
||||
let j = 0;
|
||||
|
||||
for (let i = 65; i <= 90; i++) map[i] = j++;
|
||||
for (let i = 97; i <= 122; i++) map[i] = j++;
|
||||
map[43] = j++;
|
||||
map[47] = j++;
|
||||
function decodeBase64(val: number) {
|
||||
if (val >= 65 && val <= 90) return val - 65;
|
||||
else if (val >= 97 && val <= 122) return val - 97 + 26;
|
||||
else if (val >= 48 && val <= 57) return val - 48 + 52;
|
||||
else if (val == 43) return 62;
|
||||
else if (val == 47) return 63;
|
||||
else throw "Invalid Base64 char";
|
||||
}
|
||||
|
||||
export function decodeVLQ(val: string): number[][][] {
|
||||
const lines: number[][][] = [];
|
||||
@@ -30,14 +31,14 @@ export function decodeVLQ(val: string): number[][][] {
|
||||
|
||||
for (let i = 0; i < el.length;) {
|
||||
let sign = 1;
|
||||
let curr = map[el.charCodeAt(i++)];
|
||||
let curr = decodeBase64(el.charCodeAt(i++));
|
||||
let cont = (curr & 0x20) === 0x20;
|
||||
if ((curr & 1) === 1) sign = -1;
|
||||
let res = (curr & 0b11110) >> 1;
|
||||
let n = 4;
|
||||
|
||||
|
||||
for (; i < el.length && cont;) {
|
||||
curr = map[el.charCodeAt(i++)];
|
||||
curr = decodeBase64(el.charCodeAt(i++));
|
||||
cont = (curr & 0x20) == 0x20;
|
||||
res |= (curr & 0b11111) << n;
|
||||
n += 5;
|
||||
@@ -99,7 +100,7 @@ export class VLQSourceMap {
|
||||
|
||||
while (true) {
|
||||
const done = b - a <= 1;
|
||||
|
||||
|
||||
const mid = (a + b) >> 1;
|
||||
const el = line[mid];
|
||||
|
||||
@@ -134,7 +135,6 @@ export class VLQSourceMap {
|
||||
let originalRow = 0;
|
||||
let originalCol = 0;
|
||||
let originalFile = 0;
|
||||
const lastCols = new Set<number>();
|
||||
|
||||
for (let compiledRow = 0; compiledRow < mapping.length; compiledRow++) {
|
||||
const line: [start: number, dst: Location][] = file[compiledRow] = [];
|
||||
@@ -149,10 +149,7 @@ export class VLQSourceMap {
|
||||
originalRow += rawSeg.length > 2 ? rawSeg[2] : 0;
|
||||
originalCol += rawSeg.length > 3 ? rawSeg[3] : 0;
|
||||
|
||||
if (!lastCols.has(compiledCol)) {
|
||||
line[line.length] = [compiledCol, [filenames[originalFile], originalRow, originalCol]];
|
||||
}
|
||||
lastCols.add(compiledCol);
|
||||
line[line.length] = [compiledCol, [filenames[originalFile], originalRow, originalCol]];
|
||||
}
|
||||
|
||||
line.sort((a, b) => a[0] - b[0]);
|
||||
|
||||
@@ -16,10 +16,10 @@ export default function typescript(next: Compiler): Compiler {
|
||||
const settings: CompilerOptions = {
|
||||
target: ScriptTarget.ES5,
|
||||
module: ModuleKind.Preserve,
|
||||
|
||||
|
||||
allowImportingTsExtensions: true,
|
||||
verbatimModuleSyntax: true,
|
||||
|
||||
verbatimModuleSyntax: false,
|
||||
|
||||
strict: false,
|
||||
skipLibCheck: true,
|
||||
forceConsistentCasingInFileNames: true,
|
||||
@@ -52,7 +52,7 @@ export default function typescript(next: Compiler): Compiler {
|
||||
}
|
||||
},
|
||||
getScriptVersion: (filename) => String(versions[filename] || 0),
|
||||
|
||||
|
||||
readFile: () => { throw "no"; },
|
||||
writeFile: () => { throw "no"; },
|
||||
}, createDocumentRegistry());
|
||||
@@ -61,7 +61,7 @@ export default function typescript(next: Compiler): Compiler {
|
||||
service.getEmitOutput("/lib.d.ts");
|
||||
});
|
||||
print("Loaded typescript!");
|
||||
|
||||
|
||||
return (filename, code, prevMap) => {
|
||||
files["/src.ts"] = ScriptSnapshot.fromString(code);
|
||||
versions["/src.ts"] ??= 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("common-java");
|
||||
id("j2s-common-java");
|
||||
id("com.gradleup.shadow") version "9.0.0-beta4";
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
@@ -41,55 +42,61 @@ public class SimpleRepl {
|
||||
static Key<InputStream> STDIN = new Key<>();
|
||||
|
||||
static int j = 0;
|
||||
static String[] args;
|
||||
static String[] files;
|
||||
static boolean inspect = false;
|
||||
static int inspectPort = 9229;
|
||||
|
||||
private static void reader() {
|
||||
try {
|
||||
server = new DebugServer();
|
||||
debugTask = server.start(new InetSocketAddress("127.0.0.1", 9229), true);
|
||||
server.targets.put("default", (socket, req) -> new SimpleDebugger(socket)
|
||||
.attach((SimpleDebugHandler)DebugHandler.get(environment))
|
||||
);
|
||||
if (inspect) {
|
||||
server = new DebugServer();
|
||||
debugTask = server.start(new InetSocketAddress("127.0.0.1", inspectPort), true);
|
||||
server.targets.put("default", (socket, req) -> new SimpleDebugger(socket)
|
||||
.attach((SimpleDebugHandler)DebugHandler.get(environment))
|
||||
);
|
||||
System.out.println("Debug server started at localhost:" + inspectPort);
|
||||
}
|
||||
|
||||
System.out.println(String.format("Running %s v%s by %s", Metadata.name(), Metadata.version(), Metadata.author()));
|
||||
|
||||
for (var arg : args) {
|
||||
var file = new File(arg);
|
||||
var raw = Reading.streamToString(new FileInputStream(file));
|
||||
if (files.length > 0) {
|
||||
for (var arg : files) {
|
||||
var file = new File(arg);
|
||||
var raw = Reading.streamToString(new FileInputStream(file));
|
||||
|
||||
try {
|
||||
try {
|
||||
var res = engine.pushMsg(
|
||||
false, environment,
|
||||
Filename.fromFile(file), raw, null
|
||||
).get();
|
||||
try {
|
||||
var res = engine.pushMsg(
|
||||
false, environment,
|
||||
Filename.fromFile(file), raw, null
|
||||
).get();
|
||||
|
||||
System.err.println(res.toReadable(environment));
|
||||
System.err.println(res.toReadable(environment));
|
||||
}
|
||||
catch (ExecutionException e) { throw e.getCause(); }
|
||||
}
|
||||
catch (ExecutionException e) { throw e.getCause(); }
|
||||
catch (EngineException | SyntaxException e) { System.err.println(Value.errorToReadable(environment, e, null)); }
|
||||
}
|
||||
catch (EngineException | SyntaxException e) { System.err.println(Value.errorToReadable(environment, e, null)); }
|
||||
|
||||
}
|
||||
else {
|
||||
for (var i = 0; ; i++) {
|
||||
var raw = Reading.readline();
|
||||
|
||||
for (var i = 0; ; i++) {
|
||||
var raw = Reading.readline();
|
||||
if (raw == null) break;
|
||||
|
||||
if (raw == null) break;
|
||||
|
||||
try {
|
||||
try {
|
||||
var res = engine.pushMsg(
|
||||
false, environment,
|
||||
new Filename(Metadata.name(), "repl/" + i + ".js"), raw,
|
||||
Value.UNDEFINED
|
||||
).get();
|
||||
System.err.println(res.toReadable(environment));
|
||||
try {
|
||||
var res = engine.pushMsg(
|
||||
false, environment,
|
||||
new Filename(Metadata.name(), "repl/" + i + ".js"), raw,
|
||||
Value.UNDEFINED
|
||||
).get();
|
||||
System.err.println(res.toReadable(environment));
|
||||
}
|
||||
catch (ExecutionException e) { throw e.getCause(); }
|
||||
}
|
||||
catch (ExecutionException e) { throw e.getCause(); }
|
||||
catch (EngineException | SyntaxException e) { System.err.println(Value.errorToReadable(environment, e, null)); }
|
||||
}
|
||||
catch (EngineException | SyntaxException e) { System.err.println(Value.errorToReadable(environment, e, null)); }
|
||||
|
||||
}
|
||||
}
|
||||
catch (EngineException | SyntaxException e) { System.err.println(Value.errorToReadable(environment, e, null)); }
|
||||
@@ -104,11 +111,30 @@ public class SimpleRepl {
|
||||
}
|
||||
}
|
||||
|
||||
private static Environment createESEnv() {
|
||||
private static Environment createESEnv(String compiler) {
|
||||
var env = StdLib.apply(null);
|
||||
env.add(EventLoop.KEY, engine);
|
||||
env.add(DebugHandler.KEY, new SimpleDebugHandler());
|
||||
env.add(Compiler.KEY, Compilers.chainTranspilers(Compilers.jsCompiler(), env, Compilers::babelCompiler));
|
||||
|
||||
switch (compiler) {
|
||||
case "typescript":
|
||||
case "ts":
|
||||
env.add(Compiler.KEY, Compilers.chainTranspilers(Compilers.jsCompiler(), env, Compilers::typescriptCompiler));
|
||||
break;
|
||||
case "coffeescript":
|
||||
case "cs":
|
||||
env.add(Compiler.KEY, Compilers.chainTranspilers(Compilers.jsCompiler(), env, Compilers::babelCompiler, Compilers::coffeescriptCompiler));
|
||||
break;
|
||||
case "babel":
|
||||
case "es6":
|
||||
case "esnext":
|
||||
env.add(Compiler.KEY, Compilers.chainTranspilers(Compilers.jsCompiler(), env, Compilers::babelCompiler));
|
||||
break;
|
||||
default:
|
||||
case "js":
|
||||
env.add(Compiler.KEY, Compilers.jsCompiler());
|
||||
break;
|
||||
}
|
||||
|
||||
var glob = Value.global(env);
|
||||
|
||||
@@ -137,10 +163,29 @@ public class SimpleRepl {
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws InterruptedException {
|
||||
SimpleRepl.args = args;
|
||||
var compiler = "js";
|
||||
var files = new ArrayList<String>();
|
||||
|
||||
for (String arg : args) {
|
||||
if (arg.startsWith("--lang=")) {
|
||||
compiler = arg.substring(7);
|
||||
}
|
||||
else if (arg.equals("--inspect")) {
|
||||
inspect = true;
|
||||
}
|
||||
else if (arg.startsWith("--inspect=")) {
|
||||
inspect = true;
|
||||
inspectPort = Integer.parseInt(arg.substring(10));
|
||||
}
|
||||
else {
|
||||
files.add(arg);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleRepl.files = files.toArray(new String[0]);
|
||||
var reader = new Thread(SimpleRepl::reader);
|
||||
|
||||
environment = createESEnv();
|
||||
environment = createESEnv(compiler);
|
||||
|
||||
initEngine();
|
||||
|
||||
@@ -150,6 +195,6 @@ public class SimpleRepl {
|
||||
|
||||
reader.join();
|
||||
engineTask.interrupt();
|
||||
debugTask.interrupt();
|
||||
if (debugTask != null) debugTask.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("common-java");
|
||||
id("j2s-common-java");
|
||||
}
|
||||
|
||||
description = "The runtime of J2S, used to execute J2S bytecode";
|
||||
|
||||
@@ -93,7 +93,7 @@ public interface DebugHandler {
|
||||
}
|
||||
public default FunctionMap getMapOrEmpty(Environment env, FunctionValue func) {
|
||||
if (func instanceof CodeFunction codeFunc) return getMapOrEmpty(env, codeFunc.body);
|
||||
else return null;
|
||||
else return FunctionMap.EMPTY;
|
||||
}
|
||||
|
||||
public static DebugHandler get(Environment exts) {
|
||||
|
||||
@@ -15,8 +15,9 @@ public class Arguments {
|
||||
public final <T extends Value> T setTargetProto(T obj) {
|
||||
if (!self.isPrimitive()) {
|
||||
var proto = self.getMember(env, "prototype");
|
||||
if (proto instanceof ObjectValue objProto) self.setPrototype(env, objProto);
|
||||
else if (proto == Value.NULL) self.setPrototype(env, null);
|
||||
|
||||
if (proto instanceof ObjectValue objProto) obj.setPrototype(env, objProto);
|
||||
else if (proto == Value.NULL) obj.setPrototype(env, null);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -195,7 +195,6 @@ public abstract class ArrayLikeValue extends ObjectValue {
|
||||
res.add(" " + line);
|
||||
}
|
||||
}
|
||||
res.set(res.size() - 1, res.getLast().substring(0, res.getLast().length() - 1));
|
||||
res.add("]");
|
||||
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user