diff --git a/README.md b/README.md index 589fb8c..ab56bb3 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,8 @@ env.add(Compiler.KEY, (_env, filename, raw, mapper) -> { // We'll register the source and function source mappings for debugging DebugContext.get(env).onSource(filename, raw); - for (var el : res.bodies()) { - DebugContext.get(env).onFunctionLoad(el, res.map(mapper)); + for (var el : res.all()) { + DebugContext.get(env).onFunctionLoad(el.body(), el.map(mapper)); } // Finally, we will construct the function diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 2cb7307..0416b61 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -5,7 +5,7 @@ plugins { description = "A collection of utils and structures for the rest of the project"; tasks.processResources { - filesMatching("metadata.json", { + filesMatching("metadata", { expand( "version" to properties["project_version"], "name" to properties["project_name"], diff --git a/common/src/main/java/me/topchetoeu/j2s/common/environment/Environment.java b/common/src/main/java/me/topchetoeu/j2s/common/Environment.java similarity index 94% rename from common/src/main/java/me/topchetoeu/j2s/common/environment/Environment.java rename to common/src/main/java/me/topchetoeu/j2s/common/Environment.java index 9099640..3163873 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/environment/Environment.java +++ b/common/src/main/java/me/topchetoeu/j2s/common/Environment.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.common.environment; +package me.topchetoeu.j2s.common; import java.util.HashMap; import java.util.HashSet; @@ -63,8 +63,11 @@ public class Environment { } public T init(Key key, T val) { - if (!has(key)) this.add(key, val); - return val; + if (!has(key)) { + this.add(key, val); + return val; + } + else return get(key); } public T initFrom(Key key, Supplier val) { if (!has(key)) { diff --git a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Filename.java b/common/src/main/java/me/topchetoeu/j2s/common/Filename.java similarity index 96% rename from common/src/main/java/me/topchetoeu/j2s/common/parsing/Filename.java rename to common/src/main/java/me/topchetoeu/j2s/common/Filename.java index 0bdc7e0..bb3f0f3 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Filename.java +++ b/common/src/main/java/me/topchetoeu/j2s/common/Filename.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.common.parsing; +package me.topchetoeu.j2s.common; import java.io.File; diff --git a/common/src/main/java/me/topchetoeu/j2s/common/mapping/FunctionMap.java b/common/src/main/java/me/topchetoeu/j2s/common/FunctionMap.java similarity index 85% rename from common/src/main/java/me/topchetoeu/j2s/common/mapping/FunctionMap.java rename to common/src/main/java/me/topchetoeu/j2s/common/FunctionMap.java index aaca8fe..cb39a5c 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/mapping/FunctionMap.java +++ b/common/src/main/java/me/topchetoeu/j2s/common/FunctionMap.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.common.mapping; +package me.topchetoeu.j2s.common; import java.util.ArrayList; import java.util.Arrays; @@ -14,11 +14,10 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Filename; -import me.topchetoeu.j2s.common.parsing.Location; public class FunctionMap { public static class FunctionMapBuilder { + private Location first, last; private final TreeMap sourceMap = new TreeMap<>(); private final HashMap breakpoints = new HashMap<>(); @@ -33,6 +32,9 @@ public class FunctionMap { } public FunctionMapBuilder setLocation(int i, Location loc) { if (loc == null || i < 0) return this; + if (first == null || first.compareTo(loc) > 0) first = loc; + if (last == null || last.compareTo(loc) < 0) last = loc; + sourceMap.put(i, loc); return this; } @@ -43,12 +45,10 @@ public class FunctionMap { } public Location first() { - if (sourceMap.size() == 0) return null; - return sourceMap.firstEntry().getValue(); + return first; } public Location last() { - if (sourceMap.size() == 0) return null; - return sourceMap.lastEntry().getValue(); + return last; } public FunctionMapBuilder map(Function mapper) { @@ -76,10 +76,10 @@ public class FunctionMap { } public FunctionMap build(String[] localNames, String[] capturableNames, String[] captureNames) { - return new FunctionMap(sourceMap, breakpoints, localNames, capturableNames, captureNames); + return new FunctionMap(sourceMap, breakpoints, first, last, localNames, capturableNames, captureNames); } - public FunctionMap build(Function mapper) { - return new FunctionMap(sourceMap, breakpoints, new String[0], new String[0], new String[0]); + public FunctionMap build() { + return new FunctionMap(sourceMap, breakpoints, first, last, new String[0], new String[0], new String[0]); } private FunctionMapBuilder() { } @@ -93,11 +93,12 @@ public class FunctionMap { private final TreeMap pcToLoc = new TreeMap<>(); public final String[] localNames, capturableNames, captureNames; + public final Location first, last; - public Location toLocation(int pc, boolean approxiamte) { + public Location toLocation(int pc, boolean approximate) { if (pcToLoc.size() == 0 || pc < 0 || pc > pcToLoc.lastKey()) return null; var res = pcToLoc.get(pc); - if (!approxiamte || res != null) return res; + if (!approximate || res != null) return res; var entry = pcToLoc.headMap(pc, true).lastEntry(); if (entry == null) return null; else return entry.getValue(); @@ -153,7 +154,7 @@ public class FunctionMap { } public FunctionMap clone() { - var res = new FunctionMap(new HashMap<>(), new HashMap<>(), localNames, capturableNames, captureNames); + var res = new FunctionMap(new HashMap<>(), new HashMap<>(), first, last, localNames, capturableNames, captureNames); res.pcToLoc.putAll(this.pcToLoc); res.bps.putAll(bps); res.bpLocs.putAll(bpLocs); @@ -161,7 +162,7 @@ public class FunctionMap { return res; } - public FunctionMap(Map map, Map breakpoints, String[] localNames, String[] capturableNames, String[] captureNames) { + public FunctionMap(Map map, Map breakpoints, Location first, Location last, String[] localNames, String[] capturableNames, String[] captureNames) { var locToPc = new HashMap(); for (var el : map.entrySet()) { @@ -180,11 +181,16 @@ public class FunctionMap { this.localNames = localNames; this.captureNames = captureNames; this.capturableNames = capturableNames; + + this.first = first; + this.last = last; } private FunctionMap() { localNames = new String[0]; captureNames = new String[0]; capturableNames = new String[0]; + first = null; + last = null; } public static FunctionMapBuilder builder() { diff --git a/common/src/main/java/me/topchetoeu/j2s/common/Instruction.java b/common/src/main/java/me/topchetoeu/j2s/common/Instruction.java index 372bea9..cb4387c 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/Instruction.java +++ b/common/src/main/java/me/topchetoeu/j2s/common/Instruction.java @@ -4,8 +4,6 @@ import java.util.HashMap; import java.util.function.IntFunction; import java.util.function.IntSupplier; -import me.topchetoeu.j2s.common.parsing.Location; - public class Instruction { public static enum Type { RETURN(0x00), diff --git a/common/src/main/java/me/topchetoeu/j2s/common/Key.java b/common/src/main/java/me/topchetoeu/j2s/common/Key.java new file mode 100644 index 0000000..2aeb707 --- /dev/null +++ b/common/src/main/java/me/topchetoeu/j2s/common/Key.java @@ -0,0 +1,3 @@ +package me.topchetoeu.j2s.common; + +public final class Key { } diff --git a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Location.java b/common/src/main/java/me/topchetoeu/j2s/common/Location.java similarity index 67% rename from common/src/main/java/me/topchetoeu/j2s/common/parsing/Location.java rename to common/src/main/java/me/topchetoeu/j2s/common/Location.java index cc2eadd..39d867d 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Location.java +++ b/common/src/main/java/me/topchetoeu/j2s/common/Location.java @@ -1,10 +1,8 @@ -package me.topchetoeu.j2s.common.parsing; +package me.topchetoeu.j2s.common; import java.util.ArrayList; import java.util.Objects; -import me.topchetoeu.j2s.common.Metadata; - public abstract class Location implements Comparable { public static final Location INTERNAL = Location.of(new Filename(Metadata.name(), "native"), -1, -1); @@ -32,9 +30,9 @@ public abstract class Location implements Comparable { }; } public final Location nextLine() { - return changeLine(1); + return nextLine(1); } - public final Location changeLine(int offset) { + public final Location nextLine(int offset) { var self = this; return new Location() { @@ -60,7 +58,14 @@ public abstract class Location implements Comparable { } @Override public int compareTo(Location other) { - int a = filename().toString().compareTo(other.filename().toString()); + int a; + var filenameA = filename(); + var filenameB = other.filename(); + if (filenameB == null && filenameA == null) a = 0; + else if (filenameA == null) a = -1; + else if (filenameB == null) a = 1; + else a = filenameA.toString().compareTo(filenameB.toString()); + int b = Integer.compare(line(), other.line()); int c = Integer.compare(start(), other.start()); @@ -79,21 +84,27 @@ public abstract class Location implements Comparable { } public static Location of(String raw) { - var i0 = raw.lastIndexOf(':'); - if (i0 < 0) return Location.of(Filename.parse(raw), -1, -1); + var i1 = raw.lastIndexOf(':'); + if (i1 < 0) return Location.of(Filename.parse(raw), -1, -1); - var i1 = raw.lastIndexOf(':', i0); + var i0 = raw.substring(0, i1).lastIndexOf(':', i1); if (i0 < 0) { try { - return Location.of(Filename.parse(raw.substring(0, i0)), Integer.parseInt(raw.substring(i0 + 1)), -1); + return Location.of(null, Integer.parseInt(raw.substring(0, i1)) - 1, Integer.parseInt(raw.substring(i1 + 1)) - 1); } - catch (NumberFormatException e) { - return Location.of(Filename.parse(raw), -1, -1); + catch (NumberFormatException e) {} + + try { + return Location.of(Filename.parse(raw.substring(0, i1)), Integer.parseInt(raw.substring(i1 + 1)) - 1, -1); } + catch (NumberFormatException e) {} + + return Location.of(Filename.parse(raw), -1, -1); } int start, line; + try { start = Integer.parseInt(raw.substring(i1 + 1)); } @@ -105,9 +116,9 @@ public abstract class Location implements Comparable { line = Integer.parseInt(raw.substring(i0 + 1, i1)); } catch (NumberFormatException e) { - return Location.of(Filename.parse(raw.substring(i1 + 1)), start, -1); + return Location.of(Filename.parse(raw.substring(0, i1)), start - 1, -1); } - return Location.of(Filename.parse(raw.substring(0, i0)), start, line); + return Location.of(Filename.parse(raw.substring(0, i0)), line - 1, start - 1); } } diff --git a/common/src/main/java/me/topchetoeu/j2s/common/Metadata.java b/common/src/main/java/me/topchetoeu/j2s/common/Metadata.java index 3e13e0a..2fdeba1 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/Metadata.java +++ b/common/src/main/java/me/topchetoeu/j2s/common/Metadata.java @@ -1,18 +1,46 @@ package me.topchetoeu.j2s.common; -import me.topchetoeu.j2s.common.json.JSON; -import me.topchetoeu.j2s.common.parsing.Filename; - public class Metadata { - private static final String VERSION; - private static final String AUTHOR; - private static final String NAME; + private static String VERSION; + private static String AUTHOR; + private static String NAME; static { - var data = JSON.parse(new Filename("internal", "metadata.json"), Reading.resourceToString("metadata.json")).map(); - VERSION = data.string("version"); - AUTHOR = data.string("author"); - NAME = data.string("name"); + var raw = Reading.resourceToString("metadata").split("\n"); + var line = 0; + var file = "internal://metadata"; + + for (var el : raw) { + line++; + + el = el.trim(); + if (el.startsWith("#")) continue; + if (el.isEmpty()) continue; + + var i = el.indexOf(":"); + if (i < 0) throw new RuntimeException(String.format("%s:%s: Expected colon on line", file, line)); + + var name = el.substring(0, i).trim(); + var value = el.substring(i + 1).trim(); + + switch (name) { + case "version": + VERSION = value; + break; + case "author": + AUTHOR = value; + break; + case "name": + NAME = name; + break; + default: + throw new RuntimeException(String.format("%s:%s: Unexpected metadata key '%s'", file, line, name)); + } + } + + if (VERSION == null) throw new RuntimeException(String.format("%s:%s: No version specified", file, line)); + if (AUTHOR == null) throw new RuntimeException(String.format("%s:%s: No author specified", file, line)); + if (NAME == null) throw new RuntimeException(String.format("%s:%s: No name specified", file, line)); } public static String version() { diff --git a/common/src/main/java/me/topchetoeu/j2s/common/StringifyUtils.java b/common/src/main/java/me/topchetoeu/j2s/common/StringifyUtils.java new file mode 100644 index 0000000..38919cf --- /dev/null +++ b/common/src/main/java/me/topchetoeu/j2s/common/StringifyUtils.java @@ -0,0 +1,123 @@ +package me.topchetoeu.j2s.common; + +import java.math.BigDecimal; + +public class StringifyUtils { + public static String quoteString(String raw) { + var res = new StringBuilder("\""); + var alphabet = "0123456789ABCDEF".toCharArray(); + + for (var c : raw.toCharArray()) { + if (c < 32 || c >= 127) { + res + .append("\\u") + .append(alphabet[(c >> 12) & 0xF]) + .append(alphabet[(c >> 8) & 0xF]) + .append(alphabet[(c >> 4) & 0xF]) + .append(alphabet[(c >> 0) & 0xF]); + } + else if (c == '\\') + res.append("\\\\"); + else if (c == '"') + res.append("\\\""); + else res.append(c); + } + + return res.append('"').toString(); + } + + public static String quoteNumber(Double num) { + if (num == Double.NEGATIVE_INFINITY) return "-Infinity"; + if (num == Double.POSITIVE_INFINITY) return "Infinity"; + if (Double.isNaN(num)) return "NaN"; + return BigDecimal.valueOf(num).stripTrailingZeros().toPlainString(); + } + + private static double power(double a, long b) { + if (b == 0) return 1; + if (b == 1) return a; + if (b < 0) return 1 / power(a, -b); + + if ((b & 1) == 0) return power(a * a, b / 2); + else return a * power(a * a, b / 2); + } + + public static Double unqoteNumber(String src) { + var i = 0; + + double whole = 0; + double fract = 0; + long exponent = 0; + boolean parsedAny = false; + boolean negative = false; + + if (src.charAt(i) == '-') { + negative = true; + i++; + } + + while (i < src.length()) { + var c = src.charAt(i); + if (c < '0' || c > '9') break; + + parsedAny = true; + whole *= 10; + whole += src.charAt(i++) - '0'; + } + + if (i < src.length() && src.charAt(i) == '.') { + parsedAny = true; + i++; + + while (i < src.length()) { + var c = src.charAt(i); + if (c < '0' || c > '9') break; + + parsedAny = true; + fract += src.charAt(i++) - '0'; + fract /= 10; + } + } + + if (i < src.length() && (src.charAt(i) == 'e' || src.charAt(i) == 'E')) { + i++; + parsedAny = true; + boolean expNegative = false; + boolean parsedE = false; + + if (i < src.length()) { + if (src.charAt(i) == '-') { + expNegative = true; + i++; + } + else if (src.charAt(i) == '+') { + i++; + } + } + + + while (i < src.length()) { + var c = src.charAt(i); + if (c < '0' || c > '9') break; + + parsedE = true; + exponent *= 10; + + if (expNegative) exponent -= src.charAt(i) - '0'; + else exponent += src.charAt(i) - '0'; + } + + if (!parsedE) return Double.NaN; + } + + if (i != src.length()) return Double.NaN; + + if (!parsedAny) { + if (negative) return Double.NaN; + return 0.; + } + else if (negative) return -(whole + fract) * power(10, exponent); + else return (whole + fract) * power(10, exponent); + } +} + diff --git a/common/src/main/java/me/topchetoeu/j2s/common/SyntaxException.java b/common/src/main/java/me/topchetoeu/j2s/common/SyntaxException.java index 4e21345..4d12e27 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/SyntaxException.java +++ b/common/src/main/java/me/topchetoeu/j2s/common/SyntaxException.java @@ -1,7 +1,5 @@ package me.topchetoeu.j2s.common; -import me.topchetoeu.j2s.common.parsing.Location; - public class SyntaxException extends RuntimeException { public final Location loc; public final String msg; diff --git a/common/src/main/java/me/topchetoeu/j2s/common/environment/Key.java b/common/src/main/java/me/topchetoeu/j2s/common/environment/Key.java deleted file mode 100644 index a09adde..0000000 --- a/common/src/main/java/me/topchetoeu/j2s/common/environment/Key.java +++ /dev/null @@ -1,3 +0,0 @@ -package me.topchetoeu.j2s.common.environment; - -public final class Key { } diff --git a/common/src/main/resources/metadata b/common/src/main/resources/metadata new file mode 100644 index 0000000..8ce993c --- /dev/null +++ b/common/src/main/resources/metadata @@ -0,0 +1,3 @@ +version: ${version} +name: ${name} +author: TopchetoEU diff --git a/common/src/main/resources/metadata.json b/common/src/main/resources/metadata.json deleted file mode 100644 index 42ba55f..0000000 --- a/common/src/main/resources/metadata.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "version": "${version}", - "name": "${name}", - "author": "TopchetoEU" -} \ No newline at end of file diff --git a/common/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java b/common/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java deleted file mode 100644 index 638e19d..0000000 --- a/common/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.topchetoeu.j2s; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TestHelloWorld { - - @Test - public void testHelloWorld() { - final String message = "Hello World!"; - assertEquals("Hello World!", message); - } -} diff --git a/common/src/test/java/me/topchetoeu/j2s/common/TestEnvironment.java b/common/src/test/java/me/topchetoeu/j2s/common/TestEnvironment.java new file mode 100644 index 0000000..0aa0354 --- /dev/null +++ b/common/src/test/java/me/topchetoeu/j2s/common/TestEnvironment.java @@ -0,0 +1,69 @@ +package me.topchetoeu.j2s.common; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +import org.junit.jupiter.api.Test; + +public class TestEnvironment { + private final Key FOO = new Key<>(); + private final Key MARKER = new Key<>(); + + @Test public void testShouldCreate() { + new Environment(); + Environment.empty(); + } + @Test public void testShouldNotExist() { + var env = new Environment(); + assertEquals(null, env.get(FOO)); + assertEquals(false, env.has(FOO)); + } + + @Test public void testShouldAdd() { + var env = new Environment(); + env.add(FOO, "test"); + assertEquals("test", env.get(FOO)); + } + + @Test public void testShouldGetFromParent() { + var parent = new Environment(); + parent.add(FOO, "test"); + var child = parent.child(); + assertEquals("test", child.get(FOO)); + assertEquals(true, child.has(FOO)); + } + @Test public void testShouldHideParent() { + var parent = new Environment(); + parent.add(FOO, "test"); + var child = parent.child(); + child.remove(FOO); + assertEquals(null, child.get(FOO)); + assertEquals(false, child.has(FOO)); + } + + @Test public void testShouldAddMarker() { + var env = new Environment(); + env.add(MARKER); + assertEquals(true, env.has(MARKER)); + assertEquals(false, env.hasNotNull(MARKER)); + } + + @Test public void testShouldInitOnce() { + var env = new Environment(); + assertEquals("a", env.init(FOO, "a")); + assertEquals("a", env.init(FOO, "b")); + assertEquals("a", env.get(FOO)); + } + @Test public void testShouldInitOnceFrom() { + var env = new Environment(); + assertEquals("a", env.initFrom(FOO, () -> "a")); + assertEquals("a", env.initFrom(FOO, () -> "b")); + assertEquals("a", env.get(FOO)); + } + + @Test public void testShouldWrap() { + var env = new Environment(); + assertEquals(env, Environment.wrap(env)); + assertInstanceOf(Environment.class, Environment.wrap(null)); + } +} diff --git a/common/src/test/java/me/topchetoeu/j2s/common/TestFilename.java b/common/src/test/java/me/topchetoeu/j2s/common/TestFilename.java new file mode 100644 index 0000000..dbad89e --- /dev/null +++ b/common/src/test/java/me/topchetoeu/j2s/common/TestFilename.java @@ -0,0 +1,37 @@ +package me.topchetoeu.j2s.common; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TestFilename { + @Test public void testShouldParseFilePath() { + var filename = Filename.parse("file://hello.world"); + assertEquals("file", filename.protocol); + assertEquals("hello.world", filename.path); + } + @Test public void testShouldParseNoProtocolFilename() { + var filename = Filename.parse("hello.world"); + assertEquals("file", filename.protocol); + assertEquals("hello.world", filename.path); + } + @Test public void testShouldParseAdditionalSlashFilename() { + var filename = Filename.parse("test:///hello.world"); + assertEquals("test", filename.protocol); + assertEquals("/hello.world", filename.path); + } + @Test public void testShouldParseOneSlashFilename() { + var filename = Filename.parse("test:/hello.world"); + assertEquals("file", filename.protocol); + assertEquals("test:/hello.world", filename.path); + } + @Test public void testShouldParseMatroshkaFilename() { + var a = Filename.parse("a://b://hello.world"); + assertEquals("a", a.protocol); + assertEquals("b://hello.world", a.path); + + var b = Filename.parse(a.path); + assertEquals("b", b.protocol); + assertEquals("hello.world", b.path); + } +} diff --git a/common/src/test/java/me/topchetoeu/j2s/common/TestFunctionMap.java b/common/src/test/java/me/topchetoeu/j2s/common/TestFunctionMap.java new file mode 100644 index 0000000..f3ac0e4 --- /dev/null +++ b/common/src/test/java/me/topchetoeu/j2s/common/TestFunctionMap.java @@ -0,0 +1,18 @@ +package me.topchetoeu.j2s.common; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class TestFunctionMap { + @Test public void createEmpty() { + FunctionMap.builder().build(null, null, null); + FunctionMap.builder().build(); + } + @Test public void startOfEmpty() { + var empty = FunctionMap.EMPTY; + + assertEquals(null, empty.start()); + assertEquals(null, empty.end()); + } +} diff --git a/common/src/test/java/me/topchetoeu/j2s/common/TestLocation.java b/common/src/test/java/me/topchetoeu/j2s/common/TestLocation.java new file mode 100644 index 0000000..fad7982 --- /dev/null +++ b/common/src/test/java/me/topchetoeu/j2s/common/TestLocation.java @@ -0,0 +1,159 @@ +package me.topchetoeu.j2s.common; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TestLocation { + @Test public void testShouldCreateLocation() { + var loc = Location.of(new Filename("file", "test.txt"), 10, 5); + assertEquals("test.txt", loc.filename().path); + assertEquals(10, loc.line()); + assertEquals(5, loc.start()); + } + + @Test public void testShouldGetNextLineLocation() { + var loc = Location.of("test.txt:10:5"); + var next = loc.nextLine(); + assertEquals(new Filename("file", "test.txt"), next.filename()); + assertEquals(10, next.line()); + assertEquals(0, next.start()); + assertEquals(new Filename("file", "test.txt"), loc.filename()); + assertEquals(9, loc.line()); + assertEquals(4, loc.start()); + } + @Test public void testShouldGetNextNthLineLocation() { + var loc = Location.of(new Filename("file", "test.txt"), 10, 5); + var next = loc.nextLine(5); + assertEquals(15, next.line()); + assertEquals(0, next.start()); + assertEquals(10, loc.line()); + assertEquals(5, loc.start()); + } + + @Test public void testShouldGetNextLocation() { + var loc = Location.of("test:10:5"); + var next = loc.add(10); + assertEquals(new Filename("file", "test"), next.filename()); + assertEquals(9, next.line()); + assertEquals(14, next.start()); + assertEquals(new Filename("file", "test"), loc.filename()); + assertEquals(9, loc.line()); + assertEquals(4, loc.start()); + } + + @Test public void testShouldParseLocation() { + var loc = Location.of("test.txt:10:5"); + assertEquals(new Filename("file", "test.txt"), loc.filename()); + assertEquals(9, loc.line()); + assertEquals(4, loc.start()); + } + @Test public void testShouldParseComplexFilenameLocation() { + var loc = Location.of("testificate://test.txt:10:5"); + assertEquals(new Filename("testificate", "test.txt"), loc.filename()); + assertEquals(9, loc.line()); + assertEquals(4, loc.start()); + } + @Test public void testShouldParseNoFilenameLocation() { + var loc = Location.of("10:5"); + assertEquals(null, loc.filename()); + assertEquals(9, loc.line()); + assertEquals(4, loc.start()); + } + @Test public void testShouldParseNoStartLocationA() { + var loc = Location.of("file://10:5"); + assertEquals(new Filename("file", "10"), loc.filename()); + assertEquals(4, loc.line()); + assertEquals(-1, loc.start()); + } + @Test public void testShouldParseNoStartLocationB() { + var loc = Location.of("file:5"); + assertEquals(new Filename("file", "file"), loc.filename()); + assertEquals(4, loc.line()); + assertEquals(-1, loc.start()); + } + @Test public void testShouldParseOnlyFilenameLocationA() { + var loc = Location.of("http://example.org/test.txt"); + assertEquals(new Filename("http", "example.org/test.txt"), loc.filename()); + assertEquals(-1, loc.line()); + assertEquals(-1, loc.start()); + } + @Test public void testShouldParseOnlyFilenameLocationB() { + var loc = Location.of("test.txt"); + assertEquals(new Filename("file", "test.txt"), loc.filename()); + assertEquals(-1, loc.line()); + assertEquals(-1, loc.start()); + } + @Test public void testShouldParseOnlyFilenameWithColonLocation() { + var loc = Location.of("my-file:bad-file"); + assertEquals(new Filename("file", "my-file:bad-file"), loc.filename()); + assertEquals(-1, loc.line()); + assertEquals(-1, loc.start()); + } + @Test public void testShouldParseOnlyFilenameWithTripleColonLocation() { + var loc = Location.of("a:my-file:bad-file"); + assertEquals(new Filename("file", "a:my-file:bad-file"), loc.filename()); + assertEquals(-1, loc.line()); + assertEquals(-1, loc.start()); + } + + @Test public void testCompareEqualLoc() { + var locA = Location.of("test:10:5"); + var locB = Location.of("test:10:5"); + + assertEquals(0, locA.compareTo(locB)); + assertEquals(0, locB.compareTo(locA)); + } + @Test public void testCompareNoFileLoc() { + var locA = Location.of("10:5"); + var locB = Location.of("11:5"); + + assertEquals(-1, locA.compareTo(locB)); + assertEquals(1, locB.compareTo(locA)); + } + @Test public void testCompareOneNoFileLoc() { + var locA = Location.of("10:5"); + var locB = Location.of("test:10:5"); + + assertEquals(-1, locA.compareTo(locB)); + assertEquals(1, locB.compareTo(locA)); + } + @Test public void testCompareDiffFileLoc() { + var locA = Location.of("a:10:5"); + var locB = Location.of("b:10:5"); + + assertEquals(-1, locA.compareTo(locB)); + assertEquals(1, locB.compareTo(locA)); + } + @Test public void testCompareDiffLineLoc() { + var locA = Location.of("test:10:5"); + var locB = Location.of("test:11:5"); + + assertEquals(-1, locA.compareTo(locB)); + assertEquals(1, locB.compareTo(locA)); + } + @Test public void testCompareDiffStartLoc() { + var locA = Location.of("test:10:5"); + var locB = Location.of("test:10:10"); + + assertEquals(-1, locA.compareTo(locB)); + assertEquals(1, locB.compareTo(locA)); + } + + @Test public void testToStringAll() { + var locA = Location.of("test:10:5"); + assertEquals("file://test:10:5", locA.toString()); + } + @Test public void testToStringNoFilename() { + var locA = Location.of("10:5"); + assertEquals("10:5", locA.toString()); + } + @Test public void testToStringNoStart() { + var locA = Location.of("file:5"); + assertEquals("file://file:5", locA.toString()); + } + @Test public void testToStringNoLoc() { + var locA = Location.of("file"); + assertEquals("file://file", locA.toString()); + } +} diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompileResult.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompileResult.java index 95dbcc7..e55e956 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompileResult.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompileResult.java @@ -5,14 +5,14 @@ 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.FunctionMap; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Key; +import me.topchetoeu.j2s.common.Location; +import me.topchetoeu.j2s.common.FunctionMap.FunctionMapBuilder; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.environment.Key; -import me.topchetoeu.j2s.common.mapping.FunctionMap; -import me.topchetoeu.j2s.common.mapping.FunctionMap.FunctionMapBuilder; -import me.topchetoeu.j2s.common.parsing.Location; import me.topchetoeu.j2s.compilation.control.TryNode; import me.topchetoeu.j2s.compilation.scope.FunctionScope; import me.topchetoeu.j2s.compilation.scope.Variable; @@ -25,6 +25,7 @@ import java.util.LinkedList; public final class CompileResult { public static final Key DEBUG_LOG = new Key<>(); + private FunctionBody body; public final List instructions; public final List children; public final Map childrenMap = new HashMap<>(); @@ -71,17 +72,17 @@ public final class CompileResult { setLocationAndDebug(instructions.size() - 1, loc, type); } - public Iterable bodies() { - var stack = new Stack(); - stack.push(body()); + public Iterable all() { + var stack = new Stack(); + stack.push(this); - return () -> new Iterator() { - @Override public FunctionBody next() { + return () -> new Iterator() { + @Override public CompileResult next() { if (stack.empty()) return null; else { var res = stack.pop(); - for (var el : res.children) { - stack.push(el); + for (var child : res.children) { + stack.push(child); } return res; } @@ -110,6 +111,8 @@ public final class CompileResult { 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(); @@ -124,7 +127,7 @@ public final class CompileResult { for (var instr : instrRes) System.out.println(instr); } - return new FunctionBody( + return body = new FunctionBody( scope.localsCount(), scope.capturablesCount(), scope.capturesCount(), length, instrRes, builtChildren ); diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompoundNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompoundNode.java index 7daca70..2a7c14b 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompoundNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/CompoundNode.java @@ -5,11 +5,11 @@ 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.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +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 { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionNode.java index f41e88d..1e2a361 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionNode.java @@ -2,13 +2,13 @@ package me.topchetoeu.j2s.compilation; import java.util.List; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.scope.FunctionScope; import me.topchetoeu.j2s.compilation.values.VariableNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionStatementNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionStatementNode.java index 0ade941..64968c4 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionStatementNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionStatementNode.java @@ -3,8 +3,8 @@ package me.topchetoeu.j2s.compilation; 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.common.parsing.Location; import me.topchetoeu.j2s.compilation.scope.Variable; import me.topchetoeu.j2s.compilation.values.VariableNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionValueNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionValueNode.java index 27064d6..2e19e45 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionValueNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/FunctionValueNode.java @@ -3,8 +3,8 @@ package me.topchetoeu.j2s.compilation; 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.common.parsing.Location; import me.topchetoeu.j2s.compilation.values.VariableNode; public class FunctionValueNode extends FunctionNode { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/JavaScript.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/JavaScript.java index 1563482..ef320cb 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/JavaScript.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/JavaScript.java @@ -6,13 +6,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Key; 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.parsing.Filename; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.control.BreakNode; import me.topchetoeu.j2s.compilation.control.ContinueNode; import me.topchetoeu.j2s.compilation.control.DebugNode; @@ -26,6 +23,9 @@ import me.topchetoeu.j2s.compilation.control.SwitchNode; import me.topchetoeu.j2s.compilation.control.ThrowNode; import me.topchetoeu.j2s.compilation.control.TryNode; import me.topchetoeu.j2s.compilation.control.WhileNode; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.scope.FunctionScope; import me.topchetoeu.j2s.compilation.values.ArgumentsNode; import me.topchetoeu.j2s.compilation.values.ArrayNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/LabelContext.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/LabelContext.java index e9aca45..e225070 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/LabelContext.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/LabelContext.java @@ -5,11 +5,11 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.function.IntSupplier; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Key; +import me.topchetoeu.j2s.common.Location; 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.parsing.Location; public class LabelContext { public static final Key BREAK_CTX = new Key<>(); diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/Node.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/Node.java index 8fb5e8a..44c248e 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/Node.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/Node.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.compilation; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; public abstract class Node { private Location loc; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/Parameter.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/Parameter.java index 65cf3b2..bd157dd 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/Parameter.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/Parameter.java @@ -1,6 +1,6 @@ package me.topchetoeu.j2s.compilation; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; public final class Parameter { public final Location loc; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/VariableDeclareNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/VariableDeclareNode.java index 833a8f2..2d7a76c 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/VariableDeclareNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/VariableDeclareNode.java @@ -6,10 +6,10 @@ import java.util.List; import com.github.bsideup.jabel.Desugar; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.values.VariableNode; public class VariableDeclareNode extends Node { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/BreakNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/BreakNode.java index 377ca8b..e7da94c 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/BreakNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/BreakNode.java @@ -1,15 +1,15 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.SyntaxException; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class BreakNode extends Node { public final String label; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ContinueNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ContinueNode.java index f823c85..e78f105 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ContinueNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ContinueNode.java @@ -1,15 +1,15 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.SyntaxException; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class ContinueNode extends Node { public final String label; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DebugNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DebugNode.java index 80e0aaa..5b61478 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DebugNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DebugNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class DebugNode extends Node { @Override public void compileFunctions(CompileResult target) { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DeleteNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DeleteNode.java index 9872219..f769a28 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DeleteNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DeleteNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.values.VariableNode; import me.topchetoeu.j2s.compilation.values.constants.BoolNode; import me.topchetoeu.j2s.compilation.values.operations.IndexNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DoWhileNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DoWhileNode.java index 2ec5e78..ba4a626 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DoWhileNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/DoWhileNode.java @@ -1,16 +1,16 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.DeferredIntSupplier; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class DoWhileNode extends Node { public final Node condition, body; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForInNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForInNode.java index 4238059..a11bce8 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForInNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForInNode.java @@ -1,16 +1,16 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.DeferredIntSupplier; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.values.VariableNode; public class ForInNode extends Node { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForNode.java index 71ce3b8..f765b5b 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ForNode.java @@ -1,17 +1,17 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.DeferredIntSupplier; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; import me.topchetoeu.j2s.compilation.VariableDeclareNode; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class ForNode extends Node { public final Node declaration, assignment, condition, body; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/IfNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/IfNode.java index 1b3f805..1d3b13a 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/IfNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/IfNode.java @@ -1,16 +1,16 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.DeferredIntSupplier; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class IfNode extends Node { public final Node condition, body, elseBody; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ReturnNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ReturnNode.java index c5ee1b0..ebc4554 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ReturnNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ReturnNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class ReturnNode extends Node { public final Node value; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/SwitchNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/SwitchNode.java index 8465ee1..fab72b3 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/SwitchNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/SwitchNode.java @@ -4,17 +4,17 @@ import java.util.ArrayList; import java.util.HashMap; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Operation; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.DeferredIntSupplier; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class SwitchNode extends Node { public static class SwitchCase { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ThrowNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ThrowNode.java index 87e06f3..8ce24db 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ThrowNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/ThrowNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class ThrowNode extends Node { public final Node value; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/TryNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/TryNode.java index 68ea2da..027bda5 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/TryNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/TryNode.java @@ -1,17 +1,17 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.CompoundNode; import me.topchetoeu.j2s.compilation.DeferredIntSupplier; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class TryNode extends Node { public final CompoundNode tryBody; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/WhileNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/WhileNode.java index b6e9136..d5d98aa 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/WhileNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/control/WhileNode.java @@ -1,16 +1,16 @@ package me.topchetoeu.j2s.compilation.control; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.DeferredIntSupplier; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.LabelContext; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class WhileNode extends Node { public final Node condition, body; diff --git a/common/src/main/java/me/topchetoeu/j2s/common/json/JSON.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSON.java similarity index 78% rename from common/src/main/java/me/topchetoeu/j2s/common/json/JSON.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSON.java index 1cf678b..7c4182b 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/json/JSON.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSON.java @@ -1,16 +1,16 @@ -package me.topchetoeu.j2s.common.json; +package me.topchetoeu.j2s.compilation.json; -import java.math.BigDecimal; import java.util.HashMap; import java.util.stream.Collectors; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Metadata; +import me.topchetoeu.j2s.common.StringifyUtils; import me.topchetoeu.j2s.common.SyntaxException; -import me.topchetoeu.j2s.common.parsing.Filename; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class JSON { public static ParseRes parseString(Source src, int i) { @@ -110,37 +110,10 @@ public class JSON { } public static String stringify(JSONElement el) { - if (el.isNumber()) { - var d = el.number(); - if (d == Double.NEGATIVE_INFINITY) return "-Infinity"; - if (d == Double.POSITIVE_INFINITY) return "Infinity"; - if (Double.isNaN(d)) return "NaN"; - return BigDecimal.valueOf(d).stripTrailingZeros().toPlainString(); - } + if (el.isNumber()) return StringifyUtils.quoteNumber(el.number()); + if (el.isString()) return StringifyUtils.quoteString(el.string()); if (el.isBoolean()) return el.bool() ? "true" : "false"; if (el.isNull()) return "null"; - if (el.isString()) { - var res = new StringBuilder("\""); - var alphabet = "0123456789ABCDEF".toCharArray(); - - for (var c : el.string().toCharArray()) { - if (c < 32 || c >= 127) { - res - .append("\\u") - .append(alphabet[(c >> 12) & 0xF]) - .append(alphabet[(c >> 8) & 0xF]) - .append(alphabet[(c >> 4) & 0xF]) - .append(alphabet[(c >> 0) & 0xF]); - } - else if (c == '\\') - res.append("\\\\"); - else if (c == '"') - res.append("\\\""); - else res.append(c); - } - - return res.append('"').toString(); - } if (el.isList()) { var res = new StringBuilder().append("["); for (int i = 0; i < el.list().size(); i++) { @@ -156,7 +129,7 @@ public class JSON { for (int i = 0; i < entries.size(); i++) { if (i != 0) res.append(","); - res.append(stringify(JSONElement.string(entries.get(i).getKey()))); + res.append(StringifyUtils.quoteString(entries.get(i).getKey())); res.append(":"); res.append(stringify(entries.get(i).getValue())); } diff --git a/common/src/main/java/me/topchetoeu/j2s/common/json/JSONElement.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONElement.java similarity index 98% rename from common/src/main/java/me/topchetoeu/j2s/common/json/JSONElement.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONElement.java index ad18e67..4cffab5 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/json/JSONElement.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONElement.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.common.json; +package me.topchetoeu.j2s.compilation.json; public class JSONElement { public static enum Type { diff --git a/common/src/main/java/me/topchetoeu/j2s/common/json/JSONList.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONList.java similarity index 95% rename from common/src/main/java/me/topchetoeu/j2s/common/json/JSONList.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONList.java index 49a0c3b..ad333a1 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/json/JSONList.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONList.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.common.json; +package me.topchetoeu.j2s.compilation.json; import java.util.ArrayList; import java.util.Arrays; diff --git a/common/src/main/java/me/topchetoeu/j2s/common/json/JSONMap.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONMap.java similarity index 99% rename from common/src/main/java/me/topchetoeu/j2s/common/json/JSONMap.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONMap.java index 7a9e39e..d17a363 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/json/JSONMap.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/json/JSONMap.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.common.json; +package me.topchetoeu.j2s.compilation.json; import java.util.Collection; import java.util.HashMap; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/FieldMemberNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/FieldMemberNode.java index d871a4d..0f3ec13 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/FieldMemberNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/FieldMemberNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.members; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.values.ObjectNode; public class FieldMemberNode implements Member { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/Member.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/Member.java index c15adbd..755dc81 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/Member.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/Member.java @@ -1,6 +1,6 @@ package me.topchetoeu.j2s.compilation.members; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; public interface Member { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/PropertyMemberNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/PropertyMemberNode.java index dd32cb2..658b61b 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/PropertyMemberNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/members/PropertyMemberNode.java @@ -3,16 +3,16 @@ package me.topchetoeu.j2s.compilation.members; import java.util.Arrays; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.CompoundNode; import me.topchetoeu.j2s.compilation.FunctionNode; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.values.ObjectNode; import me.topchetoeu.j2s.compilation.values.VariableNode; import me.topchetoeu.j2s.compilation.values.constants.StringNode; diff --git a/common/src/main/java/me/topchetoeu/j2s/common/parsing/ParseRes.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/ParseRes.java similarity index 89% rename from common/src/main/java/me/topchetoeu/j2s/common/parsing/ParseRes.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/ParseRes.java index 9d632cf..24f41a6 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/parsing/ParseRes.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/ParseRes.java @@ -1,4 +1,6 @@ -package me.topchetoeu.j2s.common.parsing; +package me.topchetoeu.j2s.compilation.parsing; + +import me.topchetoeu.j2s.common.Location; public class ParseRes { public static enum State { @@ -33,19 +35,20 @@ public class ParseRes { if (!state.isSuccess()) return this; return new ParseRes<>(state, null, null, result, this.n + n); } + @SuppressWarnings("unchecked") public ParseRes chainError() { if (isSuccess()) throw new RuntimeException("Can't transform a ParseRes that hasn't failed"); - return new ParseRes<>(state, errorLocation, error, null, 0); + return (ParseRes)this; } @SuppressWarnings("unchecked") public ParseRes chainError(ParseRes other) { - if (!this.isError()) return other.chainError(); - return (ParseRes) this; + if (this.isError()) return other.chainError(); + return (ParseRes)this; } @SuppressWarnings("unchecked") public ParseRes chainError(Location loc, String error) { if (!this.isError()) return new ParseRes<>(State.ERROR, loc, error, null, 0); - return (ParseRes) this; + return (ParseRes)this; } public boolean isSuccess() { return state.isSuccess(); } @@ -63,7 +66,6 @@ public class ParseRes { return new ParseRes<>(State.SUCCESS, null, null, val, i); } - @SafeVarargs @SuppressWarnings("all") public static ParseRes first(Source src, int i, Parser ...parsers) { int n = Parsing.skipEmpty(src, i); diff --git a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Parser.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Parser.java similarity index 62% rename from common/src/main/java/me/topchetoeu/j2s/common/parsing/Parser.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Parser.java index 7be6041..b8c49b0 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Parser.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Parser.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.common.parsing; +package me.topchetoeu.j2s.compilation.parsing; public interface Parser { public ParseRes parse(Source src, int i); diff --git a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Parsing.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Parsing.java similarity index 96% rename from common/src/main/java/me/topchetoeu/j2s/common/parsing/Parsing.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Parsing.java index 3f0082f..a1c457d 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Parsing.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Parsing.java @@ -1,6 +1,4 @@ -package me.topchetoeu.j2s.common.parsing; - -import me.topchetoeu.j2s.common.SyntaxException; +package me.topchetoeu.j2s.compilation.parsing; public class Parsing { public static boolean isDigit(Character c) { @@ -18,14 +16,13 @@ public class Parsing { } public static int skipEmpty(Source src, int i) { - return skipEmpty(src, i, true); - } - - public static int skipEmpty(Source src, int i, boolean noComments) { int n = 0; if (i == 0 && src.is(0, "#!")) { - while (!src.is(n, '\n')) n++; + while (!src.is(n, '\n')) { + if (n >= src.size()) return src.size(); + n++; + } n++; } @@ -88,7 +85,7 @@ public class Parsing { if (i + n >= src.size()) return ParseRes.error(src.loc(i), "Invalid hexadecimal escape sequence"); int val = fromHex(src.at(i + n)); - if (val == -1) throw new SyntaxException(src.loc(i + n), "Invalid hexadecimal escape sequence"); + if (val == -1) return ParseRes.error(src.loc(i + n), "Invalid hexadecimal escape sequence"); n++; newC = (newC << 4) | val; @@ -103,7 +100,7 @@ public class Parsing { if (i + n >= src.size()) return ParseRes.error(src.loc(i), "Invalid Unicode escape sequence"); int val = fromHex(src.at(i + n)); - if (val == -1) throw new SyntaxException(src.loc(i + n), "Invalid Unicode escape sequence"); + if (val == -1) return ParseRes.error(src.loc(i + n), "Invalid Unicode escape sequence"); n++; newC = (newC << 4) | val; diff --git a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Source.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Source.java similarity index 86% rename from common/src/main/java/me/topchetoeu/j2s/common/parsing/Source.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Source.java index 531778e..a994fb9 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/parsing/Source.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/Source.java @@ -1,8 +1,10 @@ -package me.topchetoeu.j2s.common.parsing; +package me.topchetoeu.j2s.compilation.parsing; import java.util.function.Predicate; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Location; public class Source { public final Environment env; @@ -12,6 +14,8 @@ public class Source { private int[] lineStarts; public Location loc(int offset) { + if (offset < 0) offset = 0; + if (offset > src.length()) offset = src.length(); return new SourceLocation(filename, lineStarts, offset); } public boolean is(int i, char c) { diff --git a/common/src/main/java/me/topchetoeu/j2s/common/parsing/SourceLocation.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/SourceLocation.java similarity index 91% rename from common/src/main/java/me/topchetoeu/j2s/common/parsing/SourceLocation.java rename to compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/SourceLocation.java index be9b083..f2e0490 100644 --- a/common/src/main/java/me/topchetoeu/j2s/common/parsing/SourceLocation.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/parsing/SourceLocation.java @@ -1,7 +1,10 @@ -package me.topchetoeu.j2s.common.parsing; +package me.topchetoeu.j2s.compilation.parsing; import java.util.Objects; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Location; + public class SourceLocation extends Location { private int[] lineStarts; private int line; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/patterns/AssignTarget.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/patterns/AssignTarget.java index 676cad2..2f2f25e 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/patterns/AssignTarget.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/patterns/AssignTarget.java @@ -1,6 +1,6 @@ package me.topchetoeu.j2s.compilation.patterns; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; /** diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArgumentsNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArgumentsNode.java index 4cdeb1e..52a8465 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArgumentsNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArgumentsNode.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.compilation.values; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArrayNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArrayNode.java index 6525e4d..c166be5 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArrayNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ArrayNode.java @@ -3,13 +3,13 @@ package me.topchetoeu.j2s.compilation.values; import java.util.ArrayList; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class ArrayNode extends Node { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/GlobalThisNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/GlobalThisNode.java index 5b6cd5c..823a9a8 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/GlobalThisNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/GlobalThisNode.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.compilation.values; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ObjectNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ObjectNode.java index c234a4d..a39da13 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ObjectNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ObjectNode.java @@ -4,16 +4,16 @@ import java.util.LinkedList; import java.util.List; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; import me.topchetoeu.j2s.compilation.members.FieldMemberNode; import me.topchetoeu.j2s.compilation.members.Member; import me.topchetoeu.j2s.compilation.members.PropertyMemberNode; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.values.constants.NumberNode; import me.topchetoeu.j2s.compilation.values.constants.StringNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/RegexNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/RegexNode.java index 04b353c..fe0fbd7 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/RegexNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/RegexNode.java @@ -1,12 +1,12 @@ package me.topchetoeu.j2s.compilation.values; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class RegexNode extends Node { public final String pattern, flags; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ThisNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ThisNode.java index 77d53c8..8c323f4 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ThisNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/ThisNode.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.compilation.values; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/VariableNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/VariableNode.java index 0e8fe10..8c841c2 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/VariableNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/VariableNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.values; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.patterns.ChangeTarget; public class VariableNode extends Node implements ChangeTarget { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/BoolNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/BoolNode.java index 19447eb..75a1960 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/BoolNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/BoolNode.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.compilation.values.constants; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NullNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NullNode.java index b48ee3d..2038e28 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NullNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NullNode.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.compilation.values.constants; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NumberNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NumberNode.java index 8003f09..ff60b56 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NumberNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/NumberNode.java @@ -1,12 +1,12 @@ package me.topchetoeu.j2s.compilation.values.constants; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class NumberNode extends Node { public final double value; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/StringNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/StringNode.java index 05f3ffb..07ffa82 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/StringNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/constants/StringNode.java @@ -1,12 +1,12 @@ package me.topchetoeu.j2s.compilation.values.constants; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class StringNode extends Node { public final String value; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/AssignNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/AssignNode.java index 2f95dc9..e295ae1 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/AssignNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/AssignNode.java @@ -1,9 +1,9 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Operation; import me.topchetoeu.j2s.common.SyntaxException; -import me.topchetoeu.j2s.common.parsing.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; import me.topchetoeu.j2s.compilation.patterns.AssignTarget; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/CallNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/CallNode.java index dfae0ed..912c8cf 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/CallNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/CallNode.java @@ -3,14 +3,14 @@ package me.topchetoeu.j2s.compilation.values.operations; import java.util.ArrayList; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class CallNode extends Node { public final Node func; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/ChangeNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/ChangeNode.java index 0ac0eb3..d409333 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/ChangeNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/ChangeNode.java @@ -1,14 +1,14 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Operation; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.patterns.ChangeTarget; import me.topchetoeu.j2s.compilation.values.constants.NumberNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/DiscardNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/DiscardNode.java index cd40fc5..20dc5e5 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/DiscardNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/DiscardNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class DiscardNode extends Node { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/IndexNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/IndexNode.java index 7de4965..e6408de 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/IndexNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/IndexNode.java @@ -1,14 +1,14 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Instruction.BreakpointType; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.patterns.ChangeTarget; import me.topchetoeu.j2s.compilation.values.constants.NumberNode; import me.topchetoeu.j2s.compilation.values.constants.StringNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyAndNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyAndNode.java index 529dcd3..6dc0f41 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyAndNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyAndNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class LazyAndNode extends Node { public final Node first, second; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyOrNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyOrNode.java index 807a7ed..370f258 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyOrNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/LazyOrNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; public class LazyOrNode extends Node { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/OperationNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/OperationNode.java index 7887116..b27ffa3 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/OperationNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/OperationNode.java @@ -6,14 +6,14 @@ import java.util.Map; import java.util.stream.Collectors; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Operation; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.patterns.AssignTargetLike; import me.topchetoeu.j2s.compilation.patterns.ChangeTarget; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/PostfixNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/PostfixNode.java index 1b7ae52..7308f1c 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/PostfixNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/PostfixNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Operation; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.patterns.ChangeTarget; import me.topchetoeu.j2s.compilation.values.constants.NumberNode; diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/TypeofNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/TypeofNode.java index d371240..eb4338b 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/TypeofNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/TypeofNode.java @@ -1,13 +1,13 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.parsing.Location; -import me.topchetoeu.j2s.common.parsing.ParseRes; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.JavaScript; import me.topchetoeu.j2s.compilation.Node; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; import me.topchetoeu.j2s.compilation.values.VariableNode; public class TypeofNode extends Node { diff --git a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/VariableAssignNode.java b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/VariableAssignNode.java index 5c758fe..d0b004b 100644 --- a/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/VariableAssignNode.java +++ b/compilation/src/main/java/me/topchetoeu/j2s/compilation/values/operations/VariableAssignNode.java @@ -1,8 +1,8 @@ package me.topchetoeu.j2s.compilation.values.operations; import me.topchetoeu.j2s.common.Instruction; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.common.Operation; -import me.topchetoeu.j2s.common.parsing.Location; import me.topchetoeu.j2s.compilation.CompileResult; import me.topchetoeu.j2s.compilation.FunctionNode; import me.topchetoeu.j2s.compilation.Node; diff --git a/compilation/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java b/compilation/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java deleted file mode 100644 index 638e19d..0000000 --- a/compilation/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.topchetoeu.j2s; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TestHelloWorld { - - @Test - public void testHelloWorld() { - final String message = "Hello World!"; - assertEquals("Hello World!", message); - } -} diff --git a/compilation/src/test/java/me/topchetoeu/j2s/compilation/TestParseRes.java b/compilation/src/test/java/me/topchetoeu/j2s/compilation/TestParseRes.java new file mode 100644 index 0000000..bf56fba --- /dev/null +++ b/compilation/src/test/java/me/topchetoeu/j2s/compilation/TestParseRes.java @@ -0,0 +1,98 @@ +package me.topchetoeu.j2s.compilation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +import me.topchetoeu.j2s.common.Location; +import me.topchetoeu.j2s.compilation.parsing.ParseRes; + +public class TestParseRes { + @Test public void testCreateFailed() { + var res = ParseRes.failed(); + assertEquals(false, res.isSuccess()); + assertEquals(true, res.isFailed()); + assertEquals(false, res.isError()); + assertEquals(0, res.n); + assertEquals(null, res.result); + assertEquals(null, res.errorLocation); + assertEquals(null, res.error); + } + @Test public void testCreateError() { + var res = ParseRes.error(Location.of("test:10:5"), "test"); + assertEquals(false, res.isSuccess()); + assertEquals(false, res.isFailed()); + assertEquals(true, res.isError()); + assertEquals(0, res.n); + assertEquals(null, res.result); + assertEquals(Location.of("test:10:5"), res.errorLocation); + assertEquals("test", res.error); + } + @Test public void testCreateResult() { + var res = ParseRes.res("test", 10); + assertEquals(true, res.isSuccess()); + assertEquals(false, res.isFailed()); + assertEquals(false, res.isError()); + assertEquals(10, res.n); + assertEquals("test", res.result); + assertEquals(null, res.errorLocation); + assertEquals(null, res.error); + } + + @Test public void testChainFailed() { + var a = ParseRes.failed(); + + var b1 = a.chainError(); + assertEquals(a, b1); + + var b2 = a.chainError(Location.of("test:1:2"), "test"); + assertEquals(true, b2.isError()); + assertEquals("test", b2.error); + } + @Test public void testChainError() { + var a = ParseRes.error(Location.of("test:1:2"), "test"); + + var b1 = a.chainError(); + assertEquals(a, b1); + + var b2 = a.chainError(Location.of("test:1:2"), "test"); + assertEquals(a, b2); + } + @Test public void testChainResult() { + var a = ParseRes.res(10, 6); + + assertThrows(RuntimeException.class, () -> a.chainError()); + + var b1 = a.chainError(Location.of("test:1:2"), "test"); + assertEquals(true, b1.isError()); + assertEquals("test", b1.error); + } + + + @Test public void testShouldAdd5() { + var a = ParseRes.res("test", 6); + var b = a.addN(5); + + assertEquals(11, b.n); + } + @Test public void testShouldSet5() { + var a = ParseRes.res("test", 6); + var b = a.setN(5); + + assertEquals(5, b.n); + } + + @Test public void testShouldNotAdd() { + var a = ParseRes.failed(); + var b = a.addN(5); + + assertEquals(0, b.n); + } + @Test public void testShouldNotSet() { + var a = ParseRes.failed(); + var b = a.setN(5); + + assertEquals(0, b.n); + } +} diff --git a/compilation/src/test/java/me/topchetoeu/j2s/compilation/TestSource.java b/compilation/src/test/java/me/topchetoeu/j2s/compilation/TestSource.java new file mode 100644 index 0000000..ce15cf5 --- /dev/null +++ b/compilation/src/test/java/me/topchetoeu/j2s/compilation/TestSource.java @@ -0,0 +1,65 @@ +package me.topchetoeu.j2s.compilation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Location; +import me.topchetoeu.j2s.compilation.parsing.Source; + +public class TestSource { + private Source mkSource(String src) { + return new Source(new Environment(), Filename.parse("test"), src); + } + + @Test public void testShouldCreate() { + new Source(new Environment(), Filename.parse("test"), "my little source :)"); + new Source(null, Filename.parse("test"), "my little source :)"); + new Source("my little source :)"); + } + + @Test public void testShouldGet() { + var src = mkSource("1234567890"); + assertEquals('1', src.at(0)); + assertEquals('6', src.at(5)); + } + @Test public void testShouldThrowOutOfRange() { + var src = mkSource("1234567890"); + assertThrows(IndexOutOfBoundsException.class, () -> src.at(-1)); + assertThrows(IndexOutOfBoundsException.class, () -> src.at(10)); + } + @Test public void testImmutableSrcLoc() { + var src = mkSource("1234567890"); + var loc = src.loc(5); + // kinda stupid + for (var i = 0; i < 1000; i++) { + assertEquals(5, loc.start()); + assertEquals(0, loc.line()); + assertEquals(Filename.parse("test"), loc.filename()); + } + } + @Test public void testSingleLineSourceLocation() { + var src = mkSource("1234567890"); + assertEquals(Location.of("test:1:1"), src.loc(-5)); + assertEquals(Location.of("test:1:1"), src.loc(0)); + assertEquals(Location.of("test:1:10"), src.loc(9)); + assertEquals(Location.of("test:1:11"), src.loc(14)); + } + @Test public void testMultilineSourceLocation() { + var src = mkSource("123\n456\n\n789\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + assertEquals(Location.of("test:1:1"), src.loc(-5)); + assertEquals(Location.of("test:1:1"), src.loc(0)); + assertEquals(Location.of("test:1:4"), src.loc(3)); + assertEquals(Location.of("test:2:1"), src.loc(4)); + assertEquals(Location.of("test:2:4"), src.loc(7)); + assertEquals(Location.of("test:3:1"), src.loc(8)); + assertEquals(Location.of("test:4:1"), src.loc(9)); + assertEquals(Location.of("test:4:2"), src.loc(10)); + assertEquals(Location.of("test:4:4"), src.loc(12)); + assertEquals(Location.of("test:5:1"), src.loc(13)); + assertEquals(Location.of("test:19:1"), src.loc(50)); + } +} diff --git a/compilation/src/test/java/me/topchetoeu/j2s/compilation/parsing/TestParseString.java b/compilation/src/test/java/me/topchetoeu/j2s/compilation/parsing/TestParseString.java new file mode 100644 index 0000000..b4a013b --- /dev/null +++ b/compilation/src/test/java/me/topchetoeu/j2s/compilation/parsing/TestParseString.java @@ -0,0 +1,68 @@ +package me.topchetoeu.j2s.compilation.parsing; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; + +public class TestParseString { + @Test public void notAString() { + var res = Parsing.parseString(new Source("var a = 10"), 0); + assertEquals(true, res.isFailed()); + } + @Test public void simple() { + var src = new Source("\"this is a test\""); + var res = Parsing.parseString(src, 0); + assertEquals(true, res.isSuccess()); + assertEquals("this is a test", res.result); + assertEquals(16, res.n); + } + @Test public void simpleEscaped() { + var src = new Source("\'this\\\\ is \\n some \\'\\\"\\\n escapes for you :\\)\'"); + var res = Parsing.parseString(src, 0); + assertEquals(true, res.isSuccess()); + assertEquals("this\\ is \n some '\" escapes for you :)", res.result); + assertEquals(46, res.n); + } + @Test public void allEscaped() { + var src = new Source("'\\b\\t\\n\\f\\r\\0\\'\\x01\\u0123'"); + var res = Parsing.parseString(src, 0); + assertEquals(true, res.isSuccess()); + assertEquals("\b\t\n\f\r\0'\u0001\u0123", res.result); + assertEquals(26, res.n); + } + @Test public void shouldFailOctal() { + var res1 = Parsing.parseString(new Source("'\\012'"), 0); + assertEquals(true, res1.isError()); + + var res2 = Parsing.parseString(new Source("'\\123'"), 0); + assertEquals(true, res2.isError()); + } + @Test public void shouldFailIncompleteHex() { + var res1 = Parsing.parseString(new Source("'\\x"), 0); + assertEquals(true, res1.isError()); + + var res2 = Parsing.parseString(new Source("'\\x1turd"), 0); + assertEquals(true, res2.isError()); + + var res3 = Parsing.parseString(new Source("'\\xturd"), 0); + assertEquals(true, res3.isError()); + } + @Test public void shouldFailIncompleteUnicode() { + var res1 = Parsing.parseString(new Source("'\\u"), 0); + assertEquals(true, res1.isError()); + + var res2 = Parsing.parseString(new Source("'\\u123turd"), 0); + assertEquals(true, res2.isError()); + + var res3 = Parsing.parseString(new Source("'\\uturd"), 0); + assertEquals(true, res3.isError()); + } + @Test public void unterminated() { + var src = new Source("\"this is a test"); + var res = Parsing.parseString(src, 0); + assertEquals(true, res.isError()); + } +} diff --git a/compilation/src/test/java/me/topchetoeu/j2s/compilation/parsing/TestSkipWhite.java b/compilation/src/test/java/me/topchetoeu/j2s/compilation/parsing/TestSkipWhite.java new file mode 100644 index 0000000..cb20b6f --- /dev/null +++ b/compilation/src/test/java/me/topchetoeu/j2s/compilation/parsing/TestSkipWhite.java @@ -0,0 +1,51 @@ +package me.topchetoeu.j2s.compilation.parsing; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +import me.topchetoeu.j2s.compilation.parsing.Parsing; +import me.topchetoeu.j2s.compilation.parsing.Source; + +public class TestSkipWhite { + @Test public void shBang() { + var res1 = Parsing.skipEmpty(new Source("#!my-shbang\n10"), 0); + assertEquals(12, res1); + + var res2 = Parsing.skipEmpty(new Source("#!fin"), 0); + assertEquals(5, res2); + } + @Test public void simple() { + var res1 = Parsing.skipEmpty(new Source("2134 45324"), 4); + assertEquals(3, res1); + + var res2 = Parsing.skipEmpty(new Source("2134 "), 4); + assertEquals(3, res2); + } + + @Test public void nothing() { + var res1 = Parsing.skipEmpty(new Source("12345678"), 4); + assertEquals(0, res1); + + var res2 = Parsing.skipEmpty(new Source("1234"), 4); + assertEquals(0, res2); + } + + @Test public void singleLineComment() { + var res1 = Parsing.skipEmpty(new Source("123// test\n54314214"), 3); + assertEquals(8, res1); + + var res2 = Parsing.skipEmpty(new Source("123// test"), 3); + assertEquals(7, res2); + } + @Test public void multilineComment() { + var res1 = Parsing.skipEmpty(new Source("123/*test*/54314214"), 3); + assertEquals(8, res1); + + var res2 = Parsing.skipEmpty(new Source("123/*test*/"), 3); + assertEquals(8, res2); + + var res3 = Parsing.skipEmpty(new Source("123/*test"), 3); + assertEquals(6, res3); + } +} diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/JSONConverter.java b/repl/src/main/java/me/topchetoeu/j2s/repl/JSONConverter.java similarity index 91% rename from runtime/src/main/java/me/topchetoeu/j2s/runtime/JSONConverter.java rename to repl/src/main/java/me/topchetoeu/j2s/repl/JSONConverter.java index 729078d..221e5f4 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/JSONConverter.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/JSONConverter.java @@ -1,12 +1,12 @@ -package me.topchetoeu.j2s.runtime; +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.common.json.JSONElement; -import me.topchetoeu.j2s.common.json.JSONList; -import me.topchetoeu.j2s.common.json.JSONMap; +import me.topchetoeu.j2s.common.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; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/SimpleRepl.java b/repl/src/main/java/me/topchetoeu/j2s/repl/SimpleRepl.java index a726ef5..7807517 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/SimpleRepl.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/SimpleRepl.java @@ -16,14 +16,20 @@ import java.util.concurrent.ExecutionException; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Key; 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.buffers.Int32ArrayValue; +import me.topchetoeu.j2s.repl.buffers.Int8ArrayValue; +import me.topchetoeu.j2s.repl.buffers.TypedArrayValue; +import me.topchetoeu.j2s.repl.buffers.Uint8ArrayValue; import me.topchetoeu.j2s.repl.debug.DebugServer; import me.topchetoeu.j2s.repl.debug.Debugger; import me.topchetoeu.j2s.repl.debug.SimpleDebugger; @@ -33,7 +39,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; @@ -43,10 +48,6 @@ import me.topchetoeu.j2s.runtime.values.functions.NativeFunction; import me.topchetoeu.j2s.runtime.values.objects.ArrayLikeValue; import me.topchetoeu.j2s.runtime.values.objects.ArrayValue; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; -import me.topchetoeu.j2s.runtime.values.objects.buffers.Int32ArrayValue; -import me.topchetoeu.j2s.runtime.values.objects.buffers.Int8ArrayValue; -import me.topchetoeu.j2s.runtime.values.objects.buffers.TypedArrayValue; -import me.topchetoeu.j2s.runtime.values.objects.buffers.Uint8ArrayValue; import me.topchetoeu.j2s.runtime.values.primitives.BoolValue; import me.topchetoeu.j2s.runtime.values.primitives.StringValue; import me.topchetoeu.j2s.runtime.values.primitives.SymbolValue; @@ -61,8 +62,8 @@ public class SimpleRepl { var body = res.body(); DebugContext.get(env).onSource(filename, raw); - for (var el : res.bodies()) { - DebugContext.get(env).onFunctionLoad(el, res.map(mapper)); + for (var el : res.all()) { + DebugContext.get(env).onFunctionLoad(el.body(), el.map(mapper)); } return new CodeFunction(env, filename.toString(), body, new Value[0][]); @@ -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()))); @@ -684,14 +701,14 @@ public class SimpleRepl { res.defineOwnField(env, "invoke", new NativeFunction(args -> { var func = (FunctionValue)args.get(0); var self = args.get(1); - var funcArgs = (ArrayValue)args.get(2); + var funcArgs = (ArrayLikeValue)args.get(2); return func.apply(env, self, funcArgs.toArray()); })); res.defineOwnField(env, "construct", new NativeFunction(args -> { var func = (FunctionValue)args.get(0); var target = args.get(1); - var funcArgs = (ArrayValue)args.get(2); + var funcArgs = (ArrayLikeValue)args.get(2); if (target == Value.UNDEFINED) return func.constructNoSelf(env, funcArgs.toArray()); else return func.construct(env, target, funcArgs.toArray()); diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/V8Error.java b/repl/src/main/java/me/topchetoeu/j2s/repl/V8Error.java index 9251ddc..dca7053 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/V8Error.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/V8Error.java @@ -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; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Int32ArrayValue.java b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Int32ArrayValue.java similarity index 92% rename from runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Int32ArrayValue.java rename to repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Int32ArrayValue.java index f09aa47..aea022f 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Int32ArrayValue.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Int32ArrayValue.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.runtime.values.objects.buffers; +package me.topchetoeu.j2s.repl.buffers; public final class Int32ArrayValue extends TypedArrayValue { @Override protected int onGet(int i) { diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Int8ArrayValue.java b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Int8ArrayValue.java similarity index 85% rename from runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Int8ArrayValue.java rename to repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Int8ArrayValue.java index cb46163..d3a8fa5 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Int8ArrayValue.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Int8ArrayValue.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.runtime.values.objects.buffers; +package me.topchetoeu.j2s.repl.buffers; public final class Int8ArrayValue extends TypedArrayValue { @Override protected int onGet(int i) { diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/TypedArrayValue.java b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/TypedArrayValue.java similarity index 93% rename from runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/TypedArrayValue.java rename to repl/src/main/java/me/topchetoeu/j2s/repl/buffers/TypedArrayValue.java index a26ce9e..db1d6d5 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/TypedArrayValue.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/TypedArrayValue.java @@ -1,8 +1,8 @@ -package me.topchetoeu.j2s.runtime.values.objects.buffers; +package me.topchetoeu.j2s.repl.buffers; import java.util.WeakHashMap; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.objects.ArrayLikeValue; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Uint8ArrayValue.java b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Uint8ArrayValue.java similarity index 88% rename from runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Uint8ArrayValue.java rename to repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Uint8ArrayValue.java index 2d51cf5..dd2590a 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/buffers/Uint8ArrayValue.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/buffers/Uint8ArrayValue.java @@ -1,4 +1,4 @@ -package me.topchetoeu.j2s.runtime.values.objects.buffers; +package me.topchetoeu.j2s.repl.buffers; public final class Uint8ArrayValue extends TypedArrayValue { @Override protected int onGet(int i) { diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/DebugServer.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/DebugServer.java index 63a691a..bc7d98c 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/DebugServer.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/DebugServer.java @@ -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 { diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/ScopeObject.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/ScopeObject.java index c7ffb37..7b5200b 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/ScopeObject.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/ScopeObject.java @@ -7,7 +7,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.IntUnaryOperator; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.Frame; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.KeyCache; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/SimpleDebugger.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/SimpleDebugger.java index 793a722..d32e7c1 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/SimpleDebugger.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/SimpleDebugger.java @@ -11,25 +11,25 @@ import java.util.concurrent.ExecutionException; import java.util.regex.Pattern; import java.util.stream.Collectors; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; import me.topchetoeu.j2s.common.FunctionBody; +import me.topchetoeu.j2s.common.FunctionMap; 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; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/StackObject.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/StackObject.java index 0dd88fa..e061240 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/StackObject.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/StackObject.java @@ -1,6 +1,6 @@ package me.topchetoeu.j2s.repl.debug; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.Frame; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.objects.ArrayLikeValue; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Error.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Error.java index 83e7d78..15b708b 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Error.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Error.java @@ -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; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Event.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Event.java index c4e3b1e..93db46f 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Event.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Event.java @@ -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; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Message.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Message.java index f607472..67a6f29 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Message.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Message.java @@ -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; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Result.java b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Result.java index 880e201..b7f5661 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Result.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/debug/V8Result.java @@ -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; diff --git a/repl/src/main/java/me/topchetoeu/j2s/repl/mapping/NativeMapper.java b/repl/src/main/java/me/topchetoeu/j2s/repl/mapping/NativeMapper.java index 2d0486c..eae9b50 100644 --- a/repl/src/main/java/me/topchetoeu/j2s/repl/mapping/NativeMapper.java +++ b/repl/src/main/java/me/topchetoeu/j2s/repl/mapping/NativeMapper.java @@ -2,9 +2,9 @@ package me.topchetoeu.j2s.repl.mapping; import java.util.function.Function; -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.common.Environment; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.functions.FunctionValue; diff --git a/repl/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java b/repl/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java deleted file mode 100644 index 638e19d..0000000 --- a/repl/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.topchetoeu.j2s; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TestHelloWorld { - - @Test - public void testHelloWorld() { - final String message = "Hello World!"; - assertEquals("Hello World!", message); - } -} diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/ArgumentsValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/ArgumentsValue.java index 6e3050b..375f2ee 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/ArgumentsValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/ArgumentsValue.java @@ -1,13 +1,53 @@ package me.topchetoeu.j2s.runtime; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.Value; -import me.topchetoeu.j2s.runtime.values.objects.ArrayValue; +import me.topchetoeu.j2s.runtime.values.objects.ArrayLikeValue; -public class ArgumentsValue extends ArrayValue { +public class ArgumentsValue extends ArrayLikeValue { public final Frame frame; + private Value[] args; + private boolean shadowed; - public ArgumentsValue(Frame frame, Value... args) { - super(args); + private void shadow() { + if (!shadowed) { + var newArgs = new Value[args.length]; + System.arraycopy(args, 0, newArgs, 0, args.length); + args = newArgs; + shadowed = true; + } + } + + @Override public Value get(int i) { + return args[i]; + } + @Override public boolean has(int i) { + if (i < 0 || i >= size()) return false; + + if (shadowed) return args[i] != null; + else return true; + } + @Override public boolean remove(int i) { + shadow(); + args[i] = null; + return true; + } + @Override public boolean set(Environment env, int i, Value val) { + shadow(); + args[i] = val; + return true; + } + @Override public boolean setSize(int val) { + return false; + } + @Override public int size() { + return args.length; + } + + public ArgumentsValue(Frame frame) { this.frame = frame; + this.args = frame.args; + this.shadowed = false; + setPrototype(e -> null); } } diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/Compiler.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/Compiler.java index f2ec26d..dfb665f 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/Compiler.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/Compiler.java @@ -2,10 +2,10 @@ package me.topchetoeu.j2s.runtime; import java.util.function.Function; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.environment.Key; -import me.topchetoeu.j2s.common.parsing.Filename; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Key; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.functions.FunctionValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/EventLoop.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/EventLoop.java index d5a8305..3a5337a 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/EventLoop.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/EventLoop.java @@ -3,9 +3,9 @@ package me.topchetoeu.j2s.runtime; import java.util.concurrent.Future; import java.util.function.Supplier; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.environment.Key; -import me.topchetoeu.j2s.common.parsing.Filename; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; +import me.topchetoeu.j2s.common.Key; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.functions.FunctionValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/Frame.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/Frame.java index bee4949..b84cea4 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/Frame.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/Frame.java @@ -4,9 +4,9 @@ import java.util.Arrays; import java.util.Stack; import java.util.concurrent.CancellationException; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.environment.Key; +import me.topchetoeu.j2s.common.Key; import me.topchetoeu.j2s.runtime.debug.DebugContext; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Value; @@ -383,7 +383,7 @@ public final class Frame { this.self = self; this.args = args; - this.argsVal = new ArgumentsValue(this, args); + this.argsVal = new ArgumentsValue(this); this.argsLen = new IntValue(args.length); this.captures = func.captures; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/InstructionRunner.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/InstructionRunner.java index 651fad4..d9f6621 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/InstructionRunner.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/InstructionRunner.java @@ -4,9 +4,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Optional; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.common.Instruction; import me.topchetoeu.j2s.common.Operation; -import me.topchetoeu.j2s.common.environment.Environment; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.functions.CodeFunction; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugContext.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugContext.java index 3bbfe79..1996e1e 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugContext.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugContext.java @@ -3,12 +3,12 @@ package me.topchetoeu.j2s.runtime.debug; import java.util.HashMap; import java.util.WeakHashMap; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; import me.topchetoeu.j2s.common.FunctionBody; +import me.topchetoeu.j2s.common.FunctionMap; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.environment.Key; -import me.topchetoeu.j2s.common.mapping.FunctionMap; -import me.topchetoeu.j2s.common.parsing.Filename; +import me.topchetoeu.j2s.common.Key; import me.topchetoeu.j2s.runtime.Frame; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Value; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugHandler.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugHandler.java index 5a559a5..e68fdd0 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugHandler.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/debug/DebugHandler.java @@ -1,10 +1,10 @@ package me.topchetoeu.j2s.runtime.debug; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Filename; import me.topchetoeu.j2s.common.FunctionBody; +import me.topchetoeu.j2s.common.FunctionMap; import me.topchetoeu.j2s.common.Instruction; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.mapping.FunctionMap; -import me.topchetoeu.j2s.common.parsing.Filename; import me.topchetoeu.j2s.runtime.Frame; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Value; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/exceptions/EngineException.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/exceptions/EngineException.java index 3322266..978ed9e 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/exceptions/EngineException.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/exceptions/EngineException.java @@ -3,8 +3,8 @@ package me.topchetoeu.j2s.runtime.exceptions; import java.util.ArrayList; import java.util.List; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.parsing.Location; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Location; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue.PrototypeProvider; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/KeyCache.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/KeyCache.java index 77edb60..456042b 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/KeyCache.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/KeyCache.java @@ -1,6 +1,6 @@ package me.topchetoeu.j2s.runtime.values; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.primitives.StringValue; import me.topchetoeu.j2s.runtime.values.primitives.SymbolValue; import me.topchetoeu.j2s.runtime.values.primitives.numbers.NumberValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Member.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Member.java index b58e78a..8af0c02 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Member.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Member.java @@ -2,7 +2,7 @@ package me.topchetoeu.j2s.runtime.values; import java.util.Optional; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.functions.FunctionValue; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; import me.topchetoeu.j2s.runtime.values.primitives.BoolValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Value.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Value.java index bc85332..ed5da41 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Value.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/Value.java @@ -14,9 +14,9 @@ import java.util.Map; import java.util.Optional; import java.util.Set; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Key; import me.topchetoeu.j2s.common.SyntaxException; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.environment.Key; import me.topchetoeu.j2s.runtime.EventLoop; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Member.PropertyMember; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/Arguments.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/Arguments.java index 18f59a4..f14ddb0 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/Arguments.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/Arguments.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.runtime.values.functions; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; import me.topchetoeu.j2s.runtime.values.primitives.UserValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/CodeFunction.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/CodeFunction.java index 935e182..57e3ccf 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/CodeFunction.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/CodeFunction.java @@ -1,7 +1,7 @@ package me.topchetoeu.j2s.runtime.values.functions; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.common.FunctionBody; -import me.topchetoeu.j2s.common.environment.Environment; import me.topchetoeu.j2s.runtime.Frame; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/FunctionValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/FunctionValue.java index 33c7be7..8ed0ee6 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/FunctionValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/FunctionValue.java @@ -5,7 +5,7 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.debug.DebugContext; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.KeyCache; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/NativeFunction.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/NativeFunction.java index d083405..9ce68d7 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/NativeFunction.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/functions/NativeFunction.java @@ -1,6 +1,6 @@ package me.topchetoeu.j2s.runtime.values.functions; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.Value; public final class NativeFunction extends FunctionValue { diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayLikeValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayLikeValue.java index caea5b0..b6eea39 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayLikeValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayLikeValue.java @@ -7,7 +7,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.KeyCache; import me.topchetoeu.j2s.runtime.values.Member; @@ -56,6 +56,17 @@ public abstract class ArrayLikeValue extends ObjectValue { public abstract boolean has(int i); public abstract boolean remove(int i); + public Value[] toArray() { + var n = size(); + var res = new Value[n]; + + for (var i = 0; i < n; i++) { + if (has(i)) res[i] = get(i); + } + + return res; + } + @Override public Member getOwnMember(Environment env, KeyCache key) { var res = super.getOwnMember(env, key); if (res != null) return res; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayValue.java index f8af406..7d7deac 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ArrayValue.java @@ -6,7 +6,7 @@ import java.util.Comparator; import java.util.Iterator; import java.util.stream.Stream; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.primitives.VoidValue; @@ -68,7 +68,7 @@ public class ArrayValue extends ArrayLikeValue implements Iterable { } } - public Value[] toArray() { + @Override public Value[] toArray() { var res = new Value[size]; copyTo(res, 0, 0, size); return res; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ObjectValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ObjectValue.java index d9ef238..47064f2 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ObjectValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/objects/ObjectValue.java @@ -10,8 +10,8 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.environment.Key; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.Key; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.KeyCache; import me.topchetoeu.j2s.runtime.values.Member; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/BoolValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/BoolValue.java index a0c0ad2..2b34083 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/BoolValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/BoolValue.java @@ -1,6 +1,6 @@ package me.topchetoeu.j2s.runtime.values.primitives; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; import me.topchetoeu.j2s.runtime.values.primitives.numbers.NumberValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/PrimitiveValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/PrimitiveValue.java index af17408..a08ad05 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/PrimitiveValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/PrimitiveValue.java @@ -4,7 +4,7 @@ import java.util.HashSet; import java.util.Optional; import java.util.Set; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.KeyCache; import me.topchetoeu.j2s.runtime.values.Member; import me.topchetoeu.j2s.runtime.values.Value; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/StringValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/StringValue.java index 64be39a..b035dc1 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/StringValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/StringValue.java @@ -7,11 +7,8 @@ import java.util.List; import java.util.Set; import java.util.WeakHashMap; -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.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Environment; +import me.topchetoeu.j2s.common.StringifyUtils; import me.topchetoeu.j2s.runtime.values.KeyCache; import me.topchetoeu.j2s.runtime.values.Member; import me.topchetoeu.j2s.runtime.values.Member.FieldMember; @@ -29,10 +26,7 @@ public final class StringValue extends PrimitiveValue { @Override public NumberValue toNumber(Environment ext) { var val = value.trim(); if (val.equals("")) return NumberValue.of(0); - var res = Parsing.parseNumber(new Source(val), 0, true); - - if (res.isSuccess() && res.n == val.length()) return NumberValue.of(res.result); - else return NumberValue.NAN; + return NumberValue.of(StringifyUtils.unqoteNumber(val)); } @Override public String toString(Environment ext) { return value; } @@ -79,7 +73,7 @@ public final class StringValue extends PrimitiveValue { } @Override public List toReadableLines(Environment env, HashSet passed) { - return Arrays.asList(JSON.stringify(JSONElement.string(value))); + return Arrays.asList(StringifyUtils.quoteString(value)); } private StringValue(String value) { diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/SymbolValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/SymbolValue.java index c84ece9..f0119c1 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/SymbolValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/SymbolValue.java @@ -5,7 +5,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.Value; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/UserValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/UserValue.java index 925702e..4829dd4 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/UserValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/UserValue.java @@ -7,7 +7,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.KeyCache; import me.topchetoeu.j2s.runtime.values.Member; import me.topchetoeu.j2s.runtime.values.Value; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/VoidValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/VoidValue.java index d2be58e..0741749 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/VoidValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/VoidValue.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.exceptions.EngineException; import me.topchetoeu.j2s.runtime.values.KeyCache; import me.topchetoeu.j2s.runtime.values.Member; diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/DoubleValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/DoubleValue.java index bc90fea..8e51b4f 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/DoubleValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/DoubleValue.java @@ -1,7 +1,6 @@ package me.topchetoeu.j2s.runtime.values.primitives.numbers; -import me.topchetoeu.j2s.common.json.JSON; -import me.topchetoeu.j2s.common.json.JSONElement; +import me.topchetoeu.j2s.common.StringifyUtils; public final class DoubleValue extends NumberValue { public final double value; @@ -22,7 +21,7 @@ public final class DoubleValue extends NumberValue { return value; } - @Override public String toString() { return JSON.stringify(JSONElement.number(value)); } + @Override public String toString() { return StringifyUtils.quoteNumber(value); } @Override public int hashCode() { return Double.hashCode(value); diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/IntValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/IntValue.java index 43eae12..3ed1791 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/IntValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/IntValue.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; -import me.topchetoeu.j2s.common.environment.Environment; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; public final class IntValue extends NumberValue { diff --git a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/NumberValue.java b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/NumberValue.java index d5cb285..338f689 100644 --- a/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/NumberValue.java +++ b/runtime/src/main/java/me/topchetoeu/j2s/runtime/values/primitives/numbers/NumberValue.java @@ -1,8 +1,6 @@ package me.topchetoeu.j2s.runtime.values.primitives.numbers; -import me.topchetoeu.j2s.common.environment.Environment; -import me.topchetoeu.j2s.common.parsing.Parsing; -import me.topchetoeu.j2s.common.parsing.Source; +import me.topchetoeu.j2s.common.Environment; import me.topchetoeu.j2s.runtime.values.objects.ObjectValue; import me.topchetoeu.j2s.runtime.values.primitives.PrimitiveValue; import me.topchetoeu.j2s.runtime.values.primitives.StringValue; @@ -31,25 +29,6 @@ public abstract class NumberValue extends PrimitiveValue { return env.get(NUMBER_PROTO); } - public static NumberValue parseInt(String str, int radix, boolean relaxed) { - if (radix < 2 || radix > 36) return NumberValue.NAN; - - str = str.trim(); - var res = Parsing.parseInt(new Source(str), 0, "0123456789abcdefghijklmnopqrstuvwxyz".substring(0, radix), true); - if (res.isSuccess()) { - if (relaxed || res.n == str.length()) return of(res.result); - } - return NumberValue.NAN; - } - public static NumberValue parseFloat(String str, boolean relaxed) { - str = str.trim(); - var res = Parsing.parseFloat(new Source(str), 0, true); - if (res.isSuccess()) { - if (relaxed || res.n == str.length()) return of(res.result); - } - return NumberValue.NAN; - } - public static NumberValue of(double value) { if (Double.isNaN(value)) return NAN; else if ((int)value == value) return new IntValue((int)value); diff --git a/runtime/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java b/runtime/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java deleted file mode 100644 index 638e19d..0000000 --- a/runtime/src/main/test/java/me/topchetoeu/j2s/TestHelloWorld.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.topchetoeu.j2s; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TestHelloWorld { - - @Test - public void testHelloWorld() { - final String message = "Hello World!"; - assertEquals("Hello World!", message); - } -}