summaryrefslogtreecommitdiff
path: root/dice-lang/src/bjc/dicelang/v2/Shunter.java
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2017-02-13 02:56:51 -0500
committerbculkin2442 <bjculkin@mix.wvu.edu>2017-02-13 02:56:51 -0500
commitc8bec56ce8bd384b31ab6025ba7d31c3dfb1b874 (patch)
tree3d8e0e80e8bddce01bb4656a036df2b9eb71f3d1 /dice-lang/src/bjc/dicelang/v2/Shunter.java
parent517b89b4aa936be1457bb26290b23369cbe4a9f1 (diff)
Lexer/shunter work
Diffstat (limited to 'dice-lang/src/bjc/dicelang/v2/Shunter.java')
-rw-r--r--dice-lang/src/bjc/dicelang/v2/Shunter.java111
1 files changed, 108 insertions, 3 deletions
diff --git a/dice-lang/src/bjc/dicelang/v2/Shunter.java b/dice-lang/src/bjc/dicelang/v2/Shunter.java
index bca08eb..3edceeb 100644
--- a/dice-lang/src/bjc/dicelang/v2/Shunter.java
+++ b/dice-lang/src/bjc/dicelang/v2/Shunter.java
@@ -5,7 +5,9 @@ import bjc.utils.funcdata.FunctionalMap;
import bjc.utils.funcdata.IList;
import bjc.utils.funcdata.IMap;
+import java.util.Deque;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.Set;
import static bjc.dicelang.v2.Token.Type.*;
@@ -42,18 +44,121 @@ public class Shunter {
ops.put(DICEGROUP, 0 + DICE_PREC);
ops.put(DICECONCAT, 1 + DICE_PREC);
+ ops.put(DICELIST, 2 + DICE_PREC);
ops.put(LET, 0 + EXPR_PREC);
ops.put(BIND, 1 + EXPR_PREC);
}
- public IList<Token> shuntTokens(IList<Token> tks) {
- IList<Token> returned = new FunctionalList<>();
+ public boolean shuntTokens(IList<Token> tks, IList<Token> returned) {
+ Deque<Token> opStack = new LinkedList<>();
+
+ boolean unaryMode = false;
+ Deque<Token> unaryOps = new LinkedList<>();
for(Token tk : tks.toIterable()) {
+ if(unaryMode) {
+ // @TODO finish unary mode
+ if(unaryAdjectives.contains(tk.type) || unaryAdverbs.contains(tk.type)) {
+ unaryOps.push(tk);
+ continue;
+ }
+
+ Token currOperator = unaryOps.peek();
+
+ if(unaryAdjectives.contains(currOperator.type)) {
+ boolean isOp = ops.containsKey(tk.type)
+ || unaryAdverbs.contains(tk.type)
+ || unaryAdjectives.contains(tk.type);
+
+ if(isOp) {
+ System.out.printf("\tError: Unary operator %s is an"
+ + " adjective, not an adverb (can't be applied"
+ + " to operator %s)\n", currOperator, tk );
+
+ return false;
+ }
+
+ returned.add(tk);
+ returned.add(unaryOps.pop());
+ } else if (unaryAdverbs.contains(currOperator.type)) {
+ if(opStack.size() < 1) {
+ System.out.printf("\tError: Unary operators %s is an adverb,"
+ + " but there is no operator to apply it to\n");
+ }
+
+ Token currOperand = opStack.peek();
+
+ boolean isOp = ops.containsKey(currOperand.type)
+ || unaryAdverbs.contains(currOperand.type)
+ || unaryAdjectives.contains(currOperand.type);
+
+ if(!isOp) {
+ System.out.printf("\tError: Unary operator %s is an adverb,"
+ + " not an adjective (can't be applied to operand %s)\n",
+ currOperator, tk);
+
+ return false;
+ }
+
+ returned.add(tk);
+ returned.add(unaryOps.pop());
+ }
+
+ if(unaryOps.isEmpty()) unaryMode = false;
+ } else {
+ if(unaryAdjectives.contains(tk.type) || unaryAdverbs.contains(tk.type)) {
+ unaryMode = true;
+
+ unaryOps.add(tk);
+ continue;
+ } else if(ops.containsKey(tk.type)) {
+ while(!opStack.isEmpty()
+ && isHigherPrec(tk.type, opStack.peek().type)) {
+ returned.add(opStack.pop());
+ }
+
+ opStack.push(tk);
+ } else if(tk.type == OPAREN) {
+ opStack.push(tk);
+ } else if(tk.type == CPAREN) {
+ Token currTk = opStack.peek();
+
+ while(currTk.type != OPAREN && currTk.intValue != tk.intValue) {
+ if(opStack.isEmpty()) {
+ System.out.printf("\tError: Could not find matching parenthesis"
+ + " with matching level %d", tk.intValue);
+
+ return false;
+ }
+
+ returned.add(opStack.pop());
+ }
+ } else {
+ returned.add(tk);
+ }
+ }
+ }
+
+ // Flush leftover operators
+ while(!opStack.isEmpty()) {
+ returned.add(opStack.pop());
+ }
+ return true;
+ }
+
+ private boolean isHigherPrec(Token.Type left, Token.Type right) {
+ boolean exists = ops.containsKey(right);
+
+ // If it doesn't, the left is higher precedence.
+ if (!exists) {
+ return false;
}
- return returned;
+ int rightPrecedence = ops.get(right);
+ int leftPrecedence = ops.get(left);
+
+ return rightPrecedence >= leftPrecedence;
}
}