diff --git a/src/com/annimon/ownlang/lib/StringValue.java b/src/com/annimon/ownlang/lib/StringValue.java index 39d83e1..8e820a9 100644 --- a/src/com/annimon/ownlang/lib/StringValue.java +++ b/src/com/annimon/ownlang/lib/StringValue.java @@ -8,6 +8,8 @@ import java.util.Objects; */ public final class StringValue implements Value { + public static final StringValue EMPTY = new StringValue(""); + private final String value; public StringValue(String value) { diff --git a/src/com/annimon/ownlang/lib/modules/functions/robot_exec.java b/src/com/annimon/ownlang/lib/modules/functions/robot_exec.java new file mode 100644 index 0000000..0792848 --- /dev/null +++ b/src/com/annimon/ownlang/lib/modules/functions/robot_exec.java @@ -0,0 +1,54 @@ +package com.annimon.ownlang.lib.modules.functions; + +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; +import com.annimon.ownlang.lib.*; + +public final class robot_exec implements Function { + + public static enum Mode { EXEC, EXEC_AND_WAIT }; + + private final Mode mode; + + public robot_exec(Mode mode) { + this.mode = mode; + } + + @Override + public Value execute(Value... args) { + if (args.length == 0) throw new ArgumentsMismatchException("At least one argument expected"); + + try { + final Process process; + if (args.length > 1) { + process = Runtime.getRuntime().exec(toStringArray(args)); + } else switch (args[0].type()) { + case Types.ARRAY: + final ArrayValue array = (ArrayValue) args[0]; + process = Runtime.getRuntime().exec(toStringArray(array.getCopyElements())); + break; + + default: + process = Runtime.getRuntime().exec(args[0].asString()); + } + + switch (mode) { + case EXEC_AND_WAIT: + return new NumberValue(process.waitFor()); + case EXEC: + default: + return NumberValue.ZERO; + } + } catch (Exception ex) { + ex.printStackTrace(); + return NumberValue.ZERO; + } + } + + private static String[] toStringArray(Value[] values) { + final String[] strings = new String[values.length]; + for (int i = 0; i < values.length; i++) { + strings[i] = values[i].asString(); + } + return strings; + } +} \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/robot_fromclipboard.java b/src/com/annimon/ownlang/lib/modules/functions/robot_fromclipboard.java new file mode 100644 index 0000000..cf50b64 --- /dev/null +++ b/src/com/annimon/ownlang/lib/modules/functions/robot_fromclipboard.java @@ -0,0 +1,21 @@ +package com.annimon.ownlang.lib.modules.functions; + +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.StringValue; +import com.annimon.ownlang.lib.Value; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; + +public final class robot_fromclipboard implements Function { + + @Override + public Value execute(Value... args) { + try { + Object data = Toolkit.getDefaultToolkit().getSystemClipboard() + .getData(DataFlavor.stringFlavor); + return new StringValue(data.toString()); + } catch (Exception ex) { + return StringValue.EMPTY; + } + } +} \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/robot_toclipboard.java b/src/com/annimon/ownlang/lib/modules/functions/robot_toclipboard.java new file mode 100644 index 0000000..c701594 --- /dev/null +++ b/src/com/annimon/ownlang/lib/modules/functions/robot_toclipboard.java @@ -0,0 +1,20 @@ +package com.annimon.ownlang.lib.modules.functions; + +import com.annimon.ownlang.exceptions.ArgumentsMismatchException; +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.NumberValue; +import com.annimon.ownlang.lib.Value; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; + +public final class robot_toclipboard implements Function { + + @Override + public Value execute(Value... args) { + if (args.length != 1) throw new ArgumentsMismatchException("One argument expected"); + + Toolkit.getDefaultToolkit().getSystemClipboard() + .setContents(new StringSelection(args[0].asString()), null); + return NumberValue.ZERO; + } +} \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/std_readln.java b/src/com/annimon/ownlang/lib/modules/functions/std_readln.java new file mode 100644 index 0000000..0ec243a --- /dev/null +++ b/src/com/annimon/ownlang/lib/modules/functions/std_readln.java @@ -0,0 +1,14 @@ +package com.annimon.ownlang.lib.modules.functions; + +import com.annimon.ownlang.lib.*; +import java.util.Scanner; + +public final class std_readln implements Function { + + @Override + public Value execute(Value... args) { + try (Scanner sc = new Scanner(System.in)) { + return new StringValue(sc.nextLine()); + } + } +} \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/functions/std_time.java b/src/com/annimon/ownlang/lib/modules/functions/std_time.java new file mode 100644 index 0000000..37b8ce1 --- /dev/null +++ b/src/com/annimon/ownlang/lib/modules/functions/std_time.java @@ -0,0 +1,13 @@ +package com.annimon.ownlang.lib.modules.functions; + +import com.annimon.ownlang.lib.Function; +import com.annimon.ownlang.lib.NumberValue; +import com.annimon.ownlang.lib.Value; + +public final class std_time implements Function { + + @Override + public Value execute(Value... args) { + return new NumberValue(System.currentTimeMillis()); + } +} \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/robot.java b/src/com/annimon/ownlang/lib/modules/robot.java index b61a246..7a91a03 100644 --- a/src/com/annimon/ownlang/lib/modules/robot.java +++ b/src/com/annimon/ownlang/lib/modules/robot.java @@ -2,6 +2,9 @@ package com.annimon.ownlang.lib.modules; import com.annimon.ownlang.exceptions.ArgumentsMismatchException; import com.annimon.ownlang.lib.*; +import com.annimon.ownlang.lib.modules.functions.robot_exec; +import com.annimon.ownlang.lib.modules.functions.robot_fromclipboard; +import com.annimon.ownlang.lib.modules.functions.robot_toclipboard; import java.awt.AWTException; import java.awt.Robot; import java.awt.event.InputEvent; @@ -53,6 +56,10 @@ public final class robot implements Module { } catch (IllegalArgumentException iae) { } return NumberValue.ZERO; }); + Functions.set("toClipboard", new robot_toclipboard()); + Functions.set("fromClipboard", new robot_fromclipboard()); + Functions.set("execProcess", new robot_exec(robot_exec.Mode.EXEC)); + Functions.set("execProcessAndWait", new robot_exec(robot_exec.Mode.EXEC_AND_WAIT)); Variables.set("VK_DOWN", new NumberValue(KeyEvent.VK_DOWN)); Variables.set("VK_LEFT", new NumberValue(KeyEvent.VK_LEFT)); diff --git a/src/com/annimon/ownlang/lib/modules/std.java b/src/com/annimon/ownlang/lib/modules/std.java index 6958732..9422a5f 100644 --- a/src/com/annimon/ownlang/lib/modules/std.java +++ b/src/com/annimon/ownlang/lib/modules/std.java @@ -12,10 +12,12 @@ public final class std implements Module { @Override public void init() { Functions.set("echo", new std_echo()); + Functions.set("readln", new std_readln()); Functions.set("newarray", new std_newarray()); Functions.set("sort", new std_sort()); Functions.set("length", new std_length()); Functions.set("rand", new std_rand()); + Functions.set("time", new std_time()); Functions.set("sleep", new std_sleep()); Functions.set("thread", new std_thread()); diff --git a/src/com/annimon/ownlang/parser/ast/UseStatement.java b/src/com/annimon/ownlang/parser/ast/UseStatement.java index 39397fa..cd46154 100644 --- a/src/com/annimon/ownlang/parser/ast/UseStatement.java +++ b/src/com/annimon/ownlang/parser/ast/UseStatement.java @@ -22,7 +22,9 @@ public final class UseStatement implements Statement { final String moduleName = expression.eval().asString(); final Module module = (Module) Class.forName(PACKAGE + moduleName).newInstance(); module.init(); - } catch (Exception ex) { } + } catch (Exception ex) { + throw new RuntimeException(ex); + } } @Override