Skip to content

Commit 6221dfa

Browse files
committed
add MultListExpr, PlusListExpr
1 parent 5d67d5d commit 6221dfa

File tree

3 files changed

+278
-36
lines changed

3 files changed

+278
-36
lines changed

src/main/java/io/polypen/parse/Macro.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
import io.polypen.parse.Parser.Expr;
44
import io.polypen.parse.Parser.ListExpr;
55
import io.polypen.parse.Parser.MultExpr;
6+
import io.polypen.parse.Parser.MultListExpr;
67
import io.polypen.parse.Parser.NumberExpr;
8+
import io.polypen.parse.Parser.PlusListExpr;
79
import io.polypen.parse.Parser.VarExp;
810

911
import java.util.ArrayList;
1012
import java.util.List;
1113

1214
public class Macro {
1315

14-
static List<Expr> applyStarMacro(ListExpr listExpr) {
15-
List<Expr> exprs = listExpr.value();
16+
static Expr applyStarMacro(List<Expr> exprs) {
1617
List<Expr> exprsCopy = new ArrayList<>(exprs.size());
1718
List<Expr> region = new ArrayList<>(exprs.size());
1819
Expr previous = null;
@@ -21,25 +22,36 @@ static List<Expr> applyStarMacro(ListExpr listExpr) {
2122
region.add(previous);
2223
} else {
2324
if (!region.isEmpty()) {
24-
exprsCopy.add(new ListExpr(new ArrayList<>(region)));
25+
exprsCopy.add(new MultListExpr(new ArrayList<>(region)));
2526
region.clear();
2627
}
2728
if (previous != null) {
2829
exprsCopy.add(previous);
2930
}
3031
}
31-
previous = expr;
32+
previous = expandRecursively(expr);
3233
}
3334
if (exprsCopy.isEmpty()) {
34-
return listExpr.value();
35+
List<Expr> mapped = new ArrayList<>();
36+
for (Expr expr : exprs) {
37+
mapped.add(expandRecursively(expr));
38+
}
39+
return new MultListExpr(mapped);
3540
}
3641
if (region.isEmpty()) {
37-
exprsCopy.add(previous);
42+
exprsCopy.add(expandRecursively(previous));
3843
} else {
39-
region.add(previous);
40-
exprsCopy.add(new ListExpr(region));
44+
region.add(expandRecursively(previous));
45+
exprsCopy.add(new MultListExpr(region));
4146
}
42-
return exprsCopy;
47+
return new PlusListExpr(exprsCopy);
48+
}
49+
50+
private static Expr expandRecursively(Expr expr) {
51+
return switch (expr) {
52+
case ListExpr x -> applyStarMacro(x.value());
53+
default -> expr;
54+
};
4355
}
4456

4557
public static boolean isStrongBind(Expr expr) {
@@ -48,6 +60,8 @@ public static boolean isStrongBind(Expr expr) {
4860
}
4961
return switch (expr) {
5062
case ListExpr ignored -> true;
63+
case PlusListExpr ignored -> true;
64+
case MultListExpr ignored -> true;
5165
case MultExpr ignored -> true;
5266
case NumberExpr ignored -> true;
5367
case VarExp ignored -> true;

src/main/java/io/polypen/parse/Parser.java

Lines changed: 215 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,34 @@ public static ListExpr parse(String s) {
111111
}
112112
}
113113

114-
public sealed interface Expr permits PlusExpr, MinusExpr, MultExpr, ListExpr, NumberExpr, VarExp {
114+
public sealed interface Expr permits PlusExpr, MinusExpr, MultExpr, ListExpr, NumberExpr, VarExp, PlusListExpr, MultListExpr {
115+
int size();
116+
117+
Expr getFirst();
118+
119+
List<Expr> getExprs();
115120
}
116121

117122
public static final class PlusExpr implements Expr {
118123
@Override
119124
public String toString() {
120125
return "+";
121126
}
127+
128+
@Override
129+
public int size() {
130+
return 0;
131+
}
132+
133+
@Override
134+
public Expr getFirst() {
135+
return null;
136+
}
137+
138+
@Override
139+
public List<Expr> getExprs() {
140+
return List.of();
141+
}
122142
}
123143

124144
public static final Expr PLUS = new PlusExpr();
@@ -128,6 +148,21 @@ public static final class MinusExpr implements Expr {
128148
public String toString() {
129149
return "-";
130150
}
151+
152+
@Override
153+
public int size() {
154+
return 0;
155+
}
156+
157+
@Override
158+
public Expr getFirst() {
159+
return null;
160+
}
161+
162+
@Override
163+
public List<Expr> getExprs() {
164+
return List.of();
165+
}
131166
}
132167

133168
public static final Expr MINUS = new MinusExpr();
@@ -137,25 +172,112 @@ public static final class MultExpr implements Expr {
137172
public String toString() {
138173
return "*";
139174
}
175+
176+
@Override
177+
public int size() {
178+
return 0;
179+
}
180+
181+
@Override
182+
public Expr getFirst() {
183+
return null;
184+
}
185+
186+
@Override
187+
public List<Expr> getExprs() {
188+
return List.of();
189+
}
140190
}
141191

142192
public static final Expr MULT = new MultExpr();
143193

144194
public static Polynomial eval(Expr expr) {
145195
return switch (expr) {
196+
case PlusListExpr listExpr -> {
197+
if (listExpr.value.size() == 1) {
198+
yield eval(listExpr.value().getFirst());
199+
}
200+
Expr exprs = Macro.applyStarMacro(listExpr.value);
201+
if (exprs.size() == 1) {
202+
yield eval(exprs.getFirst());
203+
}
204+
Polynomial result;
205+
if (hasPlus(exprs)) {
206+
result = Polynomial.ZERO;
207+
int sign = 1;
208+
for (Expr exp : exprs.getExprs()) {
209+
if (isMinus(exp)) {
210+
sign = -1;
211+
continue;
212+
}
213+
if (isPlus(exp)) {
214+
sign = 1;
215+
continue;
216+
}
217+
Polynomial p = eval(exp);
218+
result = result.add(p.multiply(sign));
219+
}
220+
} else {
221+
result = Polynomial.ONE;
222+
for (Expr exp : exprs.getExprs()) {
223+
if (isOperator(exp)) {
224+
continue;
225+
}
226+
Polynomial p = eval(exp);
227+
result = result.multiply(p);
228+
}
229+
}
230+
yield result;
231+
}
232+
case MultListExpr listExpr -> {
233+
if (listExpr.value.size() == 1) {
234+
yield eval(listExpr.value().getFirst());
235+
}
236+
Expr exprs = Macro.applyStarMacro(listExpr.value);
237+
if (exprs.size() == 1) {
238+
yield eval(exprs.getFirst());
239+
}
240+
Polynomial result;
241+
if (hasPlus(exprs)) {
242+
result = Polynomial.ZERO;
243+
int sign = 1;
244+
for (Expr exp : exprs.getExprs()) {
245+
if (isMinus(exp)) {
246+
sign = -1;
247+
continue;
248+
}
249+
if (isPlus(exp)) {
250+
sign = 1;
251+
continue;
252+
}
253+
Polynomial p = eval(exp);
254+
result = result.add(p.multiply(sign));
255+
}
256+
} else {
257+
result = Polynomial.ONE;
258+
for (Expr exp : exprs.getExprs()) {
259+
if (isOperator(exp)) {
260+
continue;
261+
}
262+
Polynomial p = eval(exp);
263+
result = result.multiply(p);
264+
}
265+
}
266+
yield result;
267+
}
146268
case ListExpr listExpr -> {
147269
if (listExpr.value.size() == 1) {
148270
yield eval(listExpr.value().getFirst());
149271
}
150-
List<Expr> exprs = Macro.applyStarMacro(listExpr);
272+
Expr exprs = Macro.applyStarMacro(listExpr.value);
151273
if (exprs.size() == 1) {
152274
yield eval(exprs.getFirst());
153275
}
154276
Polynomial result;
155277
if (hasPlus(exprs)) {
156278
result = Polynomial.ZERO;
157279
int sign = 1;
158-
for (Expr exp : exprs) {
280+
for (Expr exp : exprs.getExprs()) {
159281
if (isMinus(exp)) {
160282
sign = -1;
161283
continue;
@@ -169,7 +291,7 @@ public static Polynomial eval(Expr expr) {
169291
}
170292
} else {
171293
result = Polynomial.ONE;
172-
for (Expr exp : exprs) {
294+
for (Expr exp : exprs.getExprs()) {
173295
if (isOperator(exp)) {
174296
continue;
175297
}
@@ -202,32 +324,119 @@ private static boolean isMinus(Expr expr) {
202324
return expr instanceof MinusExpr;
203325
}
204326

205-
private static boolean hasPlus(List<Expr> exprs) {
206-
for (Expr expr : exprs) {
327+
private static boolean hasPlus(Expr exprs) {
328+
for (Expr expr : exprs.getExprs()) {
207329
if (expr instanceof PlusExpr || expr instanceof MinusExpr) {
208330
return true;
209331
}
210332
}
211333
return false;
212334
}
213335

336+
public record MultListExpr(List<Expr> value) implements Expr {
337+
public static MultListExpr of(Expr... value) {
338+
return new MultListExpr(List.of(value));
339+
}
340+
341+
@Override
342+
public int size() {
343+
return value().size();
344+
}
345+
346+
@Override
347+
public Expr getFirst() {
348+
return value.getFirst();
349+
}
350+
351+
@Override
352+
public List<Expr> getExprs() {
353+
return value;
354+
}
355+
}
356+
357+
public record PlusListExpr(List<Expr> value) implements Expr {
358+
public static PlusListExpr of(Expr... value) {
359+
return new PlusListExpr(List.of(value));
360+
}
361+
362+
363+
@Override
364+
public int size() {
365+
return value().size();
366+
}
367+
368+
@Override
369+
public Expr getFirst() {
370+
return value.getFirst();
371+
}
372+
373+
@Override
374+
public List<Expr> getExprs() {
375+
return value;
376+
}
377+
}
378+
214379
public record ListExpr(List<Expr> value) implements Expr {
215380
public static ListExpr of(Expr... value) {
216381
return new ListExpr(List.of(value));
217382
}
218383

384+
@Override
385+
public int size() {
386+
return value().size();
387+
}
388+
389+
@Override
390+
public Expr getFirst() {
391+
return value.getFirst();
392+
}
393+
394+
@Override
395+
public List<Expr> getExprs() {
396+
return value;
397+
}
219398
}
220399

221400
public record NumberExpr(int value) implements Expr {
222401
public static NumberExpr of(int value) {
223402
return new NumberExpr(value);
224403
}
404+
405+
@Override
406+
public int size() {
407+
return 1;
408+
}
409+
410+
@Override
411+
public Expr getFirst() {
412+
return this;
413+
}
414+
415+
@Override
416+
public List<Expr> getExprs() {
417+
return List.of(this);
418+
}
225419
}
226420

227421
public record VarExp(String var, int exp) implements Expr {
228422
public static VarExp of(String var, int exp) {
229423
return new VarExp(var, exp);
230424
}
425+
426+
@Override
427+
public int size() {
428+
return 1;
429+
}
430+
431+
@Override
432+
public Expr getFirst() {
433+
return this;
434+
}
435+
436+
@Override
437+
public List<Expr> getExprs() {
438+
return List.of(this);
439+
}
231440
}
232441

233442
private Parser() {

0 commit comments

Comments
 (0)