From 99bdd1c953c025dff1e9e8ad70efc7adab5ed53b Mon Sep 17 00:00:00 2001 From: aNNiMON Date: Sat, 9 Sep 2023 18:59:53 +0300 Subject: [PATCH] Separate constants and functions in module, don't load it twice --- .../ownlang/modules/canvasfx/canvasfx.java | 78 ++++++------ .../ownlang/modules/base64/base64.java | 17 +-- .../ownlang/modules/canvas/canvas.java | 56 +++++---- .../modules/collections/collections.java | 27 ++--- .../annimon/ownlang/modules/date/date.java | 32 ++--- .../modules/downloader/downloader.java | 15 ++- .../annimon/ownlang/modules/files/files.java | 112 +++++++++--------- .../annimon/ownlang/modules/forms/forms.java | 58 +++++---- .../modules/functional/functional.java | 37 +++--- .../annimon/ownlang/modules/gzip/gzip.java | 28 +++-- .../annimon/ownlang/modules/http/http.java | 20 ++-- .../annimon/ownlang/modules/java/java.java | 86 +++++++------- .../annimon/ownlang/modules/jdbc/jdbc.java | 62 +++++----- .../annimon/ownlang/modules/json/json.java | 18 ++- .../annimon/ownlang/modules/math/math.java | 88 +++++++------- .../ownlang/modules/okhttp/okhttp.java | 22 ++-- .../annimon/ownlang/modules/ounit/ounit.java | 28 +++-- .../annimon/ownlang/modules/regex/regex.java | 11 +- .../annimon/ownlang/modules/robot/robot.java | 83 +++++++------ .../ownlang/modules/socket/socket.java | 40 ++++--- .../com/annimon/ownlang/modules/std/std.java | 99 +++++++++------- .../annimon/ownlang/modules/types/types.java | 44 ++++--- .../annimon/ownlang/modules/yaml/yaml.java | 15 ++- .../com/annimon/ownlang/modules/zip/zip.java | 25 ++-- .../com/annimon/ownlang/lib/ModuleLoader.java | 28 +++++ .../com/annimon/ownlang/lib/RootScope.java | 17 +++ .../com/annimon/ownlang/lib/ScopeHandler.java | 5 +- .../com/annimon/ownlang/modules/Module.java | 10 +- .../ownlang/parser/ast/UseStatement.java | 41 ++----- .../parser/optimization/VariablesGrabber.java | 15 +-- .../ownlang/utils/ModulesInfoCreator.java | 12 +- 31 files changed, 687 insertions(+), 542 deletions(-) create mode 100644 ownlang-core/src/main/java/com/annimon/ownlang/lib/ModuleLoader.java diff --git a/modules/canvasfx/src/main/java/com/annimon/ownlang/modules/canvasfx/canvasfx.java b/modules/canvasfx/src/main/java/com/annimon/ownlang/modules/canvasfx/canvasfx.java index 1247d65..4f4ef65 100644 --- a/modules/canvasfx/src/main/java/com/annimon/ownlang/modules/canvasfx/canvasfx.java +++ b/modules/canvasfx/src/main/java/com/annimon/ownlang/modules/canvasfx/canvasfx.java @@ -8,6 +8,8 @@ import java.awt.Dimension; import java.lang.reflect.Modifier; import java.nio.IntBuffer; import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.stream.Collectors; import javafx.application.Platform; @@ -83,7 +85,9 @@ public final class canvasfx implements Module { } } - public static void initConstants() { + @Override + public Map constants() { + final var result = new HashMap(11); // Color class final Map colors = Arrays.stream(Color.class.getDeclaredFields()) .filter(f -> Modifier.isStatic(f.getModifiers())) @@ -98,94 +102,96 @@ public final class canvasfx implements Module { colors.put(new StringValue("rgb"), new FunctionValue(new rgbColor())); colors.put(new StringValue("hsb"), new FunctionValue(new hsbColor())); colors.put(new StringValue("web"), new FunctionValue(new webColor())); - ScopeHandler.setConstant("Color", new MapValue(colors)); + result.put("Color", new MapValue(colors)); final MapValue arcType = new MapValue(ArcType.values().length); for (ArcType value : ArcType.values()) { arcType.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("ArcType", arcType); + result.put("ArcType", arcType); final MapValue fillRule = new MapValue(FillRule.values().length); for (FillRule value : FillRule.values()) { fillRule.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("FillRule", fillRule); + result.put("FillRule", fillRule); final MapValue blendMode = new MapValue(BlendMode.values().length); for (BlendMode value : BlendMode.values()) { blendMode.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("BlendMode", blendMode); + result.put("BlendMode", blendMode); final MapValue lineCap = new MapValue(StrokeLineCap.values().length); for (StrokeLineCap value : StrokeLineCap.values()) { lineCap.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("StrokeLineCap", lineCap); + result.put("StrokeLineCap", lineCap); final MapValue lineJoin = new MapValue(StrokeLineJoin.values().length); for (StrokeLineJoin value : StrokeLineJoin.values()) { lineJoin.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("StrokeLineJoin", lineJoin); + result.put("StrokeLineJoin", lineJoin); final MapValue textAlignment = new MapValue(TextAlignment.values().length); for (TextAlignment value : TextAlignment.values()) { textAlignment.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("TextAlignment", textAlignment); + result.put("TextAlignment", textAlignment); final MapValue vPos = new MapValue(VPos.values().length); for (VPos value : VPos.values()) { vPos.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("VPos", vPos); + result.put("VPos", vPos); final MapValue events = new MapValue(Events.values().length); for (Events value : Events.values()) { events.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("Events", events); + result.put("Events", events); final MapValue mouseButton = new MapValue(MouseButton.values().length); for (MouseButton value : MouseButton.values()) { mouseButton.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("MouseButton", mouseButton); + result.put("MouseButton", mouseButton); final MapValue keyCodes = new MapValue(KeyCode.values().length); for (KeyCode value : KeyCode.values()) { keyCodes.set(value.name(), NumberValue.of(value.ordinal())); } - ScopeHandler.setConstant("KeyCode", keyCodes); + result.put("KeyCode", keyCodes); + return result; } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("window", new CreateWindow()); - ScopeHandler.setFunction("repaint", new Repaint()); - - ScopeHandler.setFunction("BlendEffect", new BlendEffect()); - ScopeHandler.setFunction("BloomEffect", new BloomEffect()); - ScopeHandler.setFunction("BoxBlurEffect", new BoxBlurEffect()); - ScopeHandler.setFunction("ColorAdjustEffect", new ColorAdjustEffect()); - ScopeHandler.setFunction("ColorInputEffect", new ColorInputEffect()); - ScopeHandler.setFunction("DropShadowEffect", new DropShadowEffect()); - ScopeHandler.setFunction("GaussianBlurEffect", new GaussianBlurEffect()); - ScopeHandler.setFunction("GlowEffect", new GlowEffect()); - ScopeHandler.setFunction("InnerShadowEffect", new InnerShadowEffect()); - ScopeHandler.setFunction("LightingEffect", new LightingEffect()); - ScopeHandler.setFunction("MotionBlurEffect", new MotionBlurEffect()); - ScopeHandler.setFunction("PerspectiveTransformEffect", new PerspectiveTransformEffect()); - ScopeHandler.setFunction("ReflectionEffect", new ReflectionEffect()); - ScopeHandler.setFunction("SepiaToneEffect", new SepiaToneEffect()); - ScopeHandler.setFunction("ShadowEffect", new ShadowEffect()); - - ScopeHandler.setFunction("addEventFilter", new addEventFilter()); - ScopeHandler.setFunction("addEventHandler", new addEventHandler()); - ScopeHandler.setFunction("createImage", new createImage()); + public Map functions() { + final var result = new LinkedHashMap(20); + result.put("window", new CreateWindow()); + result.put("repaint", new Repaint()); + + result.put("BlendEffect", new BlendEffect()); + result.put("BloomEffect", new BloomEffect()); + result.put("BoxBlurEffect", new BoxBlurEffect()); + result.put("ColorAdjustEffect", new ColorAdjustEffect()); + result.put("ColorInputEffect", new ColorInputEffect()); + result.put("DropShadowEffect", new DropShadowEffect()); + result.put("GaussianBlurEffect", new GaussianBlurEffect()); + result.put("GlowEffect", new GlowEffect()); + result.put("InnerShadowEffect", new InnerShadowEffect()); + result.put("LightingEffect", new LightingEffect()); + result.put("MotionBlurEffect", new MotionBlurEffect()); + result.put("PerspectiveTransformEffect", new PerspectiveTransformEffect()); + result.put("ReflectionEffect", new ReflectionEffect()); + result.put("SepiaToneEffect", new SepiaToneEffect()); + result.put("ShadowEffect", new ShadowEffect()); + + result.put("addEventFilter", new addEventFilter()); + result.put("addEventHandler", new addEventHandler()); + result.put("createImage", new createImage()); + return result; } private static class ColorValue implements Value { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/base64/base64.java b/modules/main/src/main/java/com/annimon/ownlang/modules/base64/base64.java index 1796403..15074a7 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/base64/base64.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/base64/base64.java @@ -4,21 +4,24 @@ import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.Map; public class base64 implements Module { private static final int TYPE_URL_SAFE = 8; - public static void initConstants() { - ScopeHandler.setConstant("BASE64_URL_SAFE", NumberValue.of(TYPE_URL_SAFE)); + @Override + public Map constants() { + return Map.of("BASE64_URL_SAFE", NumberValue.of(TYPE_URL_SAFE)); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("base64encode", this::base64encode); - ScopeHandler.setFunction("base64decode", this::base64decode); - ScopeHandler.setFunction("base64encodeToString", this::base64encodeToString); + public Map functions() { + return Map.of( + "base64encode", this::base64encode, + "base64decode", this::base64decode, + "base64encodeToString", this::base64encodeToString + ); } private Value base64encode(Value[] args) { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/canvas/canvas.java b/modules/main/src/main/java/com/annimon/ownlang/modules/canvas/canvas.java index 6172798..d4b5a6e 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/canvas/canvas.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/canvas/canvas.java @@ -12,9 +12,12 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.image.BufferedImage; +import java.util.LinkedHashMap; +import java.util.Map; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; +import static java.util.Map.entry; /** * @@ -29,36 +32,41 @@ public final class canvas implements Module { private static NumberValue lastKey; private static ArrayValue mouseHover; - public static void initConstants() { - ScopeHandler.setConstant("VK_UP", NumberValue.of(KeyEvent.VK_UP)); - ScopeHandler.setConstant("VK_DOWN", NumberValue.of(KeyEvent.VK_DOWN)); - ScopeHandler.setConstant("VK_LEFT", NumberValue.of(KeyEvent.VK_LEFT)); - ScopeHandler.setConstant("VK_RIGHT", NumberValue.of(KeyEvent.VK_RIGHT)); - ScopeHandler.setConstant("VK_FIRE", NumberValue.of(KeyEvent.VK_ENTER)); - ScopeHandler.setConstant("VK_ESCAPE", NumberValue.of(KeyEvent.VK_ESCAPE)); + + @Override + public Map constants() { + return Map.ofEntries( + entry("VK_UP", NumberValue.of(KeyEvent.VK_UP)), + entry("VK_DOWN", NumberValue.of(KeyEvent.VK_DOWN)), + entry("VK_LEFT", NumberValue.of(KeyEvent.VK_LEFT)), + entry("VK_RIGHT", NumberValue.of(KeyEvent.VK_RIGHT)), + entry("VK_FIRE", NumberValue.of(KeyEvent.VK_ENTER)), + entry("VK_ESCAPE", NumberValue.of(KeyEvent.VK_ESCAPE)) + ); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("window", new CreateWindow()); - ScopeHandler.setFunction("prompt", new Prompt()); - ScopeHandler.setFunction("keypressed", new KeyPressed()); - ScopeHandler.setFunction("mousehover", new MouseHover()); - ScopeHandler.setFunction("line", intConsumer4Convert(canvas::line)); - ScopeHandler.setFunction("oval", intConsumer4Convert(canvas::oval)); - ScopeHandler.setFunction("foval", intConsumer4Convert(canvas::foval)); - ScopeHandler.setFunction("rect", intConsumer4Convert(canvas::rect)); - ScopeHandler.setFunction("frect", intConsumer4Convert(canvas::frect)); - ScopeHandler.setFunction("clip", intConsumer4Convert(canvas::clip)); - ScopeHandler.setFunction("drawstring", new DrawString()); - ScopeHandler.setFunction("color", new SetColor()); - ScopeHandler.setFunction("repaint", new Repaint()); - + public Map functions() { lastKey = NumberValue.MINUS_ONE; mouseHover = new ArrayValue(new Value[] { NumberValue.ZERO, NumberValue.ZERO }); + + final var result = new LinkedHashMap(15); + result.put("window", new CreateWindow()); + result.put("prompt", new Prompt()); + result.put("keypressed", new KeyPressed()); + result.put("mousehover", new MouseHover()); + result.put("line", intConsumer4Convert(canvas::line)); + result.put("oval", intConsumer4Convert(canvas::oval)); + result.put("foval", intConsumer4Convert(canvas::foval)); + result.put("rect", intConsumer4Convert(canvas::rect)); + result.put("frect", intConsumer4Convert(canvas::frect)); + result.put("clip", intConsumer4Convert(canvas::clip)); + result.put("drawstring", new DrawString()); + result.put("color", new SetColor()); + result.put("repaint", new Repaint()); + return result; } - + @FunctionalInterface private interface IntConsumer4 { void accept(int i1, int i2, int i3, int i4); diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/collections/collections.java b/modules/main/src/main/java/com/annimon/ownlang/modules/collections/collections.java index 4a26bb0..b01fa02 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/collections/collections.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/collections/collections.java @@ -3,29 +3,28 @@ package com.annimon.ownlang.modules.collections; import com.annimon.ownlang.exceptions.TypeException; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.function.Supplier; +import static java.util.Map.entry; public class collections implements Module { - public static void initConstants() { + @Override + public Map constants() { + return Collections.emptyMap(); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("hashMap", mapFunction(HashMap::new)); - ScopeHandler.setFunction("linkedHashMap", mapFunction(LinkedHashMap::new)); - ScopeHandler.setFunction("concurrentHashMap", mapFunction(ConcurrentHashMap::new)); - ScopeHandler.setFunction("treeMap", sortedMapFunction(TreeMap::new, TreeMap::new)); - ScopeHandler.setFunction("concurrentSkipListMap", sortedMapFunction(ConcurrentSkipListMap::new, ConcurrentSkipListMap::new)); + public Map functions() { + return Map.ofEntries( + entry("hashMap", mapFunction(HashMap::new)), + entry("linkedHashMap", mapFunction(LinkedHashMap::new)), + entry("concurrentHashMap", mapFunction(ConcurrentHashMap::new)), + entry("treeMap", sortedMapFunction(TreeMap::new, TreeMap::new)), + entry("concurrentSkipListMap", sortedMapFunction(ConcurrentSkipListMap::new, ConcurrentSkipListMap::new)) + ); } private Function mapFunction(final Supplier> mapSupplier) { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/date/date.java b/modules/main/src/main/java/com/annimon/ownlang/modules/date/date.java index f0185bd..6642410 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/date/date.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/date/date.java @@ -6,9 +6,7 @@ import com.annimon.ownlang.modules.Module; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; +import java.util.*; /** * @@ -27,21 +25,25 @@ public final class date implements Module { SECOND = new StringValue("second"), MILLISECOND = new StringValue("millisecond"); - public static void initConstants() { - ScopeHandler.setConstant("STYLE_FULL", NumberValue.of(DateFormat.FULL)); - ScopeHandler.setConstant("STYLE_LONG", NumberValue.of(DateFormat.LONG)); - ScopeHandler.setConstant("STYLE_MEDIUM", NumberValue.of(DateFormat.MEDIUM)); - ScopeHandler.setConstant("STYLE_SHORT", NumberValue.of(DateFormat.SHORT)); + @Override + public Map constants() { + return Map.of( + "STYLE_FULL", NumberValue.of(DateFormat.FULL), + "STYLE_LONG", NumberValue.of(DateFormat.LONG), + "STYLE_MEDIUM", NumberValue.of(DateFormat.MEDIUM), + "STYLE_SHORT", NumberValue.of(DateFormat.SHORT) + ); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("newDate", new date_newDate()); - ScopeHandler.setFunction("newFormat", new date_newFormat()); - ScopeHandler.setFunction("formatDate", new date_format()); - ScopeHandler.setFunction("parseDate", new date_parse()); - ScopeHandler.setFunction("toTimestamp", new date_toTimestamp()); + public Map functions() { + return Map.of( + "newDate", new date_newDate(), + "newFormat", new date_newFormat(), + "formatDate", new date_format(), + "parseDate", new date_parse(), + "toTimestamp", new date_toTimestamp() + ); } // diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/downloader/downloader.java b/modules/main/src/main/java/com/annimon/ownlang/modules/downloader/downloader.java index acfcc04..949fc33 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/downloader/downloader.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/downloader/downloader.java @@ -9,13 +9,22 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.util.Collections; +import java.util.Map; public final class downloader implements Module { @Override - public void init() { - ScopeHandler.setFunction("getContentLength", this::getContentLength); - ScopeHandler.setFunction("downloader", this::downloader); + public Map constants() { + return Collections.emptyMap(); + } + + @Override + public Map functions() { + return Map.of( + "getContentLength", this::getContentLength, + "downloader", this::downloader + ); } private Value getContentLength(Value[] args) { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/files/files.java b/modules/main/src/main/java/com/annimon/ownlang/modules/files/files.java index 2335e38..31e1c76 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/files/files.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/files/files.java @@ -18,6 +18,7 @@ import java.io.OutputStreamWriter; import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; /** @@ -28,71 +29,74 @@ public final class files implements Module { private static Map files; - public static void initConstants() { - ScopeHandler.setConstant("FILES_COMPARATOR", new FunctionValue(new filesComparatorFunction())); + @Override + public Map constants() { + return Map.of( + "FILES_COMPARATOR", new FunctionValue(new filesComparatorFunction()) + ); } @Override - public void init() { + public Map functions() { files = new HashMap<>(); - initConstants(); + final var result = new LinkedHashMap(50); + result.put("fopen", new fopen()); + result.put("flush", new flush()); + result.put("fclose", new fclose()); - ScopeHandler.setFunction("fopen", new fopen()); - ScopeHandler.setFunction("flush", new flush()); - ScopeHandler.setFunction("fclose", new fclose()); - // Operations - ScopeHandler.setFunction("copy", new copy()); - ScopeHandler.setFunction("delete", fileToBoolean(File::delete)); - ScopeHandler.setFunction("listFiles", new listFiles()); - ScopeHandler.setFunction("mkdir", fileToBoolean(File::mkdir)); - ScopeHandler.setFunction("mkdirs", fileToBoolean(File::mkdirs)); - ScopeHandler.setFunction("rename", new rename()); + result.put("copy", new copy()); + result.put("delete", fileToBoolean(File::delete)); + result.put("listFiles", new listFiles()); + result.put("mkdir", fileToBoolean(File::mkdir)); + result.put("mkdirs", fileToBoolean(File::mkdirs)); + result.put("rename", new rename()); // Permissions and statuses - ScopeHandler.setFunction("canExecute", fileToBoolean(File::canExecute)); - ScopeHandler.setFunction("canRead", fileToBoolean(File::canRead)); - ScopeHandler.setFunction("canWrite", fileToBoolean(File::canWrite)); - ScopeHandler.setFunction("isDirectory", fileToBoolean(File::isDirectory)); - ScopeHandler.setFunction("isFile", fileToBoolean(File::isFile)); - ScopeHandler.setFunction("isHidden", fileToBoolean(File::isHidden)); - ScopeHandler.setFunction("setExecutable", new setExecutable()); - ScopeHandler.setFunction("setReadable", new setReadable()); - ScopeHandler.setFunction("setReadOnly", new setReadOnly()); - ScopeHandler.setFunction("setWritable", new setWritable()); + result.put("canExecute", fileToBoolean(File::canExecute)); + result.put("canRead", fileToBoolean(File::canRead)); + result.put("canWrite", fileToBoolean(File::canWrite)); + result.put("isDirectory", fileToBoolean(File::isDirectory)); + result.put("isFile", fileToBoolean(File::isFile)); + result.put("isHidden", fileToBoolean(File::isHidden)); + result.put("setExecutable", new setExecutable()); + result.put("setReadable", new setReadable()); + result.put("setReadOnly", new setReadOnly()); + result.put("setWritable", new setWritable()); - ScopeHandler.setFunction("exists", fileToBoolean(File::exists)); - ScopeHandler.setFunction("fileSize", new fileSize()); - ScopeHandler.setFunction("getParent", new getParent()); - ScopeHandler.setFunction("lastModified", new lastModified()); - ScopeHandler.setFunction("setLastModified", new setLastModified()); + result.put("exists", fileToBoolean(File::exists)); + result.put("fileSize", new fileSize()); + result.put("getParent", new getParent()); + result.put("lastModified", new lastModified()); + result.put("setLastModified", new setLastModified()); // IO - ScopeHandler.setFunction("readBoolean", new readBoolean()); - ScopeHandler.setFunction("readByte", new readByte()); - ScopeHandler.setFunction("readBytes", new readBytes()); - ScopeHandler.setFunction("readAllBytes", new readAllBytes()); - ScopeHandler.setFunction("readChar", new readChar()); - ScopeHandler.setFunction("readShort", new readShort()); - ScopeHandler.setFunction("readInt", new readInt()); - ScopeHandler.setFunction("readLong", new readLong()); - ScopeHandler.setFunction("readFloat", new readFloat()); - ScopeHandler.setFunction("readDouble", new readDouble()); - ScopeHandler.setFunction("readUTF", new readUTF()); - ScopeHandler.setFunction("readLine", new readLine()); - ScopeHandler.setFunction("readText", new readText()); - ScopeHandler.setFunction("writeBoolean", new writeBoolean()); - ScopeHandler.setFunction("writeByte", new writeByte()); - ScopeHandler.setFunction("writeBytes", new writeBytes()); - ScopeHandler.setFunction("writeChar", new writeChar()); - ScopeHandler.setFunction("writeShort", new writeShort()); - ScopeHandler.setFunction("writeInt", new writeInt()); - ScopeHandler.setFunction("writeLong", new writeLong()); - ScopeHandler.setFunction("writeFloat", new writeFloat()); - ScopeHandler.setFunction("writeDouble", new writeDouble()); - ScopeHandler.setFunction("writeUTF", new writeUTF()); - ScopeHandler.setFunction("writeLine", new writeLine()); - ScopeHandler.setFunction("writeText", new writeText()); + result.put("readBoolean", new readBoolean()); + result.put("readByte", new readByte()); + result.put("readBytes", new readBytes()); + result.put("readAllBytes", new readAllBytes()); + result.put("readChar", new readChar()); + result.put("readShort", new readShort()); + result.put("readInt", new readInt()); + result.put("readLong", new readLong()); + result.put("readFloat", new readFloat()); + result.put("readDouble", new readDouble()); + result.put("readUTF", new readUTF()); + result.put("readLine", new readLine()); + result.put("readText", new readText()); + result.put("writeBoolean", new writeBoolean()); + result.put("writeByte", new writeByte()); + result.put("writeBytes", new writeBytes()); + result.put("writeChar", new writeChar()); + result.put("writeShort", new writeShort()); + result.put("writeInt", new writeInt()); + result.put("writeLong", new writeLong()); + result.put("writeFloat", new writeFloat()); + result.put("writeDouble", new writeDouble()); + result.put("writeUTF", new writeUTF()); + result.put("writeLine", new writeLine()); + result.put("writeText", new writeText()); + return result; } private static class filesComparatorFunction implements Function { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/forms/forms.java b/modules/main/src/main/java/com/annimon/ownlang/modules/forms/forms.java index 26331e3..b9dfbd6 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/forms/forms.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/forms/forms.java @@ -4,6 +4,8 @@ import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; import java.awt.BorderLayout; import java.awt.event.WindowEvent; +import java.util.LinkedHashMap; +import java.util.Map; import javax.swing.BoxLayout; import javax.swing.JFrame; import javax.swing.ScrollPaneConstants; @@ -15,14 +17,16 @@ import javax.swing.SwingConstants; */ public final class forms implements Module { - public static void initConstants() { + @Override + public Map constants() { + final var result = new LinkedHashMap(10); // JFrame constants - ScopeHandler.setConstant("DISPOSE_ON_CLOSE", NumberValue.of(JFrame.DISPOSE_ON_CLOSE)); - ScopeHandler.setConstant("DO_NOTHING_ON_CLOSE", NumberValue.of(JFrame.DO_NOTHING_ON_CLOSE)); - ScopeHandler.setConstant("EXIT_ON_CLOSE", NumberValue.of(JFrame.EXIT_ON_CLOSE)); - ScopeHandler.setConstant("HIDE_ON_CLOSE", NumberValue.of(JFrame.HIDE_ON_CLOSE)); + result.put("DISPOSE_ON_CLOSE", NumberValue.of(JFrame.DISPOSE_ON_CLOSE)); + result.put("DO_NOTHING_ON_CLOSE", NumberValue.of(JFrame.DO_NOTHING_ON_CLOSE)); + result.put("EXIT_ON_CLOSE", NumberValue.of(JFrame.EXIT_ON_CLOSE)); + result.put("HIDE_ON_CLOSE", NumberValue.of(JFrame.HIDE_ON_CLOSE)); - // SwinfConstants + // SwingConstants final MapValue swing = new MapValue(20); swing.set("BOTTOM", NumberValue.of(SwingConstants.BOTTOM)); swing.set("CENTER", NumberValue.of(SwingConstants.CENTER)); @@ -43,7 +47,7 @@ public final class forms implements Module { swing.set("TRAILING", NumberValue.of(SwingConstants.TRAILING)); swing.set("VERTICAL", NumberValue.of(SwingConstants.VERTICAL)); swing.set("WEST", NumberValue.of(SwingConstants.WEST)); - ScopeHandler.setConstant("SwingConstants", swing); + result.put("SwingConstants", swing); // LayoutManagers constants final MapValue border = new MapValue(13); @@ -60,7 +64,7 @@ public final class forms implements Module { border.set("PAGE_START", new StringValue(BorderLayout.PAGE_START)); border.set("SOUTH", new StringValue(BorderLayout.SOUTH)); border.set("WEST", new StringValue(BorderLayout.WEST)); - ScopeHandler.setConstant("BorderLayout", border); + result.put("BorderLayout", border); // ScrollPane constants final MapValue scrollpane = new MapValue(13); @@ -85,14 +89,14 @@ public final class forms implements Module { scrollpane.set("VERTICAL_SCROLLBAR_ALWAYS", NumberValue.of(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS)); scrollpane.set("VERTICAL_SCROLLBAR_AS_NEEDED", NumberValue.of(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED)); scrollpane.set("VERTICAL_SCROLLBAR_NEVER", NumberValue.of(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER)); - ScopeHandler.setConstant("ScrollPaneConstants", scrollpane); + result.put("ScrollPaneConstants", scrollpane); final MapValue box = new MapValue(4); box.set("LINE_AXIS", NumberValue.of(BoxLayout.LINE_AXIS)); box.set("PAGE_AXIS", NumberValue.of(BoxLayout.PAGE_AXIS)); box.set("X_AXIS", NumberValue.of(BoxLayout.X_AXIS)); box.set("Y_AXIS", NumberValue.of(BoxLayout.Y_AXIS)); - ScopeHandler.setConstant("BoxLayout", box); + result.put("BoxLayout", box); final MapValue windowEvent = new MapValue(4); windowEvent.set("WINDOW_FIRST", NumberValue.of(WindowEvent.WINDOW_FIRST)); @@ -107,27 +111,29 @@ public final class forms implements Module { windowEvent.set("WINDOW_LOST_FOCUS", NumberValue.of(WindowEvent.WINDOW_LOST_FOCUS)); windowEvent.set("WINDOW_STATE_CHANGED", NumberValue.of(WindowEvent.WINDOW_STATE_CHANGED)); windowEvent.set("WINDOW_LAST", NumberValue.of(WindowEvent.WINDOW_LAST)); - ScopeHandler.setConstant("WindowEvent", windowEvent); + result.put("WindowEvent", windowEvent); + return result; } @Override - public void init() { - initConstants(); + public Map functions() { + final var result = new LinkedHashMap(16); // Components - ScopeHandler.setFunction("newButton", Components::newButton); - ScopeHandler.setFunction("newLabel", Components::newLabel); - ScopeHandler.setFunction("newPanel", Components::newPanel); - ScopeHandler.setFunction("newProgressBar", Components::newProgressBar); - ScopeHandler.setFunction("newScrollPane", Components::newScrollPane); - ScopeHandler.setFunction("newTextArea", Components::newTextArea); - ScopeHandler.setFunction("newTextField", Components::newTextField); - ScopeHandler.setFunction("newWindow", Components::newWindow); + result.put("newButton", Components::newButton); + result.put("newLabel", Components::newLabel); + result.put("newPanel", Components::newPanel); + result.put("newProgressBar", Components::newProgressBar); + result.put("newScrollPane", Components::newScrollPane); + result.put("newTextArea", Components::newTextArea); + result.put("newTextField", Components::newTextField); + result.put("newWindow", Components::newWindow); // LayoutManagers - ScopeHandler.setFunction("borderLayout", LayoutManagers::borderLayout); - ScopeHandler.setFunction("boxLayout", LayoutManagers::boxLayout); - ScopeHandler.setFunction("cardLayout", LayoutManagers::cardLayout); - ScopeHandler.setFunction("gridLayout", LayoutManagers::gridLayout); - ScopeHandler.setFunction("flowLayout", LayoutManagers::flowLayout); + result.put("borderLayout", LayoutManagers::borderLayout); + result.put("boxLayout", LayoutManagers::boxLayout); + result.put("cardLayout", LayoutManagers::cardLayout); + result.put("gridLayout", LayoutManagers::gridLayout); + result.put("flowLayout", LayoutManagers::flowLayout); + return result; } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/functional/functional.java b/modules/main/src/main/java/com/annimon/ownlang/modules/functional/functional.java index 9e2e88d..0ad6188 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/functional/functional.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/functional/functional.java @@ -1,8 +1,11 @@ package com.annimon.ownlang.modules.functional; +import com.annimon.ownlang.lib.Function; import com.annimon.ownlang.lib.FunctionValue; -import com.annimon.ownlang.lib.ScopeHandler; +import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.modules.Module; +import java.util.HashMap; +import java.util.Map; /** * @@ -10,24 +13,26 @@ import com.annimon.ownlang.modules.Module; */ public final class functional implements Module { - public static void initConstants() { - ScopeHandler.setConstant("IDENTITY", new FunctionValue(args -> args[0])); + @Override + public Map constants() { + return Map.of("IDENTITY", new FunctionValue(args -> args[0])); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("foreach", new functional_foreach()); - ScopeHandler.setFunction("map", new functional_map()); - ScopeHandler.setFunction("flatmap", new functional_flatmap()); - ScopeHandler.setFunction("reduce", new functional_reduce()); - ScopeHandler.setFunction("filter", new functional_filter(false)); - ScopeHandler.setFunction("sortby", new functional_sortby()); - ScopeHandler.setFunction("takewhile", new functional_filter(true)); - ScopeHandler.setFunction("dropwhile", new functional_dropwhile()); + public Map functions() { + final var result = new HashMap(15); + result.put("foreach", new functional_foreach()); + result.put("map", new functional_map()); + result.put("flatmap", new functional_flatmap()); + result.put("reduce", new functional_reduce()); + result.put("filter", new functional_filter(false)); + result.put("sortby", new functional_sortby()); + result.put("takewhile", new functional_filter(true)); + result.put("dropwhile", new functional_dropwhile()); - ScopeHandler.setFunction("chain", new functional_chain()); - ScopeHandler.setFunction("stream", new functional_stream()); - ScopeHandler.setFunction("combine", new functional_combine()); + result.put("chain", new functional_chain()); + result.put("stream", new functional_stream()); + result.put("combine", new functional_combine()); + return result; } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/gzip/gzip.java b/modules/main/src/main/java/com/annimon/ownlang/modules/gzip/gzip.java index 14084c7..323b4df 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/gzip/gzip.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/gzip/gzip.java @@ -3,25 +3,27 @@ package com.annimon.ownlang.modules.gzip; import com.annimon.ownlang.exceptions.TypeException; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; +import java.util.Collections; +import java.util.Map; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; public class gzip implements Module { @Override - public void init() { - ScopeHandler.setFunction("gzip", this::gzipFile); - ScopeHandler.setFunction("gzipBytes", this::gzipBytes); - ScopeHandler.setFunction("ungzip", this::ungzipFile); - ScopeHandler.setFunction("ungzipBytes", this::ungzipBytes); + public Map constants() { + return Collections.emptyMap(); + } + + @Override + public Map functions() { + return Map.of( + "gzip", this::gzipFile, + "gzipBytes", this::gzipBytes, + "ungzip", this::ungzipFile, + "ungzipBytes", this::ungzipBytes + ); } private Value gzipFile(Value[] args) { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/http/http.java b/modules/main/src/main/java/com/annimon/ownlang/modules/http/http.java index ebd36fb..4c5fe91 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/http/http.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/http/http.java @@ -1,7 +1,10 @@ package com.annimon.ownlang.modules.http; -import com.annimon.ownlang.lib.ScopeHandler; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.modules.Module; +import java.util.Collections; +import java.util.Map; /** * @@ -9,14 +12,17 @@ import com.annimon.ownlang.modules.Module; */ public final class http implements Module { - public static void initConstants() { + @Override + public Map constants() { + return Collections.emptyMap(); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("urlencode", new http_urlencode()); - ScopeHandler.setFunction("http", new http_http()); - ScopeHandler.setFunction("download", new http_download()); + public Map functions() { + return Map.of( + "urlencode", new http_urlencode(), + "http", new http_http(), + "download", new http_download() + ); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/java/java.java b/modules/main/src/main/java/com/annimon/ownlang/modules/java/java.java index aca88ba..a2f6953 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/java/java.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/java/java.java @@ -7,9 +7,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; +import static java.util.Map.entry; /** * Java interoperability module. @@ -20,48 +19,51 @@ public final class java implements Module { private static final Value NULL = new NullValue(); - public static void initConstants() { + @Override + public Map constants() { + final var result = new LinkedHashMap(16); + result.put("null", NULL); + result.put("boolean.class", new ClassValue(boolean.class)); + result.put("boolean[].class", new ClassValue(boolean[].class)); + result.put("boolean[][].class", new ClassValue(boolean[][].class)); + result.put("byte.class", new ClassValue(byte.class)); + result.put("byte[].class", new ClassValue(byte[].class)); + result.put("byte[][].class", new ClassValue(byte[][].class)); + result.put("short.class", new ClassValue(short.class)); + result.put("short[].class", new ClassValue(short[].class)); + result.put("short[][].class", new ClassValue(short[][].class)); + result.put("char.class", new ClassValue(char.class)); + result.put("char[].class", new ClassValue(char[].class)); + result.put("char[][].class", new ClassValue(char[][].class)); + result.put("int.class", new ClassValue(int.class)); + result.put("int[].class", new ClassValue(int[].class)); + result.put("int[][].class", new ClassValue(int[][].class)); + result.put("long.class", new ClassValue(long.class)); + result.put("long[].class", new ClassValue(long[].class)); + result.put("long[][].class", new ClassValue(long[][].class)); + result.put("float.class", new ClassValue(float.class)); + result.put("float[].class", new ClassValue(float[].class)); + result.put("float[][].class", new ClassValue(float[][].class)); + result.put("double.class", new ClassValue(double.class)); + result.put("double[].class", new ClassValue(double[].class)); + result.put("double[][].class", new ClassValue(double[][].class)); + result.put("String.class", new ClassValue(String.class)); + result.put("String[].class", new ClassValue(String[].class)); + result.put("String[][].class", new ClassValue(String[][].class)); + result.put("Object.class", new ClassValue(Object.class)); + result.put("Object[].class", new ClassValue(Object[].class)); + result.put("Object[][].class", new ClassValue(Object[][].class)); + return result; } @Override - public void init() { - initConstants(); - ScopeHandler.setConstant("null", NULL); - ScopeHandler.setConstant("boolean.class", new ClassValue(boolean.class)); - ScopeHandler.setConstant("boolean[].class", new ClassValue(boolean[].class)); - ScopeHandler.setConstant("boolean[][].class", new ClassValue(boolean[][].class)); - ScopeHandler.setConstant("byte.class", new ClassValue(byte.class)); - ScopeHandler.setConstant("byte[].class", new ClassValue(byte[].class)); - ScopeHandler.setConstant("byte[][].class", new ClassValue(byte[][].class)); - ScopeHandler.setConstant("short.class", new ClassValue(short.class)); - ScopeHandler.setConstant("short[].class", new ClassValue(short[].class)); - ScopeHandler.setConstant("short[][].class", new ClassValue(short[][].class)); - ScopeHandler.setConstant("char.class", new ClassValue(char.class)); - ScopeHandler.setConstant("char[].class", new ClassValue(char[].class)); - ScopeHandler.setConstant("char[][].class", new ClassValue(char[][].class)); - ScopeHandler.setConstant("int.class", new ClassValue(int.class)); - ScopeHandler.setConstant("int[].class", new ClassValue(int[].class)); - ScopeHandler.setConstant("int[][].class", new ClassValue(int[][].class)); - ScopeHandler.setConstant("long.class", new ClassValue(long.class)); - ScopeHandler.setConstant("long[].class", new ClassValue(long[].class)); - ScopeHandler.setConstant("long[][].class", new ClassValue(long[][].class)); - ScopeHandler.setConstant("float.class", new ClassValue(float.class)); - ScopeHandler.setConstant("float[].class", new ClassValue(float[].class)); - ScopeHandler.setConstant("float[][].class", new ClassValue(float[][].class)); - ScopeHandler.setConstant("double.class", new ClassValue(double.class)); - ScopeHandler.setConstant("double[].class", new ClassValue(double[].class)); - ScopeHandler.setConstant("double[][].class", new ClassValue(double[][].class)); - ScopeHandler.setConstant("String.class", new ClassValue(String.class)); - ScopeHandler.setConstant("String[].class", new ClassValue(String[].class)); - ScopeHandler.setConstant("String[][].class", new ClassValue(String[][].class)); - ScopeHandler.setConstant("Object.class", new ClassValue(Object.class)); - ScopeHandler.setConstant("Object[].class", new ClassValue(Object[].class)); - ScopeHandler.setConstant("Object[][].class", new ClassValue(Object[][].class)); - - ScopeHandler.setFunction("isNull", this::isNull); - ScopeHandler.setFunction("newClass", this::newClass); - ScopeHandler.setFunction("toObject", this::toObject); - ScopeHandler.setFunction("toValue", this::toValue); + public Map functions() { + return Map.ofEntries( + entry("isNull", this::isNull), + entry("newClass", this::newClass), + entry("toObject", this::toObject), + entry("toValue", this::toValue) + ); } // diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/jdbc/jdbc.java b/modules/main/src/main/java/com/annimon/ownlang/modules/jdbc/jdbc.java index a027a14..165eec7 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/jdbc/jdbc.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/jdbc/jdbc.java @@ -16,6 +16,8 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; @@ -25,39 +27,43 @@ import java.util.function.Function; */ public final class jdbc implements Module { - public static void initConstants() { - ScopeHandler.setConstant("TRANSACTION_NONE", NumberValue.of(Connection.TRANSACTION_NONE)); - ScopeHandler.setConstant("TRANSACTION_READ_COMMITTED", NumberValue.of(Connection.TRANSACTION_READ_COMMITTED)); - ScopeHandler.setConstant("TRANSACTION_READ_UNCOMMITTED", NumberValue.of(Connection.TRANSACTION_READ_UNCOMMITTED)); - ScopeHandler.setConstant("TRANSACTION_REPEATABLE_READ", NumberValue.of(Connection.TRANSACTION_REPEATABLE_READ)); - ScopeHandler.setConstant("TRANSACTION_SERIALIZABLE", NumberValue.of(Connection.TRANSACTION_SERIALIZABLE)); + @Override + public Map constants() { + final var result = new LinkedHashMap(25); + result.put("TRANSACTION_NONE", NumberValue.of(Connection.TRANSACTION_NONE)); + result.put("TRANSACTION_READ_COMMITTED", NumberValue.of(Connection.TRANSACTION_READ_COMMITTED)); + result.put("TRANSACTION_READ_UNCOMMITTED", NumberValue.of(Connection.TRANSACTION_READ_UNCOMMITTED)); + result.put("TRANSACTION_REPEATABLE_READ", NumberValue.of(Connection.TRANSACTION_REPEATABLE_READ)); + result.put("TRANSACTION_SERIALIZABLE", NumberValue.of(Connection.TRANSACTION_SERIALIZABLE)); - ScopeHandler.setConstant("CLOSE_ALL_RESULTS", NumberValue.of(Statement.CLOSE_ALL_RESULTS)); - ScopeHandler.setConstant("CLOSE_CURRENT_RESULT", NumberValue.of(Statement.CLOSE_CURRENT_RESULT)); - ScopeHandler.setConstant("EXECUTE_FAILED", NumberValue.of(Statement.EXECUTE_FAILED)); - ScopeHandler.setConstant("KEEP_CURRENT_RESULT", NumberValue.of(Statement.KEEP_CURRENT_RESULT)); - ScopeHandler.setConstant("NO_GENERATED_KEYS", NumberValue.of(Statement.NO_GENERATED_KEYS)); - ScopeHandler.setConstant("RETURN_GENERATED_KEYS", NumberValue.of(Statement.RETURN_GENERATED_KEYS)); - ScopeHandler.setConstant("SUCCESS_NO_INFO", NumberValue.of(Statement.SUCCESS_NO_INFO)); + result.put("CLOSE_ALL_RESULTS", NumberValue.of(Statement.CLOSE_ALL_RESULTS)); + result.put("CLOSE_CURRENT_RESULT", NumberValue.of(Statement.CLOSE_CURRENT_RESULT)); + result.put("EXECUTE_FAILED", NumberValue.of(Statement.EXECUTE_FAILED)); + result.put("KEEP_CURRENT_RESULT", NumberValue.of(Statement.KEEP_CURRENT_RESULT)); + result.put("NO_GENERATED_KEYS", NumberValue.of(Statement.NO_GENERATED_KEYS)); + result.put("RETURN_GENERATED_KEYS", NumberValue.of(Statement.RETURN_GENERATED_KEYS)); + result.put("SUCCESS_NO_INFO", NumberValue.of(Statement.SUCCESS_NO_INFO)); - ScopeHandler.setConstant("CLOSE_CURSORS_AT_COMMIT", NumberValue.of(ResultSet.CLOSE_CURSORS_AT_COMMIT)); - ScopeHandler.setConstant("CONCUR_READ_ONLY", NumberValue.of(ResultSet.CONCUR_READ_ONLY)); - ScopeHandler.setConstant("CONCUR_UPDATABLE", NumberValue.of(ResultSet.CONCUR_UPDATABLE)); - ScopeHandler.setConstant("FETCH_FORWARD", NumberValue.of(ResultSet.FETCH_FORWARD)); - ScopeHandler.setConstant("FETCH_REVERSE", NumberValue.of(ResultSet.FETCH_REVERSE)); - ScopeHandler.setConstant("FETCH_UNKNOWN", NumberValue.of(ResultSet.FETCH_UNKNOWN)); - ScopeHandler.setConstant("HOLD_CURSORS_OVER_COMMIT", NumberValue.of(ResultSet.HOLD_CURSORS_OVER_COMMIT)); - ScopeHandler.setConstant("TYPE_FORWARD_ONLY", NumberValue.of(ResultSet.TYPE_FORWARD_ONLY)); - ScopeHandler.setConstant("TYPE_SCROLL_INSENSITIVE", NumberValue.of(ResultSet.TYPE_SCROLL_INSENSITIVE)); - ScopeHandler.setConstant("TYPE_SCROLL_SENSITIVE", NumberValue.of(ResultSet.TYPE_SCROLL_SENSITIVE)); + result.put("CLOSE_CURSORS_AT_COMMIT", NumberValue.of(ResultSet.CLOSE_CURSORS_AT_COMMIT)); + result.put("CONCUR_READ_ONLY", NumberValue.of(ResultSet.CONCUR_READ_ONLY)); + result.put("CONCUR_UPDATABLE", NumberValue.of(ResultSet.CONCUR_UPDATABLE)); + result.put("FETCH_FORWARD", NumberValue.of(ResultSet.FETCH_FORWARD)); + result.put("FETCH_REVERSE", NumberValue.of(ResultSet.FETCH_REVERSE)); + result.put("FETCH_UNKNOWN", NumberValue.of(ResultSet.FETCH_UNKNOWN)); + result.put("HOLD_CURSORS_OVER_COMMIT", NumberValue.of(ResultSet.HOLD_CURSORS_OVER_COMMIT)); + result.put("TYPE_FORWARD_ONLY", NumberValue.of(ResultSet.TYPE_FORWARD_ONLY)); + result.put("TYPE_SCROLL_INSENSITIVE", NumberValue.of(ResultSet.TYPE_SCROLL_INSENSITIVE)); + result.put("TYPE_SCROLL_SENSITIVE", NumberValue.of(ResultSet.TYPE_SCROLL_SENSITIVE)); + return result; } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("getConnection", getConnectionFunction()); - ScopeHandler.setFunction("sqlite", getConnectionFunction("jdbc:sqlite:")); - ScopeHandler.setFunction("mysql", getConnectionFunction("jdbc:")); + public Map functions() { + return Map.of( + "getConnection", getConnectionFunction(), + "sqlite", getConnectionFunction("jdbc:sqlite:"), + "mysql", getConnectionFunction("jdbc:") + ); } private static com.annimon.ownlang.lib.Function getConnectionFunction() { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/json/json.java b/modules/main/src/main/java/com/annimon/ownlang/modules/json/json.java index 3b3a715..97cce63 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/json/json.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/json/json.java @@ -1,7 +1,10 @@ package com.annimon.ownlang.modules.json; -import com.annimon.ownlang.lib.ScopeHandler; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.modules.Module; +import java.util.Collections; +import java.util.Map; /** * @@ -9,13 +12,16 @@ import com.annimon.ownlang.modules.Module; */ public final class json implements Module { - public static void initConstants() { + @Override + public Map constants() { + return Collections.emptyMap(); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("jsonencode", new json_encode()); - ScopeHandler.setFunction("jsondecode", new json_decode()); + public Map functions() { + return Map.of( + "jsonencode", new json_encode(), + "jsondecode", new json_decode() + ); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/math/math.java b/modules/main/src/main/java/com/annimon/ownlang/modules/math/math.java index 3225461..e6b0e56 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/math/math.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/math/math.java @@ -2,6 +2,8 @@ package com.annimon.ownlang.modules.math; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.function.DoubleBinaryOperator; import java.util.function.DoubleFunction; import java.util.function.DoubleUnaryOperator; @@ -15,50 +17,54 @@ public final class math implements Module { private static final DoubleFunction doubleToNumber = NumberValue::of; - public static void initConstants() { - ScopeHandler.setConstant("PI", NumberValue.of(Math.PI)); - ScopeHandler.setConstant("E", NumberValue.of(Math.E)); + @Override + public Map constants() { + return Map.of( + "PI", NumberValue.of(Math.PI), + "E", NumberValue.of(Math.E) + ); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("abs", math::abs); - ScopeHandler.setFunction("acos", functionConvert(Math::acos)); - ScopeHandler.setFunction("asin", functionConvert(Math::asin)); - ScopeHandler.setFunction("atan", functionConvert(Math::atan)); - ScopeHandler.setFunction("atan2", biFunctionConvert(Math::atan2)); - ScopeHandler.setFunction("cbrt", functionConvert(Math::cbrt)); - ScopeHandler.setFunction("ceil", functionConvert(Math::ceil)); - ScopeHandler.setFunction("copySign", math::copySign); - ScopeHandler.setFunction("cos", functionConvert(Math::cos)); - ScopeHandler.setFunction("cosh", functionConvert(Math::cosh)); - ScopeHandler.setFunction("exp", functionConvert(Math::exp)); - ScopeHandler.setFunction("expm1", functionConvert(Math::expm1)); - ScopeHandler.setFunction("floor", functionConvert(Math::floor)); - ScopeHandler.setFunction("getExponent", math::getExponent); - ScopeHandler.setFunction("hypot", biFunctionConvert(Math::hypot)); - ScopeHandler.setFunction("IEEEremainder", biFunctionConvert(Math::IEEEremainder)); - ScopeHandler.setFunction("log", functionConvert(Math::log)); - ScopeHandler.setFunction("log1p", functionConvert(Math::log1p)); - ScopeHandler.setFunction("log10", functionConvert(Math::log10)); - ScopeHandler.setFunction("max", math::max); - ScopeHandler.setFunction("min", math::min); - ScopeHandler.setFunction("nextAfter", math::nextAfter); - ScopeHandler.setFunction("nextUp", functionConvert(Math::nextUp, Math::nextUp)); - ScopeHandler.setFunction("nextDown", functionConvert(Math::nextDown, Math::nextDown)); - ScopeHandler.setFunction("pow", biFunctionConvert(Math::pow)); - ScopeHandler.setFunction("rint", functionConvert(Math::rint)); - ScopeHandler.setFunction("round", math::round); - ScopeHandler.setFunction("signum", functionConvert(Math::signum, Math::signum)); - ScopeHandler.setFunction("sin", functionConvert(Math::sin)); - ScopeHandler.setFunction("sinh", functionConvert(Math::sinh)); - ScopeHandler.setFunction("sqrt", functionConvert(Math::sqrt)); - ScopeHandler.setFunction("tan", functionConvert(Math::tan)); - ScopeHandler.setFunction("tanh", functionConvert(Math::tanh)); - ScopeHandler.setFunction("toDegrees", functionConvert(Math::toDegrees)); - ScopeHandler.setFunction("toRadians", functionConvert(Math::toRadians)); - ScopeHandler.setFunction("ulp", functionConvert(Math::ulp, Math::ulp)); + public Map functions() { + final var result = new LinkedHashMap(16); + result.put("abs", math::abs); + result.put("acos", functionConvert(Math::acos)); + result.put("asin", functionConvert(Math::asin)); + result.put("atan", functionConvert(Math::atan)); + result.put("atan2", biFunctionConvert(Math::atan2)); + result.put("cbrt", functionConvert(Math::cbrt)); + result.put("ceil", functionConvert(Math::ceil)); + result.put("copySign", math::copySign); + result.put("cos", functionConvert(Math::cos)); + result.put("cosh", functionConvert(Math::cosh)); + result.put("exp", functionConvert(Math::exp)); + result.put("expm1", functionConvert(Math::expm1)); + result.put("floor", functionConvert(Math::floor)); + result.put("getExponent", math::getExponent); + result.put("hypot", biFunctionConvert(Math::hypot)); + result.put("IEEEremainder", biFunctionConvert(Math::IEEEremainder)); + result.put("log", functionConvert(Math::log)); + result.put("log1p", functionConvert(Math::log1p)); + result.put("log10", functionConvert(Math::log10)); + result.put("max", math::max); + result.put("min", math::min); + result.put("nextAfter", math::nextAfter); + result.put("nextUp", functionConvert(Math::nextUp, Math::nextUp)); + result.put("nextDown", functionConvert(Math::nextDown, Math::nextDown)); + result.put("pow", biFunctionConvert(Math::pow)); + result.put("rint", functionConvert(Math::rint)); + result.put("round", math::round); + result.put("signum", functionConvert(Math::signum, Math::signum)); + result.put("sin", functionConvert(Math::sin)); + result.put("sinh", functionConvert(Math::sinh)); + result.put("sqrt", functionConvert(Math::sqrt)); + result.put("tan", functionConvert(Math::tan)); + result.put("tanh", functionConvert(Math::tanh)); + result.put("toDegrees", functionConvert(Math::toDegrees)); + result.put("toRadians", functionConvert(Math::toRadians)); + result.put("ulp", functionConvert(Math::ulp, Math::ulp)); + return result; } private static Value abs(Value[] args) { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java index 77d465a..c593d6d 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java @@ -8,12 +8,15 @@ import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.RequestBody; +import java.util.Collections; +import java.util.Map; public final class okhttp implements Module { private static final HttpClientValue defaultClient = new HttpClientValue(new OkHttpClient()); - public static void initConstants() { + @Override + public Map constants() { MapValue requestBody = new MapValue(5); requestBody.set("bytes", args -> { Arguments.checkOrOr(2, 4, args.length); @@ -49,27 +52,30 @@ public final class okhttp implements Module { args[1].asString() )); }); - ScopeHandler.setConstant("RequestBody", requestBody); - MapValue multipartBody = new MapValue(10); + MapValue multipartBody = new MapValue(6); multipartBody.set("ALTERNATIVE", new StringValue(MultipartBody.ALTERNATIVE.toString())); multipartBody.set("DIGEST", new StringValue(MultipartBody.DIGEST.toString())); multipartBody.set("FORM", new StringValue(MultipartBody.FORM.toString())); multipartBody.set("MIXED", new StringValue(MultipartBody.MIXED.toString())); multipartBody.set("PARALLEL", new StringValue(MultipartBody.PARALLEL.toString())); multipartBody.set("builder", args -> new MultipartBodyBuilderValue()); - ScopeHandler.setConstant("MultipartBody", multipartBody); - MapValue okhttp = new MapValue(5); + MapValue okhttp = new MapValue(3); okhttp.set("client", defaultClient); okhttp.set("request", args -> new RequestBuilderValue()); - ScopeHandler.setConstant("okhttp", okhttp); + + return Map.of( + "RequestBody", requestBody, + "MultipartBody", multipartBody, + "okhttp", okhttp + ); } @Override - public void init() { - initConstants(); + public Map functions() { + return Collections.emptyMap(); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/ounit/ounit.java b/modules/main/src/main/java/com/annimon/ownlang/modules/ounit/ounit.java index e8a3d0c..07463c4 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/ounit/ounit.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/ounit/ounit.java @@ -4,7 +4,10 @@ import com.annimon.ownlang.Console; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; import java.text.DecimalFormat; +import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; /** * @@ -12,18 +15,21 @@ import java.util.List; */ public final class ounit implements Module { - public static void initConstants() { + @Override + public Map constants() { + return Collections.emptyMap(); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("assertEquals", new assertEquals()); - ScopeHandler.setFunction("assertNotEquals", new assertNotEquals()); - ScopeHandler.setFunction("assertSameType", new assertSameType()); - ScopeHandler.setFunction("assertTrue", new assertTrue()); - ScopeHandler.setFunction("assertFalse", new assertFalse()); - ScopeHandler.setFunction("runTests", new runTests()); + public Map functions() { + final var result = new LinkedHashMap(16); + result.put("assertEquals", new assertEquals()); + result.put("assertNotEquals", new assertNotEquals()); + result.put("assertSameType", new assertSameType()); + result.put("assertTrue", new assertTrue()); + result.put("assertFalse", new assertFalse()); + result.put("runTests", new runTests()); + return result; } private static String microsToSeconds(long micros) { @@ -35,7 +41,7 @@ public final class ounit implements Module { public Value execute(Value[] args) { Arguments.check(2, args.length); if (args[0].equals(args[1])) return NumberValue.ONE; - throw new OUnitAssertionException("Values are not equals: " + throw new OUnitAssertionException("Values are not equal: " + "1: " + args[0] + ", 2: " + args[1]); } } @@ -45,7 +51,7 @@ public final class ounit implements Module { public Value execute(Value[] args) { Arguments.check(2, args.length); if (!args[0].equals(args[1])) return NumberValue.ONE; - throw new OUnitAssertionException("Values are equals: " + args[0]); + throw new OUnitAssertionException("Values are equal: " + args[0]); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/regex/regex.java b/modules/main/src/main/java/com/annimon/ownlang/modules/regex/regex.java index f79ede5..5ef9668 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/regex/regex.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/regex/regex.java @@ -2,11 +2,13 @@ package com.annimon.ownlang.modules.regex; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; +import java.util.Map; import java.util.regex.Pattern; public final class regex implements Module { - public static void initConstants() { + @Override + public Map constants() { MapValue map = new MapValue(20); map.set("UNIX_LINES", NumberValue.of(Pattern.UNIX_LINES)); map.set("I", NumberValue.of(Pattern.CASE_INSENSITIVE)); @@ -37,13 +39,12 @@ public final class regex implements Module { return ArrayValue.of(pattern.split(args[1].asString(), limit)); }); map.set("compile", regex::compile); - ScopeHandler.setConstant("Pattern", map); + return Map.of("Pattern", map); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("regex", regex::compile); + public Map functions() { + return Map.of("regex", regex::compile); } private static Value compile(Value[] args) { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/robot/robot.java b/modules/main/src/main/java/com/annimon/ownlang/modules/robot/robot.java index fc519ec..f82a916 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/robot/robot.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/robot/robot.java @@ -9,6 +9,7 @@ import java.awt.event.KeyEvent; import java.util.HashMap; import java.util.Map; import java.util.function.IntConsumer; +import static java.util.Map.entry; /** * @@ -28,50 +29,42 @@ public final class robot implements Module { private static Robot awtRobot; - public static void initConstants() { - ScopeHandler.setConstant("VK_DOWN", NumberValue.of(KeyEvent.VK_DOWN)); - ScopeHandler.setConstant("VK_LEFT", NumberValue.of(KeyEvent.VK_LEFT)); - ScopeHandler.setConstant("VK_RIGHT", NumberValue.of(KeyEvent.VK_RIGHT)); - ScopeHandler.setConstant("VK_FIRE", NumberValue.of(KeyEvent.VK_ENTER)); - ScopeHandler.setConstant("VK_ESCAPE", NumberValue.of(KeyEvent.VK_ESCAPE)); + @Override + public Map constants() { + return Map.ofEntries( + entry("VK_DOWN", NumberValue.of(KeyEvent.VK_DOWN)), + entry("VK_LEFT", NumberValue.of(KeyEvent.VK_LEFT)), + entry("VK_RIGHT", NumberValue.of(KeyEvent.VK_RIGHT)), + entry("VK_FIRE", NumberValue.of(KeyEvent.VK_ENTER)), + entry("VK_ESCAPE", NumberValue.of(KeyEvent.VK_ESCAPE)), - ScopeHandler.setConstant("BUTTON1", NumberValue.of(InputEvent.BUTTON1_MASK)); - ScopeHandler.setConstant("BUTTON2", NumberValue.of(InputEvent.BUTTON2_MASK)); - ScopeHandler.setConstant("BUTTON3", NumberValue.of(InputEvent.BUTTON3_MASK)); + entry("BUTTON1", NumberValue.of(InputEvent.BUTTON1_MASK)), + entry("BUTTON2", NumberValue.of(InputEvent.BUTTON2_MASK)), + entry("BUTTON3", NumberValue.of(InputEvent.BUTTON3_MASK)) + ); } @Override - public void init() { - initConstants(); + public Map functions() { + final var result = new HashMap(16); boolean isRobotInitialized = initialize(); if (isRobotInitialized) { - ScopeHandler.setFunction("click", convertFunction(robot::click)); - ScopeHandler.setFunction("delay", convertFunction(awtRobot::delay)); - ScopeHandler.setFunction("setAutoDelay", convertFunction(awtRobot::setAutoDelay)); - ScopeHandler.setFunction("keyPress", convertFunction(awtRobot::keyPress)); - ScopeHandler.setFunction("keyRelease", convertFunction(awtRobot::keyRelease)); - ScopeHandler.setFunction("mousePress", convertFunction(awtRobot::mousePress)); - ScopeHandler.setFunction("mouseRelease", convertFunction(awtRobot::mouseRelease)); - ScopeHandler.setFunction("mouseWheel", convertFunction(awtRobot::mouseWheel)); - ScopeHandler.setFunction("mouseMove", (args) -> { - Arguments.check(2, args.length); - try { - awtRobot.mouseMove(args[0].asInt(), args[1].asInt()); - } catch (IllegalArgumentException iae) { } - return NumberValue.ZERO; - }); - ScopeHandler.setFunction("typeText", (args) -> { - Arguments.check(1, args.length); - try { - typeText(args[0].asString()); - } catch (IllegalArgumentException iae) { } - return NumberValue.ZERO; - }); - ScopeHandler.setFunction("toClipboard", new robot_toclipboard()); - ScopeHandler.setFunction("fromClipboard", new robot_fromclipboard()); + result.put("click", convertFunction(robot::click)); + result.put("delay", convertFunction(awtRobot::delay)); + result.put("setAutoDelay", convertFunction(awtRobot::setAutoDelay)); + result.put("keyPress", convertFunction(awtRobot::keyPress)); + result.put("keyRelease", convertFunction(awtRobot::keyRelease)); + result.put("mousePress", convertFunction(awtRobot::mousePress)); + result.put("mouseRelease", convertFunction(awtRobot::mouseRelease)); + result.put("mouseWheel", convertFunction(awtRobot::mouseWheel)); + result.put("mouseMove", this::mouseMove); + result.put("typeText",this::typeText); + result.put("toClipboard", new robot_toclipboard()); + result.put("fromClipboard", new robot_fromclipboard()); } - ScopeHandler.setFunction("execProcess", new robot_exec(robot_exec.Mode.EXEC)); - ScopeHandler.setFunction("execProcessAndWait", new robot_exec(robot_exec.Mode.EXEC_AND_WAIT)); + result.put("execProcess", new robot_exec(robot_exec.Mode.EXEC)); + result.put("execProcessAndWait", new robot_exec(robot_exec.Mode.EXEC_AND_WAIT)); + return result; } private static boolean initialize() { @@ -83,6 +76,22 @@ public final class robot implements Module { return false; } } + + private Value mouseMove(Value[] args) { + Arguments.check(2, args.length); + try { + awtRobot.mouseMove(args[0].asInt(), args[1].asInt()); + } catch (IllegalArgumentException iae) { } + return NumberValue.ZERO; + } + + private Value typeText(Value[] args) { + Arguments.check(1, args.length); + try { + typeText(args[0].asString()); + } catch (IllegalArgumentException iae) { } + return NumberValue.ZERO; + } private static Function convertFunction(IntConsumer consumer) { return args -> { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/socket/socket.java b/modules/main/src/main/java/com/annimon/ownlang/modules/socket/socket.java index 10b64c9..78c5ca3 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/socket/socket.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/socket/socket.java @@ -6,6 +6,8 @@ import com.annimon.ownlang.modules.Module; import io.socket.client.IO; import io.socket.client.Socket; import java.net.URISyntaxException; +import java.util.LinkedHashMap; +import java.util.Map; /** * socket.io module. @@ -14,27 +16,29 @@ import java.net.URISyntaxException; */ public final class socket implements Module { - public static void initConstants() { - ScopeHandler.setConstant("EVENT_CONNECT", new StringValue(Socket.EVENT_CONNECT)); - ScopeHandler.setConstant("EVENT_CONNECTING", new StringValue(Socket.EVENT_CONNECTING)); - ScopeHandler.setConstant("EVENT_CONNECT_ERROR", new StringValue(Socket.EVENT_CONNECT_ERROR)); - ScopeHandler.setConstant("EVENT_CONNECT_TIMEOUT", new StringValue(Socket.EVENT_CONNECT_TIMEOUT)); - ScopeHandler.setConstant("EVENT_DISCONNECT", new StringValue(Socket.EVENT_DISCONNECT)); - ScopeHandler.setConstant("EVENT_ERROR", new StringValue(Socket.EVENT_ERROR)); - ScopeHandler.setConstant("EVENT_MESSAGE", new StringValue(Socket.EVENT_MESSAGE)); - ScopeHandler.setConstant("EVENT_PING", new StringValue(Socket.EVENT_PING)); - ScopeHandler.setConstant("EVENT_PONG", new StringValue(Socket.EVENT_PONG)); - ScopeHandler.setConstant("EVENT_RECONNECT", new StringValue(Socket.EVENT_RECONNECT)); - ScopeHandler.setConstant("EVENT_RECONNECTING", new StringValue(Socket.EVENT_RECONNECTING)); - ScopeHandler.setConstant("EVENT_RECONNECT_ATTEMPT", new StringValue(Socket.EVENT_RECONNECT_ATTEMPT)); - ScopeHandler.setConstant("EVENT_RECONNECT_ERROR", new StringValue(Socket.EVENT_RECONNECT_ERROR)); - ScopeHandler.setConstant("EVENT_RECONNECT_FAILED", new StringValue(Socket.EVENT_RECONNECT_FAILED)); + @Override + public Map constants() { + final var result = new LinkedHashMap(15); + result.put("EVENT_CONNECT", new StringValue(Socket.EVENT_CONNECT)); + result.put("EVENT_CONNECTING", new StringValue(Socket.EVENT_CONNECTING)); + result.put("EVENT_CONNECT_ERROR", new StringValue(Socket.EVENT_CONNECT_ERROR)); + result.put("EVENT_CONNECT_TIMEOUT", new StringValue(Socket.EVENT_CONNECT_TIMEOUT)); + result.put("EVENT_DISCONNECT", new StringValue(Socket.EVENT_DISCONNECT)); + result.put("EVENT_ERROR", new StringValue(Socket.EVENT_ERROR)); + result.put("EVENT_MESSAGE", new StringValue(Socket.EVENT_MESSAGE)); + result.put("EVENT_PING", new StringValue(Socket.EVENT_PING)); + result.put("EVENT_PONG", new StringValue(Socket.EVENT_PONG)); + result.put("EVENT_RECONNECT", new StringValue(Socket.EVENT_RECONNECT)); + result.put("EVENT_RECONNECTING", new StringValue(Socket.EVENT_RECONNECTING)); + result.put("EVENT_RECONNECT_ATTEMPT", new StringValue(Socket.EVENT_RECONNECT_ATTEMPT)); + result.put("EVENT_RECONNECT_ERROR", new StringValue(Socket.EVENT_RECONNECT_ERROR)); + result.put("EVENT_RECONNECT_FAILED", new StringValue(Socket.EVENT_RECONNECT_FAILED)); + return result; } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("newSocket", socket::newSocket); + public Map functions() { + return Map.of("newSocket", socket::newSocket); } private static Value newSocket(Value[] args) { diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/std/std.java b/modules/main/src/main/java/com/annimon/ownlang/modules/std/std.java index 18e399b..fe76b58 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/std/std.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/std/std.java @@ -4,6 +4,8 @@ import com.annimon.ownlang.Shared; import com.annimon.ownlang.Version; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; +import java.util.Map; +import static java.util.Map.entry; /** * @@ -11,63 +13,68 @@ import com.annimon.ownlang.modules.Module; */ public final class std implements Module { - public static void initConstants() { + @Override + public Map constants() { MapValue ownlang = new MapValue(5); ownlang.set("PLATFORM", new StringValue("desktop")); ownlang.set("VERSION", new StringValue(Version.VERSION)); ownlang.set("VERSION_MAJOR", NumberValue.of(Version.VERSION_MAJOR)); ownlang.set("VERSION_MINOR", NumberValue.of(Version.VERSION_MINOR)); ownlang.set("VERSION_PATCH", NumberValue.of(Version.VERSION_PATCH)); - ScopeHandler.setConstant("OwnLang", ownlang); + + return Map.of( + "OwnLang", ownlang, + "ARGS", ArrayValue.of(Shared.getOwnlangArgs()) + ); } @Override - public void init() { - initConstants(); - ScopeHandler.setConstant("ARGS", ArrayValue.of(Shared.getOwnlangArgs())); // is not constant - ScopeHandler.setFunction("echo", new std_echo()); - ScopeHandler.setFunction("readln", new std_readln()); - ScopeHandler.setFunction("length", new std_length()); - ScopeHandler.setFunction("rand", new std_rand()); - ScopeHandler.setFunction("time", new std_time()); - ScopeHandler.setFunction("sleep", new std_sleep()); - ScopeHandler.setFunction("thread", new std_thread()); - ScopeHandler.setFunction("sync", new std_sync()); - ScopeHandler.setFunction("try", new std_try()); - ScopeHandler.setFunction("default", new std_default()); + public Map functions() { + return Map.ofEntries( + entry("echo", new std_echo()), + entry("readln", new std_readln()), + entry("length", new std_length()), + entry("rand", new std_rand()), + entry("time", new std_time()), + entry("sleep", new std_sleep()), + entry("thread", new std_thread()), + entry("sync", new std_sync()), + entry("try", new std_try()), + entry("default", new std_default()), - // Numbers - ScopeHandler.setFunction("toHexString", NumberFunctions::toHexString); + // Numbers + entry("toHexString", NumberFunctions::toHexString), - // String - ScopeHandler.setFunction("getBytes", StringFunctions::getBytes); - ScopeHandler.setFunction("sprintf", new std_sprintf()); - ScopeHandler.setFunction("split", new std_split()); - ScopeHandler.setFunction("indexOf", new std_indexof()); - ScopeHandler.setFunction("lastIndexOf", new std_lastindexof()); - ScopeHandler.setFunction("charAt", new std_charat()); - ScopeHandler.setFunction("toChar", new std_tochar()); - ScopeHandler.setFunction("substring", new std_substring()); - ScopeHandler.setFunction("toLowerCase", new std_tolowercase()); - ScopeHandler.setFunction("toUpperCase", new std_touppercase()); - ScopeHandler.setFunction("trim", new std_trim()); - ScopeHandler.setFunction("replace", new std_replace()); - ScopeHandler.setFunction("replaceAll", new std_replaceall()); - ScopeHandler.setFunction("replaceFirst", new std_replacefirst()); - ScopeHandler.setFunction("parseInt", StringFunctions::parseInt); - ScopeHandler.setFunction("parseLong", StringFunctions::parseLong); - ScopeHandler.setFunction("stripMargin", StringFunctions::stripMargin); + // String + entry("getBytes", StringFunctions::getBytes), + entry("sprintf", new std_sprintf()), + entry("split", new std_split()), + entry("indexOf", new std_indexof()), + entry("lastIndexOf", new std_lastindexof()), + entry("charAt", new std_charat()), + entry("toChar", new std_tochar()), + entry("substring", new std_substring()), + entry("toLowerCase", new std_tolowercase()), + entry("toUpperCase", new std_touppercase()), + entry("trim", new std_trim()), + entry("replace", new std_replace()), + entry("replaceAll", new std_replaceall()), + entry("replaceFirst", new std_replacefirst()), + entry("parseInt", StringFunctions::parseInt), + entry("parseLong", StringFunctions::parseLong), + entry("stripMargin", StringFunctions::stripMargin), - // Arrays and maps - ScopeHandler.setFunction("newarray", new std_newarray()); - ScopeHandler.setFunction("join", new std_join()); - ScopeHandler.setFunction("sort", new std_sort()); - ScopeHandler.setFunction("arrayCombine", new std_arrayCombine()); - ScopeHandler.setFunction("arrayKeyExists", new std_arrayKeyExists()); - ScopeHandler.setFunction("arrayKeys", new std_arrayKeys()); - ScopeHandler.setFunction("arrayValues", new std_arrayValues()); - ScopeHandler.setFunction("arraySplice", new std_arraySplice()); - ScopeHandler.setFunction("range", new std_range()); - ScopeHandler.setFunction("stringFromBytes", ArrayFunctions::stringFromBytes); + // Arrays and map, + entry("newarray", new std_newarray()), + entry("join", new std_join()), + entry("sort", new std_sort()), + entry("arrayCombine", new std_arrayCombine()), + entry("arrayKeyExists", new std_arrayKeyExists()), + entry("arrayKeys", new std_arrayKeys()), + entry("arrayValues", new std_arrayValues()), + entry("arraySplice", new std_arraySplice()), + entry("range", new std_range()), + entry("stringFromBytes", ArrayFunctions::stringFromBytes) + ); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/types/types.java b/modules/main/src/main/java/com/annimon/ownlang/modules/types/types.java index b961488..613080a 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/types/types.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/types/types.java @@ -2,6 +2,8 @@ package com.annimon.ownlang.modules.types; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; +import java.util.Map; +import static java.util.Map.entry; /** * @@ -9,27 +11,31 @@ import com.annimon.ownlang.modules.Module; */ public final class types implements Module { - public static void initConstants() { - ScopeHandler.setConstant("OBJECT", NumberValue.of(Types.OBJECT)); - ScopeHandler.setConstant("NUMBER", NumberValue.of(Types.NUMBER)); - ScopeHandler.setConstant("STRING", NumberValue.of(Types.STRING)); - ScopeHandler.setConstant("ARRAY", NumberValue.of(Types.ARRAY)); - ScopeHandler.setConstant("MAP", NumberValue.of(Types.MAP)); - ScopeHandler.setConstant("FUNCTION", NumberValue.of(Types.FUNCTION)); + @Override + public Map constants() { + return Map.ofEntries( + entry("OBJECT", NumberValue.of(Types.OBJECT)), + entry("NUMBER", NumberValue.of(Types.NUMBER)), + entry("STRING", NumberValue.of(Types.STRING)), + entry("ARRAY", NumberValue.of(Types.ARRAY)), + entry("MAP", NumberValue.of(Types.MAP)), + entry("FUNCTION", NumberValue.of(Types.FUNCTION)) + ); } @Override - public void init() { - initConstants(); - ScopeHandler.setFunction("typeof", args -> NumberValue.of(args[0].type())); - ScopeHandler.setFunction("string", args -> new StringValue(args[0].asString())); - ScopeHandler.setFunction("number", args -> NumberValue.of(args[0].asNumber())); - - ScopeHandler.setFunction("byte", args -> NumberValue.of((byte)args[0].asInt())); - ScopeHandler.setFunction("short", args -> NumberValue.of((short)args[0].asInt())); - ScopeHandler.setFunction("int", args -> NumberValue.of(args[0].asInt())); - ScopeHandler.setFunction("long", args -> NumberValue.of((long)args[0].asNumber())); - ScopeHandler.setFunction("float", args -> NumberValue.of((float)args[0].asNumber())); - ScopeHandler.setFunction("double", args -> NumberValue.of(args[0].asNumber())); + public Map functions() { + return Map.ofEntries( + entry("typeof", args -> NumberValue.of(args[0].type())), + entry("string", args -> new StringValue(args[0].asString())), + entry("number", args -> NumberValue.of(args[0].asNumber())), + + entry("byte", args -> NumberValue.of((byte)args[0].asInt())), + entry("short", args -> NumberValue.of((short)args[0].asInt())), + entry("int", args -> NumberValue.of(args[0].asInt())), + entry("long", args -> NumberValue.of((long)args[0].asNumber())), + entry("float", args -> NumberValue.of((float)args[0].asNumber())), + entry("double", args -> NumberValue.of(args[0].asNumber())) + ); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/yaml/yaml.java b/modules/main/src/main/java/com/annimon/ownlang/modules/yaml/yaml.java index 84f45df..5a57cc6 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/yaml/yaml.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/yaml/yaml.java @@ -2,6 +2,8 @@ package com.annimon.ownlang.modules.yaml; import com.annimon.ownlang.lib.*; import com.annimon.ownlang.modules.Module; +import java.util.Collections; +import java.util.Map; /** * @@ -10,8 +12,15 @@ import com.annimon.ownlang.modules.Module; public final class yaml implements Module { @Override - public void init() { - ScopeHandler.setFunction("yamlencode", new yaml_encode()); - ScopeHandler.setFunction("yamldecode", new yaml_decode()); + public Map constants() { + return Collections.emptyMap(); + } + + @Override + public Map functions() { + return Map.of( + "yamlencode", new yaml_encode(), + "yamldecode", new yaml_decode() + ); } } diff --git a/modules/main/src/main/java/com/annimon/ownlang/modules/zip/zip.java b/modules/main/src/main/java/com/annimon/ownlang/modules/zip/zip.java index ee18e48..fdaacbd 100644 --- a/modules/main/src/main/java/com/annimon/ownlang/modules/zip/zip.java +++ b/modules/main/src/main/java/com/annimon/ownlang/modules/zip/zip.java @@ -9,23 +9,28 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; +import static java.util.Map.entry; public class zip implements Module { @Override - public void init() { - ScopeHandler.setFunction("zip", this::zipWithMapper); - ScopeHandler.setFunction("zipFiles", this::zipFiles); - ScopeHandler.setFunction("unzip", this::unzip); - ScopeHandler.setFunction("unzipFiles", this::unzipFiles); - ScopeHandler.setFunction("listZipEntries", this::listZipEntries); + public Map constants() { + return Collections.emptyMap(); + } + + @Override + public Map functions() { + return Map.ofEntries( + entry("zip", this::zipWithMapper), + entry("zipFiles", this::zipFiles), + entry("unzip", this::unzip), + entry("unzipFiles", this::unzipFiles), + entry("listZipEntries", this::listZipEntries) + ); } private Value zipWithMapper(Value[] args) { diff --git a/ownlang-core/src/main/java/com/annimon/ownlang/lib/ModuleLoader.java b/ownlang-core/src/main/java/com/annimon/ownlang/lib/ModuleLoader.java new file mode 100644 index 0000000..37e7d5f --- /dev/null +++ b/ownlang-core/src/main/java/com/annimon/ownlang/lib/ModuleLoader.java @@ -0,0 +1,28 @@ +package com.annimon.ownlang.lib; + +import com.annimon.ownlang.modules.Module; + +public final class ModuleLoader { + private static final String PACKAGE = "com.annimon.ownlang.modules.%s.%s"; + + private ModuleLoader() { } + + public static Module load(String name) { + try { + return (Module) Class.forName(String.format(PACKAGE, name, name)) + .getDeclaredConstructor() + .newInstance(); + } catch (Exception ex) { + throw new RuntimeException("Unable to load module " + name, ex); + } + } + + public static void loadAndUse(String name) { + final var rootScope = ScopeHandler.rootScope(); + if (rootScope.isModuleLoaded(name)) return; + + final var module = load(name); + rootScope.getConstants().putAll(module.constants()); + rootScope.getFunctions().putAll(module.functions()); + } +} diff --git a/ownlang-core/src/main/java/com/annimon/ownlang/lib/RootScope.java b/ownlang-core/src/main/java/com/annimon/ownlang/lib/RootScope.java index 82ded80..0cdcd81 100644 --- a/ownlang-core/src/main/java/com/annimon/ownlang/lib/RootScope.java +++ b/ownlang-core/src/main/java/com/annimon/ownlang/lib/RootScope.java @@ -1,17 +1,21 @@ package com.annimon.ownlang.lib; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; final class RootScope extends Scope { private final Map constants; private final Map functions; + private final Set loadedModules; RootScope() { functions = new ConcurrentHashMap<>(); constants = new ConcurrentHashMap<>(); constants.put("true", NumberValue.ONE); constants.put("false", NumberValue.ZERO); + loadedModules = new CopyOnWriteArraySet<>(); } @Override @@ -65,4 +69,17 @@ final class RootScope extends Scope { public Map getFunctions() { return functions; } + + + public Set getLoadedModules() { + return loadedModules; + } + + public boolean isModuleLoaded(String name) { + return loadedModules.contains(name); + } + + public void addLoadedModule(String name) { + loadedModules.add(name); + } } diff --git a/ownlang-core/src/main/java/com/annimon/ownlang/lib/ScopeHandler.java b/ownlang-core/src/main/java/com/annimon/ownlang/lib/ScopeHandler.java index 67debfc..9571d50 100644 --- a/ownlang-core/src/main/java/com/annimon/ownlang/lib/ScopeHandler.java +++ b/ownlang-core/src/main/java/com/annimon/ownlang/lib/ScopeHandler.java @@ -28,6 +28,10 @@ public final class ScopeHandler { return rootScope.getFunctions(); } + static RootScope rootScope() { + return rootScope; + } + /** * Resets a scope for new program execution */ @@ -56,7 +60,6 @@ public final class ScopeHandler { } - public static boolean isFunctionExists(String name) { return rootScope.containsFunction(name); } diff --git a/ownlang-core/src/main/java/com/annimon/ownlang/modules/Module.java b/ownlang-core/src/main/java/com/annimon/ownlang/modules/Module.java index cda5ca4..961a315 100644 --- a/ownlang-core/src/main/java/com/annimon/ownlang/modules/Module.java +++ b/ownlang-core/src/main/java/com/annimon/ownlang/modules/Module.java @@ -1,10 +1,16 @@ package com.annimon.ownlang.modules; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.Value; +import java.util.Map; + /** - * + * Main interface for modules * @author aNNiMON */ public interface Module { - void init(); + Map constants(); + + Map functions(); } diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java index 69e30cf..06c5165 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UseStatement.java @@ -1,18 +1,17 @@ package com.annimon.ownlang.parser.ast; +import com.annimon.ownlang.lib.ModuleLoader; +import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.modules.Module; -import java.lang.reflect.Method; import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; /** * * @author aNNiMON */ public final class UseStatement extends InterruptableNode implements Statement { - - private static final String PACKAGE = "com.annimon.ownlang.modules.%s.%s"; - private static final String INIT_CONSTANTS_METHOD = "initConstants"; - public final Collection modules; public UseStatement(Collection modules) { @@ -23,35 +22,17 @@ public final class UseStatement extends InterruptableNode implements Statement { public void execute() { super.interruptionCheck(); for (String module : modules) { - loadModule(module); + ModuleLoader.loadAndUse(module); } } - private void loadModule(String name) { - try { - final Module module = (Module) Class.forName(String.format(PACKAGE, name, name)) - .getDeclaredConstructor() - .newInstance(); - module.init(); - } catch (Exception ex) { - throw new RuntimeException("Unable to load module " + name, ex); - } - } - - public void loadConstants() { - for (String module : modules) { - loadConstants(module); - } - } - - private void loadConstants(String moduleName) { - try { - final Class moduleClass = Class.forName(String.format(PACKAGE, moduleName, moduleName)); - final Method method = moduleClass.getMethod(INIT_CONSTANTS_METHOD); - method.invoke(this); - } catch (Exception ex) { - // ignore + public Map loadConstants() { + final var result = new LinkedHashMap(); + for (String moduleName : modules) { + final Module module = ModuleLoader.load(moduleName); + result.putAll(module.constants()); } + return result; } @Override diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java index 38b6c66..939cc3d 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/optimization/VariablesGrabber.java @@ -1,13 +1,11 @@ package com.annimon.ownlang.parser.optimization; -import com.annimon.ownlang.lib.ScopeHandler; import com.annimon.ownlang.lib.Value; -import com.annimon.ownlang.lib.Variables; import com.annimon.ownlang.parser.ast.*; -import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValue; -import static com.annimon.ownlang.parser.visitors.VisitorUtils.isVariable; import java.util.HashMap; import java.util.Map; +import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValue; +import static com.annimon.ownlang.parser.visitors.VisitorUtils.isVariable; public class VariablesGrabber extends OptimizationVisitor> { @@ -100,18 +98,11 @@ public class VariablesGrabber extends OptimizationVisitor t) { if (grabModuleConstants) { - // To get module constants we need to store current constants, clear all, then load module. - final Map currentConstants = new HashMap<>(ScopeHandler.constants()); - ScopeHandler.constants().clear(); - s.loadConstants(); - // Grab module constants - for (Map.Entry entry : ScopeHandler.constants().entrySet()) { + for (Map.Entry entry : s.loadConstants().entrySet()) { final VariableInfo var = variableInfo(t, entry.getKey()); var.value = entry.getValue(); t.put(entry.getKey(), var); } - // Restore previous constants - ScopeHandler.constants().putAll(currentConstants); } return super.visit(s, t); } diff --git a/ownlang-utils/src/main/java/com/annimon/ownlang/utils/ModulesInfoCreator.java b/ownlang-utils/src/main/java/com/annimon/ownlang/utils/ModulesInfoCreator.java index d119fd3..de6447a 100644 --- a/ownlang-utils/src/main/java/com/annimon/ownlang/utils/ModulesInfoCreator.java +++ b/ownlang-utils/src/main/java/com/annimon/ownlang/utils/ModulesInfoCreator.java @@ -28,16 +28,12 @@ public final class ModulesInfoCreator { .map(File::getName) .toArray(String[]::new); for (String moduleName : moduleNames) { - final String moduleClassPath = String.format("com.annimon.ownlang.modules.%s.%s", moduleName, moduleName); - Class moduleClass = Class.forName(moduleClassPath); - ScopeHandler.resetScope(); - final Module module = (Module) moduleClass.getDeclaredConstructor().newInstance(); - module.init(); + final Module module = ModuleLoader.load(moduleName); final ModuleInfo moduleInfo = new ModuleInfo(moduleName); - moduleInfo.functions.addAll(ScopeHandler.functions().keySet()); - moduleInfo.constants.putAll(ScopeHandler.constants()); - moduleInfo.types.addAll(listValues(moduleClass)); + moduleInfo.functions.addAll(module.functions().keySet()); + moduleInfo.constants.putAll(module.constants()); + moduleInfo.types.addAll(listValues(module.getClass())); moduleInfos.add(moduleInfo); }