summaryrefslogtreecommitdiff
path: root/parser/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'parser/src/main/java')
-rw-r--r--parser/src/main/java/lv/enes/orang/parser/Parser.java59
1 files changed, 44 insertions, 15 deletions
diff --git a/parser/src/main/java/lv/enes/orang/parser/Parser.java b/parser/src/main/java/lv/enes/orang/parser/Parser.java
index 0ff1f78..06183a3 100644
--- a/parser/src/main/java/lv/enes/orang/parser/Parser.java
+++ b/parser/src/main/java/lv/enes/orang/parser/Parser.java
@@ -131,23 +131,51 @@ public class Parser {
131 131
132 private List<ArgSpec> parseArgSpecs() throws ParserException { 132 private List<ArgSpec> parseArgSpecs() throws ParserException {
133 var argSpecs = new ArrayList<ArgSpec>(); 133 var argSpecs = new ArrayList<ArgSpec>();
134 while (true) { 134 while (couldStartArgSpec(input.peek().type())) {
135 if (input.peek().type() == Token.Type.IDENTIFIER) { 135 argSpecs.add(parseArgSpec());
136 argSpecs.add(ArgSpec.named(input.next().literal()));
137 } else if (input.peek().type() == Token.Type.PAREN_LEFT) {
138 consumeToken(Token.Type.PAREN_LEFT);
139 consumeToken(Token.Type.PAREN_RIGHT);
140 argSpecs.add(ArgSpec.nothing());
141 } else if (input.peek().type() == Token.Type.UNDERSCORE) {
142 consumeToken(Token.Type.UNDERSCORE);
143 argSpecs.add(ArgSpec.ignored());
144 } else {
145 break;
146 }
147 } 136 }
137 argSpecs.trimToSize();
148 return Collections.unmodifiableList(argSpecs); 138 return Collections.unmodifiableList(argSpecs);
149 } 139 }
150 140
141 private boolean couldStartArgSpec(Token.Type type) {
142 return switch (type) {
143 case IDENTIFIER, PAREN_LEFT, UNDERSCORE -> true;
144 default -> false;
145 };
146 }
147
148 private ArgSpec parseArgSpec() throws ParserException {
149 var token = input.next();
150 return switch (token.type()) {
151 case IDENTIFIER -> new ArgSpecNamed(token.literal());
152 case PAREN_LEFT -> {
153 if (maybeConsumeToken(Token.Type.PAREN_RIGHT)) {
154 yield new ArgSpecTuple(List.of());
155 }
156 var argspec = parseArgSpec();
157 if (maybeConsumeToken(Token.Type.COMMA)) {
158 yield parseArgSpecTuple(argspec);
159 }
160 consumeToken(Token.Type.PAREN_RIGHT);
161 yield argspec;
162 }
163 case UNDERSCORE -> ArgSpecIgnored.INSTANCE;
164 default -> throw new ParserException(STR."Unexpected token when parsing argspecs: \{token}");
165 };
166 }
167
168 private ArgSpec parseArgSpecTuple(ArgSpec first) throws ParserException {
169 var specs = new ArrayList<ArgSpec>();
170 specs.add(first);
171 do {
172 specs.add(parseArgSpec());
173 maybeConsumeToken(Token.Type.COMMA);
174 } while (!maybeConsumeToken(Token.Type.PAREN_RIGHT));
175 specs.trimToSize();
176 return new ArgSpecTuple(specs);
177 }
178
151 private Expression parseBinaryExpression() throws ParserException { 179 private Expression parseBinaryExpression() throws ParserException {
152 var lhs = parseCallExpression(); 180 var lhs = parseCallExpression();
153 if (isNotBinaryOp(input.peek())) { 181 if (isNotBinaryOp(input.peek())) {
@@ -283,7 +311,7 @@ public class Parser {
283 case PAREN_LEFT -> { 311 case PAREN_LEFT -> {
284 consumeToken(Token.Type.PAREN_LEFT); 312 consumeToken(Token.Type.PAREN_LEFT);
285 if (maybeConsumeToken(Token.Type.PAREN_RIGHT)) { 313 if (maybeConsumeToken(Token.Type.PAREN_RIGHT)) {
286 yield EmptyTupleLiteral.INSTANCE; 314 yield new TupleExpression(List.of());
287 } 315 }
288 var expr = parseExpression(); 316 var expr = parseExpression();
289 if (maybeConsumeToken(Token.Type.COMMA)) { 317 if (maybeConsumeToken(Token.Type.COMMA)) {
@@ -346,7 +374,8 @@ public class Parser {
346 exprs.add(parseExpression()); 374 exprs.add(parseExpression());
347 maybeConsumeToken(Token.Type.COMMA); 375 maybeConsumeToken(Token.Type.COMMA);
348 } while (!maybeConsumeToken(Token.Type.PAREN_RIGHT)); 376 } while (!maybeConsumeToken(Token.Type.PAREN_RIGHT));
349 return new TupleExpression(new NonEmptyList<>(exprs)); 377 exprs.trimToSize();
378 return new TupleExpression(exprs);
350 } 379 }
351 380
352 private Expression parseUnaryExpression() throws ParserException { 381 private Expression parseUnaryExpression() throws ParserException {