From d964fbfb6fc004a9dd4ba0880080bb384a004515 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Wed, 2 Aug 2017 11:26:59 -0700 Subject: [PATCH] Implement the negation operator. --- .../org/nwapw/abacus/function/OperatorType.java | 2 +- .../abacus/parsing/ShuntingYardParser.java | 17 +++++++++++++---- .../org/nwapw/abacus/plugin/StandardPlugin.java | 17 ++++++++++++++++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/nwapw/abacus/function/OperatorType.java b/src/main/java/org/nwapw/abacus/function/OperatorType.java index d003c07..9bb3aac 100644 --- a/src/main/java/org/nwapw/abacus/function/OperatorType.java +++ b/src/main/java/org/nwapw/abacus/function/OperatorType.java @@ -4,5 +4,5 @@ package org.nwapw.abacus.function; * The type of an operator, describing how it should behave. */ public enum OperatorType { - BINARY_INFIX, UNARY_POSTFIX + BINARY_INFIX, UNARY_POSTFIX, UNARY_PREFIX } diff --git a/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java b/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java index 92e7d61..598c1e8 100644 --- a/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java +++ b/src/main/java/org/nwapw/abacus/parsing/ShuntingYardParser.java @@ -55,9 +55,12 @@ public class ShuntingYardParser implements Parser>, PluginListe public List> intoPostfix(List> from) { ArrayList> output = new ArrayList<>(); Stack> tokenStack = new Stack<>(); + TokenType previousType; + TokenType matchType = null; while (!from.isEmpty()) { Match match = from.remove(0); - TokenType matchType = match.getType(); + previousType = matchType; + matchType = match.getType(); if (matchType == TokenType.NUM) { output.add(match); } else if (matchType == TokenType.FUNCTION) { @@ -74,7 +77,13 @@ public class ShuntingYardParser implements Parser>, PluginListe continue; } - while (!tokenStack.empty()) { + if(tokenString.equals("-") && (previousType == null || previousType == TokenType.OP || + previousType == TokenType.OPEN_PARENTH)){ + from.add(0, new Match<>("`", TokenType.OP)); + continue; + } + + while (!tokenStack.empty() && type == OperatorType.BINARY_INFIX) { Match otherMatch = tokenStack.peek(); TokenType otherMatchType = otherMatch.getType(); if (!(otherMatchType == TokenType.OP || otherMatchType == TokenType.FUNCTION)) break; @@ -103,8 +112,8 @@ public class ShuntingYardParser implements Parser>, PluginListe } while (!tokenStack.empty()) { Match match = tokenStack.peek(); - TokenType matchType = match.getType(); - if (!(matchType == TokenType.OP || matchType == TokenType.FUNCTION)) return null; + TokenType newMatchType = match.getType(); + if (!(newMatchType == TokenType.OP || newMatchType == TokenType.FUNCTION)) return null; output.add(tokenStack.pop()); } return output; diff --git a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java index aeed916..2abf8b2 100755 --- a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java @@ -52,6 +52,20 @@ public class StandardPlugin extends Plugin { return params[0].subtract(params[1]); } }); + /** + * The negation operator, - + */ + public static final Operator OP_NEGATE = new Operator(OperatorAssociativity.LEFT, OperatorType.UNARY_PREFIX, 0, new Function() { + @Override + protected boolean matchesParams(NumberInterface[] params) { + return params.length == 1; + } + + @Override + protected NumberInterface applyInternal(NumberInterface[] params) { + return params[0].negate(); + } + }); /** * The multiplication operator, * */ @@ -317,6 +331,7 @@ public class StandardPlugin extends Plugin { registerOperator("+", OP_ADD); registerOperator("-", OP_SUBTRACT); + registerOperator("`", OP_NEGATE); registerOperator("*", OP_MULTIPLY); registerOperator("/", OP_DIVIDE); registerOperator("^", OP_CARET); @@ -335,7 +350,7 @@ public class StandardPlugin extends Plugin { public static NumberInterface factorial(Class numberClass, int n){ if(!factorialLists.containsKey(numberClass)){ - factorialLists.put(numberClass, new ArrayList()); + factorialLists.put(numberClass, new ArrayList<>()); factorialLists.get(numberClass).add(NaiveNumber.ONE.promoteTo(numberClass)); factorialLists.get(numberClass).add(NaiveNumber.ONE.promoteTo(numberClass)); }