summaryrefslogtreecommitdiff
path: root/dice-lang/src/bjc/dicelang/v2/Shunter.java
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2017-02-26 08:22:59 -0500
committerbculkin2442 <bjculkin@mix.wvu.edu>2017-02-27 03:55:15 -0500
commitb776b8a558a2e27e4551768050f7e34e233326b5 (patch)
tree6f574992a406d65ec3fac24a3b0bc498e9d9243a /dice-lang/src/bjc/dicelang/v2/Shunter.java
parent07d8b9547a654021d8c56021779f4cdaa5f03f1b (diff)
Dice math
Diffstat (limited to 'dice-lang/src/bjc/dicelang/v2/Shunter.java')
-rw-r--r--dice-lang/src/bjc/dicelang/v2/Shunter.java225
1 files changed, 125 insertions, 100 deletions
diff --git a/dice-lang/src/bjc/dicelang/v2/Shunter.java b/dice-lang/src/bjc/dicelang/v2/Shunter.java
index e95b642..d5f9135 100644
--- a/dice-lang/src/bjc/dicelang/v2/Shunter.java
+++ b/dice-lang/src/bjc/dicelang/v2/Shunter.java
@@ -43,26 +43,29 @@ public class Shunter {
unaryAdjectives.add(COERCE);
- ops.put(ADD, 0 + MATH_PREC);
- ops.put(SUBTRACT, 0 + MATH_PREC);
+ ops.put(ADD, 0 + MATH_PREC);
+ ops.put(SUBTRACT, 0 + MATH_PREC);
- ops.put(MULTIPLY, 1 + MATH_PREC);
- ops.put(IDIVIDE, 1 + MATH_PREC);
- ops.put(DIVIDE, 1 + MATH_PREC);
+ ops.put(MULTIPLY, 1 + MATH_PREC);
+ ops.put(IDIVIDE, 1 + MATH_PREC);
+ ops.put(DIVIDE, 1 + MATH_PREC);
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);
+ ops.put(LET, 0 + EXPR_PREC);
+ ops.put(BIND, 1 + EXPR_PREC);
}
private boolean isUnary(Token ty) {
- switch(ty.type) {
- default:
- return false;
- }
+ if(unaryAdjectives.contains(ty)) return true;
+ if(unaryAdverbs.contains(ty)) return true;
+ if(unaryGerunds.contains(ty)) return true;
+
+ return false;
}
private boolean isOp(Token tk) {
@@ -77,111 +80,119 @@ public class Shunter {
return false;
}
- public boolean shuntTokens(IList<Token> tks, IList<Token> returned) {
- Deque<Token> opStack = new LinkedList<>();
+ private boolean shuntToken(Token tk, Deque<Token> opStack,
+ Deque<Token> unaryStack, Deque<Token> currReturned,
+ Deque<Token> feed) {
+ if(unaryStack.size() != 0) {
+ if(isUnary(tk)) {
+ unaryStack.add(tk);
+ return true;
+ }
- boolean unaryMode = false;
- Deque<Token> unaryOps = new LinkedList<>();
+ Token unaryOp = unaryStack.pop();
- Deque<Token> currReturned = new LinkedList<>();
+ Token.Type unaryType = unaryOp.type;
- for(Token tk : tks.toIterable()) {
- if(unaryMode) {
- if(isUnary(tk)) {
- unaryOps.add(tk);
- continue;
+ if(unaryAdjectives.contains(unaryType)) {
+ if(isOp(tk)) {
+ Errors.inst.printError(EK_SHUNT_NOTADV, unaryOp.toString(), tk.toString());
+ return false;
}
- Token unaryOp = unaryOps.pop();
-
- Token.Type unaryType = unaryOp.type;
-
- if(unaryAdjectives.contains(unaryType)) {
- if(isOp(tk)) {
- Errors.inst.printError(EK_SHUNT_NOTADV, unaryOp.toString(), tk.toString());
- return false;
- }
-
- Token newTok = new Token(TAGOPR);
-
- if(tk.type == TAGOP) {
- newTok.tokenValues = tk.tokenValues;
- } else {
- newTok.tokenValues = new FunctionalList<>();
- }
-
- newTok.tokenValues.add(unaryOp);
- opStack.push(newTok);
- } else if(unaryAdverbs.contains(unaryType)) {
- // @TODO finish implementing unary operators
- // this will require adding a 'backfeed' to the shunter to catch
- // tokens we missed while parsing unary operators
+ Token newTok = new Token(TAGOPR);
+
+ if(tk.type == TAGOP) {
+ newTok.tokenValues = tk.tokenValues;
+ } else {
+ newTok.tokenValues = new FunctionalList<>();
}
- }
- if(isUnary(tk)) {
- unaryMode = true;
+ newTok.tokenValues.add(unaryOp);
+ opStack.push(newTok);
- unaryOps.add(tk);
- continue;
- } else if(isOp(tk)) {
- while(!opStack.isEmpty() && isHigherPrec(tk, opStack.peek())) {
- currReturned.addLast(opStack.pop());
- }
+ return true;
+ } else if(unaryAdverbs.contains(unaryType)) {
+
+ }
+ }
- opStack.push(tk);
- } else if(tk.type == OPAREN || tk.type == OBRACE) {
- opStack.push(tk);
-
- if(tk.type == OBRACE) currReturned.addLast(tk);
- } else if(tk.type == CPAREN || tk.type == CBRACE) {
- Token matching = null;
-
- switch(tk.type) {
- case CPAREN:
- matching = new Token(OPAREN, tk.intValue);
- break;
- case CBRACE:
- matching = new Token(OBRACE, tk.intValue);
- break;
- default:
- break;
- }
+ if(isUnary(tk)) {
+ unaryStack.add(tk);
+ return true;
+ } else if(isOp(tk)) {
+ while(!opStack.isEmpty() && isHigherPrec(tk, opStack.peek())) {
+ currReturned.addLast(opStack.pop());
+ }
- if(!opStack.contains(matching)) {
- Errors.inst.printError(EK_SHUNT_NOGROUP, tk.toString(), matching.toString());
- return false;
- }
+ opStack.push(tk);
+ } else if(tk.type == OPAREN || tk.type == OBRACE) {
+ opStack.push(tk);
+
+ if(tk.type == OBRACE) currReturned.addLast(tk);
+ } else if(tk.type == CPAREN || tk.type == CBRACE) {
+ Token matching = null;
+
+ switch(tk.type) {
+ case CPAREN:
+ matching = new Token(OPAREN, tk.intValue);
+ break;
+ case CBRACE:
+ matching = new Token(OBRACE, tk.intValue);
+ break;
+ default:
+ break;
+ }
- while(!opStack.peek().equals(matching)) {
- currReturned.addLast(opStack.pop());
- }
+ if(!opStack.contains(matching)) {
+ Errors.inst.printError(EK_SHUNT_NOGROUP, tk.toString(), matching.toString());
+ return false;
+ }
- if(tk.type == CBRACE) {
- currReturned.addLast(tk);
- }
+ while(!opStack.peek().equals(matching)) {
+ currReturned.addLast(opStack.pop());
+ }
- opStack.pop();
- } else if(tk.type == GROUPSEP) {
- IList<Token> group = new FunctionalList<>();
+ if(tk.type == CBRACE) {
+ currReturned.addLast(tk);
+ }
- while(currReturned.size() != 0 && !currReturned.peek().isGrouper()) {
- group.add(currReturned.pop());
- }
+ opStack.pop();
+ } else if(tk.type == GROUPSEP) {
+ IList<Token> group = new FunctionalList<>();
- while(opStack.size() != 0 && !opStack.peek().isGrouper()) {
- group.add(opStack.pop());
- }
+ while(currReturned.size() != 0 && !currReturned.peek().isGrouper()) {
+ group.add(currReturned.pop());
+ }
- if(currReturned.size() == 0) {
- Errors.inst.printError(EK_SHUNT_INVSEP);
- return false;
- }
+ while(opStack.size() != 0 && !opStack.peek().isGrouper()) {
+ group.add(opStack.pop());
+ }
- currReturned.addLast(new Token(TOKGROUP, group));
- } else {
- currReturned.addLast(tk);
+ if(currReturned.size() == 0) {
+ Errors.inst.printError(EK_SHUNT_INVSEP);
+ return false;
}
+
+ currReturned.addLast(new Token(TOKGROUP, group));
+ } else {
+ currReturned.addLast(tk);
+ }
+
+ return true;
+ }
+
+ public boolean shuntTokens(IList<Token> tks, IList<Token> returned) {
+ Deque<Token> opStack = new LinkedList<>();
+ Deque<Token> unaryOps = new LinkedList<>();
+
+ Deque<Token> currReturned = new LinkedList<>();
+
+ Deque<Token> feed = new LinkedList<>();
+
+ for(Token tk : tks.toIterable()) {
+ while(feed.size() != 0)
+ shuntToken(feed.poll(), opStack, unaryOps, currReturned, feed);
+ shuntToken(tk, opStack, unaryOps, currReturned, feed);
}
// Flush leftover operators
@@ -202,13 +213,27 @@ public class Shunter {
boolean exists = ops.containsKey(right);
+ if(rght.type == TAGOPR) exists = true;
+
// If it doesn't, the left is higher precedence.
if (!exists) {
return false;
}
- int rightPrecedence = ops.get(right);
- int leftPrecedence = ops.get(left);
+ int rightPrecedence;
+ int leftPrecedence;
+
+ if(rght.type == TAGOPR) {
+ rightPrecedence = (int)rght.intValue;
+ } else {
+ rightPrecedence = ops.get(right);
+ }
+
+ if(lft.type == TAGOPR) {
+ leftPrecedence = (int)lft.intValue;
+ } else {
+ leftPrecedence = ops.get(left);
+ }
return rightPrecedence >= leftPrecedence;
}