Skip to content

Commit 08f920f

Browse files
committed
implemented EVAR
1 parent 4f0088a commit 08f920f

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

src/main/java/com/falsepattern/jfunge/interpreter/ExecutionContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public interface ExecutionContext {
4141

4242
Map<String, String> env();
4343

44+
List<String> envKeys();
45+
4446
int input(boolean stagger);
4547

4648
OutputStream output();

src/main/java/com/falsepattern/jfunge/interpreter/Interpreter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.HashMap;
2929
import java.util.List;
3030
import java.util.Map;
31+
import java.util.TreeMap;
3132

3233
@Accessors(fluent = true)
3334
public class Interpreter implements ExecutionContext {
@@ -77,6 +78,9 @@ public boolean writeFile(String file, byte[] data) throws IOException {
7778
@Getter
7879
private final Map<String, String> env;
7980

81+
@Getter
82+
private final List<String> envKeys;
83+
8084
private final TIntObjectMap<Map<String, Object>> globals = new TIntObjectHashMap<>();
8185

8286
private Integer exitCode = null;
@@ -140,6 +144,8 @@ public Interpreter(String[] args, InputStream input, OutputStream output, FileIO
140144
this.env = new HashMap<>();
141145
}
142146
this.env.put("JFUNGE_ENV", featureSet.environment ? "PASS" : "BLOCK");
147+
envKeys = new ArrayList<>();
148+
envKeys.addAll(this.env.keySet());
143149

144150
if (!featureSet.perl) {
145151
fingerprintBlackList.add(PERL.INSTANCE.code());

src/main/java/com/falsepattern/jfunge/interpreter/instructions/Funge98.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.BASE;
66
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.CPLI;
77
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.DATE;
8+
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.EVAR;
89
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.FPDP;
910
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.FPSP;
1011
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.HRTI;
@@ -49,6 +50,7 @@ public class Funge98 implements InstructionSet {
4950
addFingerprint(BASE.INSTANCE);
5051
addFingerprint(CPLI.INSTANCE);
5152
addFingerprint(DATE.INSTANCE);
53+
addFingerprint(EVAR.INSTANCE);
5254
addFingerprint(FPSP.INSTANCE);
5355
addFingerprint(FPDP.INSTANCE);
5456
addFingerprint(HRTI.INSTANCE);
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.falsepattern.jfunge.interpreter.instructions.fingerprints;
2+
3+
import com.falsepattern.jfunge.interpreter.ExecutionContext;
4+
import com.falsepattern.jfunge.interpreter.instructions.Fingerprint;
5+
import lombok.NoArgsConstructor;
6+
import lombok.val;
7+
8+
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
9+
public class EVAR implements Fingerprint {
10+
public static final EVAR INSTANCE = new EVAR();
11+
@Override
12+
public int code() {
13+
return 0x45564152;
14+
}
15+
16+
@Instr('G')
17+
public static void getEnvironmentVariable(ExecutionContext ctx) {
18+
val stack = ctx.stack();
19+
val key = stack.popString();
20+
val value = ctx.env().get(key);
21+
if (value == null) {
22+
ctx.interpret('r');
23+
return;
24+
} else {
25+
stack.pushString(value);
26+
}
27+
}
28+
29+
@Instr('N')
30+
public static void getEnvironmentVariableCount(ExecutionContext ctx) {
31+
ctx.stack().push(ctx.envKeys().size());
32+
}
33+
34+
@Instr('P')
35+
public static void setEnvironmentVariable(ExecutionContext ctx) {
36+
val stack = ctx.stack();
37+
val keyValuePar = stack.popString();
38+
val equalsIndex = keyValuePar.indexOf('=');
39+
if (equalsIndex == -1) {
40+
ctx.interpret('r');
41+
return;
42+
}
43+
val key = keyValuePar.substring(0, equalsIndex);
44+
val value = keyValuePar.substring(equalsIndex + 1);
45+
if (!ctx.env().containsKey(key)) {
46+
ctx.envKeys().add(key);
47+
}
48+
ctx.env().put(key, value);
49+
}
50+
51+
@Instr('V')
52+
public static void getEnvironmentVariableAtIndex(ExecutionContext ctx) {
53+
val stack = ctx.stack();
54+
val index = stack.pop();
55+
val keys = ctx.envKeys();
56+
if (index < 0 || index >= keys.size()) {
57+
ctx.interpret('r');
58+
return;
59+
}
60+
val key = keys.get(index);
61+
stack.pushString(key + "=" + ctx.env().get(key));
62+
}
63+
}

0 commit comments

Comments
 (0)