Skip to content

Commit 47936fb

Browse files
committed
implement DATE
1 parent 3f59584 commit 47936fb

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.falsepattern.jfunge.interpreter.ExecutionContext;
55
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.BASE;
66
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.CPLI;
7+
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.DATE;
78
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.FPDP;
89
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.FPSP;
910
import com.falsepattern.jfunge.interpreter.instructions.fingerprints.HRTI;
@@ -47,6 +48,7 @@ public class Funge98 implements InstructionSet {
4748
addFingerprint(_3DSP.INSTANCE);
4849
addFingerprint(BASE.INSTANCE);
4950
addFingerprint(CPLI.INSTANCE);
51+
addFingerprint(DATE.INSTANCE);
5052
addFingerprint(FPSP.INSTANCE);
5153
addFingerprint(FPDP.INSTANCE);
5254
addFingerprint(HRTI.INSTANCE);
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
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+
import lombok.var;
8+
9+
import java.time.DateTimeException;
10+
import java.time.Duration;
11+
import java.time.LocalDate;
12+
import java.time.temporal.JulianFields;
13+
14+
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
15+
public class DATE implements Fingerprint {
16+
public static final DATE INSTANCE = new DATE();
17+
@Override
18+
public int code() {
19+
return 0x44415445;
20+
}
21+
22+
@Instr('A')
23+
public static void addDaysToDate(ExecutionContext ctx) {
24+
val stack = ctx.stack();
25+
val days = stack.pop();
26+
val d = stack.pop();
27+
val m = stack.pop();
28+
val y = stack.pop();
29+
if (y == 0) {
30+
ctx.interpret('r');
31+
return;
32+
}
33+
val date = dateOrReflect(ctx, () -> LocalDate.of(y, m, d));
34+
if (date == null) {
35+
return;
36+
}
37+
val newDate = date.plusDays(days);
38+
stack.push(newDate.getYear());
39+
stack.push(newDate.getMonthValue());
40+
stack.push(newDate.getDayOfMonth());
41+
}
42+
43+
@Instr('C')
44+
public static void julianDayToDate(ExecutionContext ctx) {
45+
val stack = ctx.stack();
46+
val jd = stack.pop();
47+
val date = dateOrReflect(ctx, () -> LocalDate.ofEpochDay(jd - 2440588));
48+
if (date == null) {
49+
return;
50+
}
51+
var y = date.getYear();
52+
if (y == 0) {
53+
ctx.interpret('r');
54+
return;
55+
}
56+
if (y < 0) y--;
57+
stack.push(y);
58+
stack.push(date.getMonthValue());
59+
stack.push(date.getDayOfMonth());
60+
}
61+
62+
@Instr('D')
63+
public static void daysBetweenDates(ExecutionContext ctx) {
64+
val stack = ctx.stack();
65+
val d2 = stack.pop();
66+
val m2 = stack.pop();
67+
val y2 = stack.pop();
68+
val d1 = stack.pop();
69+
val m1 = stack.pop();
70+
val y1 = stack.pop();
71+
if (y1 == 0 || y2 == 0) {
72+
ctx.interpret('r');
73+
return;
74+
}
75+
val date1 = dateOrReflect(ctx, () -> LocalDate.of(y1, m1, d1));
76+
if (date1 == null) {
77+
return;
78+
}
79+
val date2 = dateOrReflect(ctx, () -> LocalDate.of(y2, m2, d2));
80+
if (date2 == null) {
81+
return;
82+
}
83+
stack.push((int) Duration.between(date2.atStartOfDay(), date1.atStartOfDay()).toDays());
84+
}
85+
86+
@Instr('J')
87+
public static void dateToJulianDay(ExecutionContext ctx) {
88+
val stack = ctx.stack();
89+
val d = stack.pop();
90+
val m = stack.pop();
91+
var y = stack.pop();
92+
if (y == 0) {
93+
ctx.interpret('r');
94+
return;
95+
}
96+
if (y < 0) y++;
97+
int finalY = y;
98+
val date = dateOrReflect(ctx, () -> LocalDate.of(finalY, m, d));
99+
if (date == null) {
100+
return;
101+
}
102+
val x = (int) JulianFields.JULIAN_DAY.getFrom(date);
103+
System.out.println(x);
104+
stack.push(x);
105+
}
106+
107+
@Instr('T')
108+
public static void yearPlusDayToDate(ExecutionContext ctx) {
109+
val stack = ctx.stack();
110+
val day = stack.pop() + 1;
111+
val year = stack.pop();
112+
if (year == 0) {
113+
ctx.interpret('r');
114+
return;
115+
}
116+
val date = dateOrReflect(ctx, () -> LocalDate.ofYearDay(year, day));
117+
if (date == null) {
118+
return;
119+
}
120+
stack.push(date.getYear());
121+
stack.push(date.getMonthValue());
122+
stack.push(date.getDayOfMonth());
123+
}
124+
125+
@Instr('W')
126+
public static void dayOfWeek(ExecutionContext ctx) {
127+
val stack = ctx.stack();
128+
val d = stack.pop();
129+
val m = stack.pop();
130+
val y = stack.pop();
131+
if (y == 0) {
132+
ctx.interpret('r');
133+
return;
134+
}
135+
val date = dateOrReflect(ctx, () -> LocalDate.of(y, m, d));
136+
if (date == null) {
137+
return;
138+
}
139+
stack.push(date.getDayOfWeek().getValue() - 1);
140+
}
141+
142+
@Instr('Y')
143+
public static void dayOfYear(ExecutionContext ctx) {
144+
val stack = ctx.stack();
145+
val d = stack.pop();
146+
val m = stack.pop();
147+
val y = stack.pop();
148+
if (y == 0) {
149+
ctx.interpret('r');
150+
return;
151+
}
152+
val date = dateOrReflect(ctx, () -> LocalDate.of(y, m, d));
153+
if (date == null) {
154+
return;
155+
}
156+
stack.push(date.getDayOfYear() - 1);
157+
}
158+
159+
private interface DateSupplier {
160+
LocalDate supply() throws DateTimeException;
161+
}
162+
163+
private static LocalDate dateOrReflect(ExecutionContext ctx, DateSupplier supplier) {
164+
try {
165+
return supplier.supply();
166+
} catch (DateTimeException e) {
167+
ctx.interpret('r');
168+
return null;
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)