Skip to content

Commit a4c8f68

Browse files
committed
[truffle] Implement nqp::getstdin
1 parent 8a9e57c commit a4c8f68

File tree

5 files changed

+180
-0
lines changed

5 files changed

+180
-0
lines changed

src/vm/jvm/Truffle.nqp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ class QAST::OperationsTruffle {
172172

173173
add_simple_op('getstdout', $OBJ, [], :side_effects);
174174
add_simple_op('getstderr', $OBJ, [], :side_effects);
175+
add_simple_op('getstdin', $OBJ, [], :side_effects);
175176

176177
add_simple_op('say', $STR, [$STR], :side_effects);
177178
add_simple_op('print', $STR, [$STR], :side_effects);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.perl6.nqp.truffle.io;
2+
3+
import org.perl6.nqp.runtime.ThreadContext;
4+
5+
public interface IIOInteractive {
6+
public String readlineInteractive(ThreadContext tc, String prompt);
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.perl6.nqp.truffle.io;
2+
3+
import org.perl6.nqp.runtime.ThreadContext;
4+
5+
public interface IIOSyncReadable {
6+
public String slurp();
7+
public String readline();
8+
public String readchars(int chars);
9+
public byte[] read(int bytes);
10+
public boolean eof();
11+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package org.perl6.nqp.truffle.io;
2+
3+
import java.io.BufferedReader;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.io.InputStreamReader;
7+
import java.io.OutputStreamWriter;
8+
import java.nio.charset.Charset;
9+
10+
import jline.ConsoleReader;
11+
12+
import org.perl6.nqp.runtime.ExceptionHandling;
13+
import org.perl6.nqp.runtime.ThreadContext;
14+
15+
public class StandardReadHandle implements IIOClosable, IIOEncodable, IIOSyncReadable, IIOInteractive, IIOPossiblyTTY {
16+
private InputStream is;
17+
private BufferedReader br;
18+
private ConsoleReader cr;
19+
private boolean eof = false;
20+
private Charset cs;
21+
22+
public StandardReadHandle(InputStream is) {
23+
this.is = is;
24+
setEncoding(Charset.forName("UTF-8"));
25+
}
26+
27+
public void close() {
28+
try {
29+
is.close();
30+
} catch (IOException e) {
31+
throw new RuntimeException(e);
32+
}
33+
}
34+
35+
public void setEncoding(Charset cs) {
36+
this.cs = cs;
37+
}
38+
39+
public byte[] read(int bytes) {
40+
try {
41+
byte[] array = new byte[bytes];
42+
int read = 0;
43+
int offset = 0;
44+
while (offset < bytes) {
45+
if ((read = is.read(array, offset, bytes - offset)) == -1) {
46+
eof = true;
47+
break;
48+
}
49+
offset += read;
50+
}
51+
byte[] compact = new byte[offset];
52+
System.arraycopy(array, 0, compact, 0, offset);
53+
return compact;
54+
} catch (IOException e) {
55+
throw new RuntimeException(e);
56+
}
57+
}
58+
59+
public synchronized String slurp() {
60+
try {
61+
if (br == null)
62+
br = new BufferedReader(new InputStreamReader(is, cs));
63+
StringBuffer data = new StringBuffer();
64+
char[] buf = new char[4096];
65+
int read = 0;
66+
while((read = br.read(buf)) != -1)
67+
data.append(String.valueOf(buf, 0, read));
68+
eof = true;
69+
return data.toString();
70+
} catch (IOException e) {
71+
throw new RuntimeException(e);
72+
}
73+
}
74+
75+
public synchronized String readline() {
76+
try {
77+
if (br == null)
78+
br = new BufferedReader(new InputStreamReader(is, cs));
79+
String line = br.readLine();
80+
if (line == null) {
81+
eof = true;
82+
line = "";
83+
}
84+
return line;
85+
} catch (IOException e) {
86+
throw new RuntimeException(e);
87+
}
88+
}
89+
90+
/* TODO - think about unicode in readchars and getc */
91+
public synchronized String readchars(int count) {
92+
try {
93+
if (br == null)
94+
br = new BufferedReader(new InputStreamReader(is, cs));
95+
char[] chars = new char[count];
96+
97+
int actuallyRead = br.read(chars, 0, count);
98+
99+
if (actuallyRead == -1) {
100+
return "";
101+
}
102+
else {
103+
return new String(chars, 0, actuallyRead);
104+
}
105+
} catch (IOException e) {
106+
throw new RuntimeException(e);
107+
}
108+
}
109+
110+
public synchronized String readlineInteractive(ThreadContext tc, String prompt) {
111+
try {
112+
if (cr == null)
113+
cr = new ConsoleReader(is, new OutputStreamWriter(tc.gc.out));
114+
String line = cr.readLine(prompt);
115+
if (line == null) {
116+
eof = true;
117+
line = "";
118+
}
119+
return line;
120+
} catch (IOException e) {
121+
throw new RuntimeException(e);
122+
}
123+
}
124+
125+
public boolean eof() {
126+
return eof;
127+
}
128+
129+
public boolean isTTY() {
130+
return System.console() != null;
131+
}
132+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.perl6.nqp.truffle.nodes.io;
2+
import com.oracle.truffle.api.frame.VirtualFrame;
3+
import com.oracle.truffle.api.nodes.NodeInfo;
4+
import org.perl6.nqp.truffle.nodes.NQPNode;
5+
import org.perl6.nqp.truffle.nodes.NQPObjNode;
6+
import org.perl6.nqp.dsl.Deserializer;
7+
import org.perl6.nqp.truffle.runtime.HLL;
8+
import org.perl6.nqp.truffle.GlobalContext;
9+
import org.perl6.nqp.truffle.io.StandardReadHandle;
10+
import org.perl6.nqp.truffle.sixmodel.reprs.IOHandleInstance;
11+
12+
@NodeInfo(shortName = "getstdin")
13+
public final class NQPGetstdinNode extends NQPObjNode {
14+
HLL hll;
15+
GlobalContext globalContext;
16+
17+
@Deserializer
18+
public NQPGetstdinNode(HLL hll, GlobalContext globalContext) {
19+
this.hll = hll;
20+
this.globalContext = globalContext;
21+
}
22+
23+
@Override
24+
public Object execute(VirtualFrame frame) {
25+
IOHandleInstance handle = (IOHandleInstance) hll.ioType.stable.repr.allocate();
26+
handle.handle = new StandardReadHandle(globalContext.in);
27+
return handle;
28+
}
29+
}

0 commit comments

Comments
 (0)