Skip to content

Commit e419673

Browse files
authored
RLangPApplet: Support static code (#171)
Signed-off-by: Ce Gao <[email protected]>
1 parent 1046511 commit e419673

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

src/rprocessing/RLangPApplet.java

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import java.awt.event.ComponentEvent;
77
import java.lang.Thread.UncaughtExceptionHandler;
88
import java.lang.reflect.Method;
9+
import java.util.ArrayList;
910
import java.util.Arrays;
11+
import java.util.List;
1012
import java.util.concurrent.CountDownLatch;
1113

1214
import javax.script.ScriptException;
@@ -49,6 +51,7 @@ public class RLangPApplet extends BuiltinApplet {
4951

5052
/** Program code */
5153
private final String programText;
54+
private ExpressionVector expressionVector;
5255

5356
private static final String CORE_TEXT =
5457
RScriptReader.readResourceAsText(Runner.class, "r/core.R");
@@ -59,6 +62,9 @@ public class RLangPApplet extends BuiltinApplet {
5962

6063
private RSketchError terminalException = null;
6164

65+
private boolean hasSize = false;
66+
private SEXP sizeFunction = null;
67+
6268
/**
6369
* Mode for Processing.
6470
*
@@ -98,19 +104,26 @@ public void prePassCode() {
98104
SEXP source = RParser.parseSource(this.programText + "\n", "inline-string");
99105
if (isSameClass(source, ExpressionVector.class)) {
100106
ExpressionVector ev = (ExpressionVector) source;
101-
for (int i = 0; i < ev.length(); ++i) {
102-
/**
103-
* There is a bug, see https://github.com/gaocegege/Processing.R/issues/7 For example,
104-
* processing$line() is also a function call in renjin engine. To solve this problem, add a
105-
* hack to make sure the function is "<-".
106-
*/
107+
List<SEXP> sexps = new ArrayList<SEXP>();
108+
for (int i = ev.length() - 1; i >= 0; --i) {
107109
if (isSameClass(ev.get(i), FunctionCall.class)
108-
&& isSameClass(((FunctionCall) ev.get(i)).getFunction(), Symbol.class)
109-
&& ((Symbol) ((FunctionCall) ev.get(i)).getFunction()).getPrintName().equals("<-")) {
110-
this.renjinEngine.getTopLevelContext().evaluate(ev.get(i),
111-
this.renjinEngine.getTopLevelContext().getEnvironment());
110+
&& isSameClass(((FunctionCall) ev.get(i)).getFunction(), Symbol.class)) {
111+
if (((Symbol) ((FunctionCall) ev.get(i)).getFunction()).getPrintName().equals("<-")) {
112+
this.renjinEngine.getTopLevelContext().evaluate(ev.get(i),
113+
this.renjinEngine.getTopLevelContext().getEnvironment());
114+
sexps.add(ev.get(i));
115+
} else if (((Symbol) ((FunctionCall) ev.get(i)).getFunction()).getPrintName()
116+
.equals(Constant.SIZE_NAME)) {
117+
log("size function is defined in global namespace.");
118+
hasSize = true;
119+
sizeFunction = ev.get(i);
120+
} else {
121+
sexps.add(ev.get(i));
122+
}
112123
}
113124
}
125+
126+
expressionVector = new ExpressionVector(sexps);
114127
}
115128
}
116129

@@ -267,12 +280,13 @@ public void uncaughtException(final Thread t, final Throwable e) {
267280
*/
268281
@Override
269282
public void settings() {
283+
if (mode == Mode.MIXED || mode == Mode.STATIC) {
284+
this.renjinEngine.getTopLevelContext().evaluate(this.sizeFunction,
285+
this.renjinEngine.getTopLevelContext().getEnvironment());
286+
}
270287
Object obj = this.renjinEngine.get(Constant.SETTINGS_NAME);
271288
if (obj.getClass().equals(Closure.class)) {
272289
((Closure) obj).doApply(this.renjinEngine.getTopLevelContext());
273-
} else if (mode == Mode.STATIC) {
274-
// TODO: Implement Static Mode.
275-
// Set size and something else.
276290
}
277291
}
278292

@@ -289,6 +303,8 @@ public void setup() {
289303
if (this.mode == Mode.STATIC) {
290304
try {
291305
log("The mode is static, run the program directly.");
306+
// The code includes size function but it would not raise a error, I don't know what happens
307+
// although it works well.
292308
this.renjinEngine.eval(this.programText);
293309
log("Evaluate the code in static mode.");
294310
} catch (final Exception exception) {
@@ -304,6 +320,10 @@ public void setup() {
304320
}
305321
} else {
306322
System.out.println("The program is in mix mode now.");
323+
Object obj = this.renjinEngine.get(Constant.SETUP_NAME);
324+
if (obj.getClass().equals(Closure.class)) {
325+
((Closure) obj).doApply(this.renjinEngine.getTopLevelContext());
326+
}
307327
}
308328
log("Setup done");
309329
}
@@ -349,10 +369,8 @@ private boolean isActiveMode() {
349369
*
350370
* @return
351371
*/
352-
@SuppressWarnings("rawtypes")
353372
private boolean isMixMode() {
354-
Class closureClass = Closure.class;
355-
return isSameClass(this.renjinEngine.get(Constant.SIZE_NAME), closureClass);
373+
return hasSize;
356374
}
357375

358376
/**

0 commit comments

Comments
 (0)