@@ -1,5 +1,6 @@
11package org.idris.rts;
22
3+import java.lang.reflect.InvocationTargetException;
34import java.util.Arrays;
45import java.util.List;
56import java.util.Map;
@@ -9,7 +10,6 @@ import java.util.HashSet;
910import java.io.Closeable;
1011import java.io.File;
1112import java.io.IOException;
12−import java.io.EOFException;
1313import java.io.PrintStream;
1414import java.io.InputStream;
1515import java.nio.ByteBuffer;
@@ -25,190 +25,205 @@ import java.util.concurrent.Semaphore;
2525
2626@SuppressWarnings("unchecked")
2727public class ForeignPrimitives {
28+
2829 private static final Map<Thread, List<String>> args = new HashMap<>();
2930 private static final Semaphore messageMutex = new Semaphore(1);
3031 private static final Map<Thread, BlockingQueue<Object>> messages = new HashMap<>();
3132 private static final Set<Object> feofFiles = new HashSet<>();
3233
33− public static synchronized void idris_initArgs(Thread t, String [] args) {
34− ForeignPrimitives.args.put(t, Arrays.asList(args));
34+ public static synchronized void idris_initArgs(Thread t, String[] args) {
35+ ForeignPrimitives.args.put(t, Arrays.asList(args));
3536 }
3637
3738 public static synchronized int idris_numArgs(Object thread) {
38− List<String> argsForThread = ForeignPrimitives.args.get((Thread)thread);
39− return (argsForThread == null ? 0 : argsForThread.size());
39+ List<String> argsForThread = ForeignPrimitives.args.get((Thread) thread);
40+ return (argsForThread == null ? 0 : argsForThread.size());
4041 }
4142
4243 public static synchronized String idris_getArg(Object thread, int num) {
43− List<String> argsForThread = ForeignPrimitives.args.get((Thread)thread);
44− return (argsForThread == null ? null : argsForThread.get(num));
44+ List<String> argsForThread = ForeignPrimitives.args.get((Thread) thread);
45+ return (argsForThread == null ? null : argsForThread.get(num));
4546 }
4647
4748 public static String getenv(String x) {
48− return System.getenv(x);
49+ return System.getenv(x);
4950 }
5051
5152 public static void exit(int exitCode) {
52− System.exit(exitCode);
53+ System.exit(exitCode);
5354 }
5455
5556 public static void usleep(int microsecs) {
56− try {
57− Thread.sleep(microsecs / 1000, microsecs % 1000);
58− } catch (InterruptedException ex) {
59− }
57+ try {
58+ Thread.sleep(microsecs / 1000, microsecs % 1000);
59+ } catch (InterruptedException ex) {
60+ }
6061 }
6162
6263 public static void idris_sendMessage(Object from, Object dest, Object message) throws InterruptedException {
63− messageMutex.acquire();
64− BlockingQueue<Object> messagesForTarget = messages.get((Thread)dest);
65− if (messagesForTarget == null) {
66− messagesForTarget = new LinkedBlockingQueue<>();
67− messages.put((Thread)dest, messagesForTarget);
68− }
69− messagesForTarget.put(message);
64+ messageMutex.acquire();
65+ BlockingQueue<Object> messagesForTarget = messages.get((Thread) dest);
66+ if (messagesForTarget == null) {
67+ messagesForTarget = new LinkedBlockingQueue<>();
68+ messages.put((Thread) dest, messagesForTarget);
69+ }
70+ messagesForTarget.put(message);
7071 messageMutex.release();
7172 }
7273
7374 public static int idris_checkMessage(Object dest) throws InterruptedException {
74− messageMutex.acquire();
75− BlockingQueue<Object> messagesForTarget = messages.get((Thread)dest);
76− messageMutex.release();
77− return (messagesForTarget == null ? 0 : messagesForTarget.size());
75+ messageMutex.acquire();
76+ BlockingQueue<Object> messagesForTarget = messages.get((Thread) dest);
77+ messageMutex.release();
78+ return (messagesForTarget == null ? 0 : messagesForTarget.size());
7879 }
7980
8081 public static Object idris_recvMessage(Object dest) throws InterruptedException {
81− messageMutex.acquire();
82− BlockingQueue<Object> messagesForTarget = messages.get((Thread)dest);
83− if (messagesForTarget == null) {
84− messagesForTarget = new LinkedBlockingQueue();
85− messages.put((Thread)dest, messagesForTarget);
86− }
87− messageMutex.release();
88− return messagesForTarget.take();
82+ messageMutex.acquire();
83+ BlockingQueue<Object> messagesForTarget = messages.get((Thread) dest);
84+ if (messagesForTarget == null) {
85+ messagesForTarget = new LinkedBlockingQueue();
86+ messages.put((Thread) dest, messagesForTarget);
87+ }
88+ messageMutex.release();
89+ return messagesForTarget.take();
8990 }
9091
9192 public static void putStr(String str) {
92− System.out.print(str);
93+ System.out.print(str);
9394 }
9495
9596 public static void putchar(char c) {
96− System.out.print(c);
97+ System.out.print(c);
9798 }
9899
99100 public static int getchar() {
100− try {
101− return (char)System.in.read();
102− } catch (IOException ex) {
103− return -1;
104− }
101+ try {
102+ return (char) System.in.read();
103+ } catch (IOException ex) {
104+ return -1;
105+ }
105106 }
106107
107108 public static SeekableByteChannel fileOpen(String name, String privs) {
108− try {
109− OpenOption [] options;
110− switch (privs) {
111− case "r" :
112− options = new StandardOpenOption []
113− { StandardOpenOption.READ };
114− break;
115− case "r+" :
116− options = new StandardOpenOption []
117− { StandardOpenOption.READ,
118− StandardOpenOption.WRITE };
119− break;
120− case "w" :
121− options = new StandardOpenOption []
122− { StandardOpenOption.WRITE,
123− StandardOpenOption.CREATE };
124− break;
125− case "w+" :
126− options = new StandardOpenOption []
127− { StandardOpenOption.READ,
128− StandardOpenOption.WRITE,
129− StandardOpenOption.CREATE };
130− break;
131− case "a" :
132− options = new StandardOpenOption []
133− { StandardOpenOption.WRITE,
134− StandardOpenOption.CREATE,
135− StandardOpenOption.APPEND };
136− break;
137− case "a+" :
138− options = new StandardOpenOption []
139− { StandardOpenOption.READ,
140− StandardOpenOption.WRITE,
141− StandardOpenOption.CREATE,
142− StandardOpenOption.APPEND };
143− break;
144− default :
145− options = new StandardOpenOption [] {};
146− break;
147− }
148− return Files.newByteChannel(new File(name).toPath(), options);
149− } catch (IOException ex) {
150− return null;
151− }
109+ try {
110+ OpenOption[] options;
111+ switch (privs) {
112+ case "r":
113+ options = new StandardOpenOption[]{StandardOpenOption.READ};
114+ break;
115+ case "r+":
116+ options = new StandardOpenOption[]{StandardOpenOption.READ,
117+ StandardOpenOption.WRITE};
118+ break;
119+ case "w":
120+ options = new StandardOpenOption[]{StandardOpenOption.WRITE,
121+ StandardOpenOption.CREATE};
122+ break;
123+ case "w+":
124+ options = new StandardOpenOption[]{StandardOpenOption.READ,
125+ StandardOpenOption.WRITE,
126+ StandardOpenOption.CREATE};
127+ break;
128+ case "a":
129+ options = new StandardOpenOption[]{StandardOpenOption.WRITE,
130+ StandardOpenOption.CREATE,
131+ StandardOpenOption.APPEND};
132+ break;
133+ case "a+":
134+ options = new StandardOpenOption[]{StandardOpenOption.READ,
135+ StandardOpenOption.WRITE,
136+ StandardOpenOption.CREATE,
137+ StandardOpenOption.APPEND};
138+ break;
139+ default:
140+ options = new StandardOpenOption[]{};
141+ break;
142+ }
143+ return Files.newByteChannel(new File(name).toPath(), options);
144+ } catch (IOException ex) {
145+ return null;
146+ }
152147 }
153148
154149 public static synchronized void fileClose(Object file) throws IOException {
155− ((Closeable)file).close();
156− feofFiles.remove(file);
150+ ((Closeable) file).close();
151+ feofFiles.remove(file);
157152 }
158153
159154 public static void fputStr(Object file, String string) throws IOException {
160− if (file instanceof PrintStream) {
161− ((PrintStream)file).print(string);
162− } else if (file instanceof SeekableByteChannel) {
163− ((SeekableByteChannel)file).write(ByteBuffer.wrap(string.getBytes()));
164− }
155+ if (file instanceof PrintStream) {
156+ ((PrintStream) file).print(string);
157+ } else if (file instanceof SeekableByteChannel) {
158+ ((SeekableByteChannel) file).write(ByteBuffer.wrap(string.getBytes()));
159+ }
165160 }
166161
167162 public static synchronized String idris_readStr(Object file) throws IOException {
168− ReadableByteChannel channel = file instanceof InputStream ?
169− Channels.newChannel((InputStream)file) :
170− (ReadableByteChannel)file;
171− ByteBuffer buf = ByteBuffer.allocate(1);
172− StringBuilder resultBuilder = new StringBuilder("");
173− String delimiter = System.getProperty("line.separator");
174− int read = 0;
175− do {
176− buf.rewind();
177− read = channel.read(buf);
178− if (read > 0) {
179− resultBuilder.append(new String(buf.array()));
180− if (resultBuilder.lastIndexOf(delimiter) > -1) {
181− return resultBuilder.toString();
182− }
183− }
184− if (read < 0) {
185− feofFiles.add(file);
186− }
187− } while (read >= 0);
188− return resultBuilder.toString();
163+ ReadableByteChannel channel = file instanceof InputStream
164+ ? Channels.newChannel((InputStream) file)
165+ : (ReadableByteChannel) file;
166+ ByteBuffer buf = ByteBuffer.allocate(1);
167+ StringBuilder resultBuilder = new StringBuilder("");
168+ String delimiter = System.getProperty("line.separator");
169+ int read = 0;
170+ do {
171+ buf.rewind();
172+ read = channel.read(buf);
173+ if (read > 0) {
174+ resultBuilder.append(new String(buf.array()));
175+ if (resultBuilder.lastIndexOf(delimiter) > -1) {
176+ return resultBuilder.toString();
177+ }
178+ }
179+ if (read < 0) {
180+ feofFiles.add(file);
181+ }
182+ } while (read >= 0);
183+ return resultBuilder.toString();
189184 }
190185
191186 public static int fileEOF(Object file) {
192− return (feofFiles.contains(file) ? 1 : 0);
187+ return (feofFiles.contains(file) ? 1 : 0);
193188 }
194189
195190 public static int isNull(Object o) {
196− return (o == null ? 1 : 0);
191+ return (o == null ? 1 : 0);
197192 }
198193
199194 public final static Object idris_K(final Object result, final Object drop) {
200− return result;
195+ return result;
201196 }
202197
203198 public final static Object idris_flipK(final Object drop, final Object result) {
204− return result;
205− }
206−
207− public final static Object idris_assignStack(final Object [] context, final int start, final Object ... vars) {
208− int i = start;
209− for (Object var : vars) {
210− context[i] = var;
211− }
212− return context;
199+ return result;
200+ }
201+
202+ public final static Object idris_assignStack(final Object[] context, final int start, final Object... vars) {
203+ int i = start;
204+ for (Object var : vars) {
205+ context[i] = var;
206+ }
207+ return context;
208+ }
209+
210+ public final static Object invokeOn(final Object obj, final String methodName, Object... args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
211+ Class cls = (obj instanceof Class ? (Class)obj : obj.getClass());
212+ Class argClasses[] = new Class[args.length];
213+ int i = 0;
214+ for (Object arg : args) {
215+ argClasses[i] = arg.getClass();
216+ }
217+ return cls.getMethod(methodName, argClasses).invoke(obj, args);
218+ }
219+
220+ public final static Object newObject(final Object cls, Object... args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
221+ Class clazz = (cls instanceof Class ? (Class)cls : cls.getClass());
222+ Class argClasses[] = new Class[args.length];
223+ int i = 0;
224+ for (Object arg : args) {
225+ argClasses[i] = arg.getClass();
226+ }
227+ return clazz.getConstructor(argClasses).newInstance(args);
213228 }
214229}