Compare commits

..

6 Commits

18 changed files with 92 additions and 87 deletions

View File

@@ -1,4 +1,4 @@
project_group = me.topchetoeu
project_name = jscript
project_version = 0.8.6-beta
project_version = 0.9.7-beta
main_class = me.topchetoeu.jscript.utils.JScriptRepl

View File

@@ -24,6 +24,11 @@ public class Buffer {
return n;
}
public void clear() {
data = new byte[128];
length = 0;
}
public void append(byte b) {
write(length, new byte[] { b });
}

View File

@@ -14,7 +14,7 @@ import java.util.stream.Collectors;
import me.topchetoeu.jscript.common.Filename;
import me.topchetoeu.jscript.common.Location;
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
import me.topchetoeu.jscript.compilation.scope.LocalScopeRecord;
import me.topchetoeu.jscript.utils.mapping.SourceMap;
public class FunctionMap {

View File

@@ -10,7 +10,7 @@ import me.topchetoeu.jscript.common.Location;
import me.topchetoeu.jscript.common.Instruction.BreakpointType;
import me.topchetoeu.jscript.common.mapping.FunctionMap;
import me.topchetoeu.jscript.common.mapping.FunctionMap.FunctionMapBuilder;
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
import me.topchetoeu.jscript.compilation.scope.LocalScopeRecord;
public class CompileResult {
public final Vector<Instruction> instructions = new Vector<>();

View File

@@ -16,8 +16,8 @@ import me.topchetoeu.jscript.compilation.VariableDeclareStatement.Pair;
import me.topchetoeu.jscript.compilation.control.*;
import me.topchetoeu.jscript.compilation.control.SwitchStatement.SwitchCase;
import me.topchetoeu.jscript.compilation.parsing.ParseRes.State;
import me.topchetoeu.jscript.compilation.scope.LocalScopeRecord;
import me.topchetoeu.jscript.compilation.values.*;
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
import me.topchetoeu.jscript.core.exceptions.SyntaxException;
// TODO: this has to be rewritten

View File

@@ -1,9 +1,7 @@
package me.topchetoeu.jscript.core.scope;
package me.topchetoeu.jscript.compilation.scope;
import java.util.ArrayList;
import me.topchetoeu.jscript.common.ScopeRecord;
public class LocalScopeRecord implements ScopeRecord {
public final LocalScopeRecord parent;

View File

@@ -1,6 +1,4 @@
package me.topchetoeu.jscript.common;
import me.topchetoeu.jscript.core.scope.LocalScopeRecord;
package me.topchetoeu.jscript.compilation.scope;
public interface ScopeRecord {
public Object getKey(String name);

View File

@@ -46,7 +46,7 @@ public class InstructionRunner {
private static Object execMakeVar(Context ctx, Instruction instr, Frame frame) {
var name = (String)instr.get(0);
ctx.environment.global.define(name);
ctx.environment.global.define(ctx, name);
frame.codePtr++;
return Values.NO_RETURN;
}

View File

@@ -3,7 +3,6 @@ package me.topchetoeu.jscript.core.scope;
import java.util.HashSet;
import java.util.Set;
import me.topchetoeu.jscript.common.ScopeRecord;
import me.topchetoeu.jscript.core.Context;
import me.topchetoeu.jscript.core.values.FunctionValue;
import me.topchetoeu.jscript.core.values.NativeFunction;
@@ -11,32 +10,26 @@ import me.topchetoeu.jscript.core.values.ObjectValue;
import me.topchetoeu.jscript.core.values.Values;
import me.topchetoeu.jscript.core.exceptions.EngineException;
public class GlobalScope implements ScopeRecord {
public class GlobalScope {
public final ObjectValue obj;
public boolean has(Context ctx, String name) {
return Values.hasMember(null, obj, name, false);
}
public Object getKey(String name) {
return name;
}
public GlobalScope globalChild() {
var obj = new ObjectValue();
Values.setPrototype(null, obj, this.obj);
return new GlobalScope(obj);
}
public LocalScopeRecord child() {
return new LocalScopeRecord();
}
public Object define(String name) {
if (Values.hasMember(Context.NULL, obj, name, false)) return name;
obj.defineProperty(Context.NULL, name, null);
public Object define(Context ctx, String name) {
if (Values.hasMember(ctx, obj, name, false)) return name;
obj.defineProperty(ctx, name, null);
return name;
}
public void define(String name, Variable val) {
obj.defineProperty(Context.NULL, name,
public void define(Context ctx, String name, Variable val) {
obj.defineProperty(ctx, name,
new NativeFunction("get " + name, args -> val.get(args.ctx)),
new NativeFunction("set " + name, args -> { val.set(args.ctx, args.get(0)); return null; }),
true, true
@@ -45,11 +38,11 @@ public class GlobalScope implements ScopeRecord {
public void define(Context ctx, String name, boolean readonly, Object val) {
obj.defineProperty(ctx, name, val, readonly, true, true);
}
public void define(String ...names) {
for (var n : names) define(n);
public void define(Context ctx, String ...names) {
for (var n : names) define(ctx, n);
}
public void define(boolean readonly, FunctionValue val) {
define(null, val.name, readonly, val);
public void define(Context ctx, boolean readonly, FunctionValue val) {
define(ctx, val.name, readonly, val);
}
public Object get(Context ctx, String name) {

View File

@@ -8,7 +8,7 @@ public class NativeWrapper extends ObjectValue {
@Override
public ObjectValue getPrototype(Context ctx) {
if (prototype == NATIVE_PROTO) return ctx.environment.wrappers.getProto(wrapped.getClass());
if (ctx.environment != null && prototype == NATIVE_PROTO) return ctx.environment.wrappers.getProto(wrapped.getClass());
else return super.getPrototype(ctx);
}

View File

@@ -173,27 +173,27 @@ public class Internals {
glob.define(null, "Encoding", false, wp.getNamespace(EncodingLib.class));
glob.define(null, "Filesystem", false, wp.getNamespace(FilesystemLib.class));
glob.define(false, wp.getConstr(FileLib.class));
glob.define(null, false, wp.getConstr(FileLib.class));
glob.define(false, wp.getConstr(DateLib.class));
glob.define(false, wp.getConstr(ObjectLib.class));
glob.define(false, wp.getConstr(FunctionLib.class));
glob.define(false, wp.getConstr(ArrayLib.class));
glob.define(null, false, wp.getConstr(DateLib.class));
glob.define(null, false, wp.getConstr(ObjectLib.class));
glob.define(null, false, wp.getConstr(FunctionLib.class));
glob.define(null, false, wp.getConstr(ArrayLib.class));
glob.define(false, wp.getConstr(BooleanLib.class));
glob.define(false, wp.getConstr(NumberLib.class));
glob.define(false, wp.getConstr(StringLib.class));
glob.define(false, wp.getConstr(SymbolLib.class));
glob.define(null, false, wp.getConstr(BooleanLib.class));
glob.define(null, false, wp.getConstr(NumberLib.class));
glob.define(null, false, wp.getConstr(StringLib.class));
glob.define(null, false, wp.getConstr(SymbolLib.class));
glob.define(false, wp.getConstr(PromiseLib.class));
glob.define(false, wp.getConstr(RegExpLib.class));
glob.define(false, wp.getConstr(MapLib.class));
glob.define(false, wp.getConstr(SetLib.class));
glob.define(null, false, wp.getConstr(PromiseLib.class));
glob.define(null, false, wp.getConstr(RegExpLib.class));
glob.define(null, false, wp.getConstr(MapLib.class));
glob.define(null, false, wp.getConstr(SetLib.class));
glob.define(false, wp.getConstr(ErrorLib.class));
glob.define(false, wp.getConstr(SyntaxErrorLib.class));
glob.define(false, wp.getConstr(TypeErrorLib.class));
glob.define(false, wp.getConstr(RangeErrorLib.class));
glob.define(null, false, wp.getConstr(ErrorLib.class));
glob.define(null, false, wp.getConstr(SyntaxErrorLib.class));
glob.define(null, false, wp.getConstr(TypeErrorLib.class));
glob.define(null, false, wp.getConstr(RangeErrorLib.class));
env.add(Environment.OBJECT_PROTO, wp.getProto(ObjectLib.class));
env.add(Environment.FUNCTION_PROTO, wp.getProto(FunctionLib.class));

View File

@@ -87,10 +87,10 @@ public class JScriptRepl {
private static void initEnv() {
environment = Internals.apply(environment);
environment.global.define(false, new NativeFunction("exit", args -> {
environment.global.define(null, false, new NativeFunction("exit", args -> {
throw new InterruptException();
}));
environment.global.define(false, new NativeFunction("go", args -> {
environment.global.define(null, false, new NativeFunction("go", args -> {
try {
var f = Path.of("do.js");
var func = args.ctx.compile(new Filename("do", "do/" + j++ + ".js"), new String(Files.readAllBytes(f)));
@@ -100,7 +100,7 @@ public class JScriptRepl {
throw new EngineException("Couldn't open do.js");
}
}));
environment.global.define(false, new NativeFunction("log", args -> {
environment.global.define(null, false, new NativeFunction("log", args -> {
for (var el : args.args) {
Values.printValue(args.ctx, el);
}
@@ -111,7 +111,7 @@ public class JScriptRepl {
var fs = new RootFilesystem(PermissionsProvider.get(environment));
fs.protocols.put("temp", new MemoryFilesystem(Mode.READ_WRITE));
fs.protocols.put("file", new PhysicalFilesystem("."));
fs.protocols.put("std", STDFilesystem.ofStd(System.in, System.out, System.err));
fs.protocols.put("std", new STDFilesystem(System.in, System.out, System.err));
environment.add(PermissionsProvider.KEY, PermissionsManager.ALL_PERMS);
environment.add(Filesystem.KEY, fs);

View File

@@ -13,7 +13,7 @@ public abstract class BaseFile<T> implements File {
protected abstract long onSeek(long offset, int pos);
protected abstract boolean onClose();
@Override public int read(byte[] buff) {
@Override public synchronized int read(byte[] buff) {
try {
if (handle == null) throw new FilesystemException(ErrorReason.CLOSED);
if (!mode.readable) throw new FilesystemException(ErrorReason.NO_PERMISSION, "File not open for reading.");
@@ -21,7 +21,7 @@ public abstract class BaseFile<T> implements File {
}
catch (FilesystemException e) { throw e.setAction(ActionType.READ); }
}
@Override public void write(byte[] buff) {
@Override public synchronized void write(byte[] buff) {
try {
if (handle == null) throw new FilesystemException(ErrorReason.CLOSED);
if (!mode.writable) throw new FilesystemException(ErrorReason.NO_PERMISSION, "File not open for writting.");
@@ -29,7 +29,7 @@ public abstract class BaseFile<T> implements File {
}
catch (FilesystemException e) { throw e.setAction(ActionType.WRITE); }
}
@Override public long seek(long offset, int pos) {
@Override public synchronized long seek(long offset, int pos) {
try {
if (handle == null) throw new FilesystemException(ErrorReason.CLOSED);
if (!mode.writable) throw new FilesystemException(ErrorReason.NO_PERMISSION, "File not open for seeking.");
@@ -37,7 +37,7 @@ public abstract class BaseFile<T> implements File {
}
catch (FilesystemException e) { throw e.setAction(ActionType.SEEK); }
}
@Override public boolean close() {
@Override public synchronized boolean close() {
if (handle != null) {
try {
var res = onClose();

View File

@@ -66,7 +66,7 @@ public interface File {
public static File ofStream(InputStream str) {
return new File() {
@Override public int read(byte[] buff) {
@Override public synchronized int read(byte[] buff) {
try {
try { return str.read(buff); }
catch (NullPointerException e) { throw new FilesystemException(ErrorReason.ILLEGAL_ARGS, e.getMessage()); }
@@ -78,7 +78,7 @@ public interface File {
}
public static File ofStream(OutputStream str) {
return new File() {
@Override public void write(byte[] buff) {
@Override public synchronized void write(byte[] buff) {
try {
try { str.write(buff); }
catch (NullPointerException e) {throw new FilesystemException(ErrorReason.ILLEGAL_ARGS, e.getMessage()); }
@@ -91,7 +91,7 @@ public interface File {
public static File ofLineWriter(LineWriter writer) {
var buff = new Buffer();
return new File() {
@Override public void write(byte[] val) {
@Override public synchronized void write(byte[] val) {
try {
if (val == null) throw new FilesystemException(ErrorReason.ILLEGAL_ARGS, "Given buffer is null.");
@@ -99,6 +99,7 @@ public interface File {
if (b == '\n') {
try {
writer.writeLine(new String(buff.data()));
buff.clear();
}
catch (IOException e) {
throw new FilesystemException(ErrorReason.UNKNOWN, e.getMessage());
@@ -117,7 +118,7 @@ public interface File {
private byte[] prev = new byte[0];
@Override
public int read(byte[] buff) {
public synchronized int read(byte[] buff) {
try {
if (buff == null) throw new FilesystemException(ErrorReason.ILLEGAL_ARGS, "Given buffer is null.");
var ptr = 0;

View File

@@ -20,7 +20,7 @@ public class MemoryFilesystem implements Filesystem {
@Override public String normalize(String... path) {
return Paths.normalize(path);
}
@Override public File open(String _path, Mode perms) {
@Override public synchronized File open(String _path, Mode perms) {
try {
var path = realPath(_path);
var pcount = path.getNameCount();
@@ -47,7 +47,7 @@ public class MemoryFilesystem implements Filesystem {
}
catch (FilesystemException e) { throw e.setPath(_path).setAction(ActionType.OPEN); }
}
@Override public boolean create(String _path, EntryType type) {
@Override public synchronized boolean create(String _path, EntryType type) {
try {
var path = realPath(_path);
@@ -69,14 +69,14 @@ public class MemoryFilesystem implements Filesystem {
}
catch (FilesystemException e) { throw e.setPath(_path).setAction(ActionType.CREATE); }
}
@Override public FileStat stat(String _path) {
@Override public synchronized FileStat stat(String _path) {
var path = realPath(_path);
if (files.containsKey(path)) return new FileStat(mode, EntryType.FILE);
else if (folders.contains(path)) return new FileStat(mode, EntryType.FOLDER);
else return new FileStat(Mode.NONE, EntryType.NONE);
}
@Override public void close() throws FilesystemException {
@Override public synchronized void close() throws FilesystemException {
handles.close();
}

View File

@@ -24,7 +24,7 @@ public class PhysicalFilesystem implements Filesystem {
@Override public String normalize(String... paths) {
return Paths.normalize(paths);
}
@Override public File open(String _path, Mode perms) {
@Override public synchronized File open(String _path, Mode perms) {
try {
var path = realPath(normalize(_path));
checkMode(path, perms);
@@ -39,7 +39,7 @@ public class PhysicalFilesystem implements Filesystem {
}
catch (FilesystemException e) { throw e.setAction(ActionType.OPEN).setPath(_path); }
}
@Override public boolean create(String _path, EntryType type) {
@Override public synchronized boolean create(String _path, EntryType type) {
try {
var path = realPath(_path);
@@ -63,7 +63,7 @@ public class PhysicalFilesystem implements Filesystem {
return true;
}
@Override public FileStat stat(String _path) {
@Override public synchronized FileStat stat(String _path) {
var path = realPath(_path);
if (!Files.exists(path)) return new FileStat(Mode.NONE, EntryType.NONE);
@@ -82,7 +82,7 @@ public class PhysicalFilesystem implements Filesystem {
Files.isDirectory(path) ? EntryType.FOLDER : EntryType.FILE
);
}
@Override public void close() throws FilesystemException {
@Override public synchronized void close() throws FilesystemException {
try {
handles.close();
}

View File

@@ -53,7 +53,7 @@ public class RootFilesystem implements Filesystem {
else return filename.protocol + "://" + protocol.normalize(paths);
}
}
@Override public File open(String path, Mode perms) throws FilesystemException {
@Override public synchronized File open(String path, Mode perms) throws FilesystemException {
try {
var filename = Filename.parse(path);
var protocol = getProtocol(filename);
@@ -63,7 +63,7 @@ public class RootFilesystem implements Filesystem {
}
catch (FilesystemException e) { throw e.setPath(path).setAction(ActionType.OPEN); }
}
@Override public boolean create(String path, EntryType type) throws FilesystemException {
@Override public synchronized boolean create(String path, EntryType type) throws FilesystemException {
try {
var filename = Filename.parse(path);
var protocol = getProtocol(filename);
@@ -73,7 +73,7 @@ public class RootFilesystem implements Filesystem {
}
catch (FilesystemException e) { throw e.setPath(path).setAction(ActionType.CREATE); }
}
@Override public FileStat stat(String path) throws FilesystemException {
@Override public synchronized FileStat stat(String path) throws FilesystemException {
try {
var filename = Filename.parse(path);
var protocol = getProtocol(filename);
@@ -82,7 +82,7 @@ public class RootFilesystem implements Filesystem {
}
catch (FilesystemException e) { throw e.setPath(path).setAction(ActionType.STAT); }
}
@Override public void close() throws FilesystemException {
@Override public synchronized void close() throws FilesystemException {
try {
for (var protocol : protocols.values()) {
protocol.close();

View File

@@ -2,41 +2,51 @@ package me.topchetoeu.jscript.utils.filesystem;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
public class STDFilesystem implements Filesystem {
private final HashMap<String, File> handles = new HashMap<>();
private File in;
private File out;
private File err;
@Override
public String normalize(String... path) {
var res = Paths.normalize(path);
while (res.startsWith("/")) res = res.substring(1);
while (res.endsWith("/")) res = res.substring(0, res.length() - 1);
return res;
}
@Override public File open(String path, Mode mode) {
@Override public synchronized File open(String path, Mode mode) {
path = normalize(path);
if (handles.containsKey(path)) return handles.get(path);
if (in != null && path.equals("in")) return in;
else if (out != null && path.equals("out")) return out;
else if (err != null && path.equals("err")) return err;
else throw new FilesystemException(ErrorReason.DOESNT_EXIST).setAction(ActionType.OPEN).setPath(path);
}
@Override public FileStat stat(String path) {
@Override public synchronized FileStat stat(String path) {
path = normalize(path);
if (handles.containsKey(path)) return new FileStat(Mode.READ_WRITE, EntryType.FILE);
if (path.equals("in") || path.equals("out") || path.equals("err")) return new FileStat(Mode.READ_WRITE, EntryType.FILE);
else return new FileStat(Mode.NONE, EntryType.NONE);
}
@Override public void close() {
handles.clear();
@Override public synchronized void close() {
in = out = err = null;
}
public STDFilesystem add(String name, File handle) {
this.handles.put(name, handle);
return this;
public STDFilesystem(File in, File out, File err) {
this.in = in;
this.out = out;
this.err = err;
}
public static STDFilesystem ofStd(InputStream in, OutputStream out, OutputStream err) {
return new STDFilesystem()
.add("in", File.ofStream(in))
.add("out", File.ofStream(out))
.add("err", File.ofStream(err));
public STDFilesystem(InputStream in, OutputStream out, OutputStream err) {
if (in != null) this.in = File.ofStream(in);
if (out != null) this.out = File.ofStream(out);
if (err != null) this.err = File.ofStream(err);
}
public STDFilesystem(LineReader in, LineWriter out) {
if (in != null) this.in = File.ofLineReader(in);
if (out != null) {
this.out = File.ofLineWriter(out);
this.err = File.ofLineWriter(out);
}
}
}