From 9e257321ab28a09a46469ec744820bf6d3b75d83 Mon Sep 17 00:00:00 2001
From: Imbus <>
Date: Sat, 11 May 2024 13:02:50 +0200
Subject: [PATCH] Original sources, as-is
---
app/src/main/java/expr/Add.java | 18 +++
app/src/main/java/expr/BinaryExpr.java | 37 +++++
app/src/main/java/expr/Div.java | 21 +++
app/src/main/java/expr/Environment.java | 6 +
app/src/main/java/expr/Expr.java | 38 +++++
app/src/main/java/expr/ExprParser.java | 136 ++++++++++++++++++
app/src/main/java/expr/Mul.java | 18 +++
app/src/main/java/expr/Num.java | 21 +++
app/src/main/java/expr/Sub.java | 18 +++
app/src/main/java/expr/TestExpr.java | 30 ++++
app/src/main/java/expr/Variable.java | 18 +++
app/src/main/java/gui/BorderPanel.java | 13 ++
app/src/main/java/gui/ColoredLabel.java | 22 +++
app/src/main/java/gui/CurrentLabel.java | 10 ++
app/src/main/java/gui/Editor.java | 11 ++
app/src/main/java/gui/GridPanel.java | 13 ++
app/src/main/java/gui/RowLabels.java | 15 ++
app/src/main/java/gui/SheetPanel.java | 12 ++
app/src/main/java/gui/SlotLabel.java | 10 ++
app/src/main/java/gui/SlotLabels.java | 28 ++++
app/src/main/java/gui/StatusLabel.java | 16 +++
app/src/main/java/gui/StatusPanel.java | 12 ++
app/src/main/java/gui/XL.java | 49 +++++++
app/src/main/java/gui/XLCounter.java | 14 ++
app/src/main/java/gui/XLList.java | 40 ++++++
.../main/java/gui/menu/ClearAllMenuItem.java | 17 +++
app/src/main/java/gui/menu/ClearMenuItem.java | 17 +++
app/src/main/java/gui/menu/CloseMenuItem.java | 30 ++++
app/src/main/java/gui/menu/LoadMenuItem.java | 21 +++
app/src/main/java/gui/menu/NewMenuItem.java | 21 +++
app/src/main/java/gui/menu/OpenMenuItem.java | 45 ++++++
app/src/main/java/gui/menu/SaveMenuItem.java | 21 +++
app/src/main/java/gui/menu/WindowMenu.java | 26 ++++
.../main/java/gui/menu/WindowMenuItem.java | 21 +++
app/src/main/java/gui/menu/XLMenuBar.java | 24 ++++
app/src/main/java/util/Adjustment.java | 134 +++++++++++++++++
app/src/main/java/util/NumberAdjustment.java | 123 ++++++++++++++++
app/src/main/java/util/XLBufferedReader.java | 27 ++++
app/src/main/java/util/XLException.java | 8 ++
app/src/main/java/util/XLPrintStream.java | 25 ++++
40 files changed, 1186 insertions(+)
create mode 100644 app/src/main/java/expr/Add.java
create mode 100644 app/src/main/java/expr/BinaryExpr.java
create mode 100644 app/src/main/java/expr/Div.java
create mode 100644 app/src/main/java/expr/Environment.java
create mode 100644 app/src/main/java/expr/Expr.java
create mode 100644 app/src/main/java/expr/ExprParser.java
create mode 100644 app/src/main/java/expr/Mul.java
create mode 100644 app/src/main/java/expr/Num.java
create mode 100644 app/src/main/java/expr/Sub.java
create mode 100644 app/src/main/java/expr/TestExpr.java
create mode 100644 app/src/main/java/expr/Variable.java
create mode 100644 app/src/main/java/gui/BorderPanel.java
create mode 100644 app/src/main/java/gui/ColoredLabel.java
create mode 100644 app/src/main/java/gui/CurrentLabel.java
create mode 100644 app/src/main/java/gui/Editor.java
create mode 100644 app/src/main/java/gui/GridPanel.java
create mode 100644 app/src/main/java/gui/RowLabels.java
create mode 100644 app/src/main/java/gui/SheetPanel.java
create mode 100644 app/src/main/java/gui/SlotLabel.java
create mode 100644 app/src/main/java/gui/SlotLabels.java
create mode 100644 app/src/main/java/gui/StatusLabel.java
create mode 100644 app/src/main/java/gui/StatusPanel.java
create mode 100644 app/src/main/java/gui/XL.java
create mode 100644 app/src/main/java/gui/XLCounter.java
create mode 100644 app/src/main/java/gui/XLList.java
create mode 100644 app/src/main/java/gui/menu/ClearAllMenuItem.java
create mode 100644 app/src/main/java/gui/menu/ClearMenuItem.java
create mode 100644 app/src/main/java/gui/menu/CloseMenuItem.java
create mode 100644 app/src/main/java/gui/menu/LoadMenuItem.java
create mode 100644 app/src/main/java/gui/menu/NewMenuItem.java
create mode 100644 app/src/main/java/gui/menu/OpenMenuItem.java
create mode 100644 app/src/main/java/gui/menu/SaveMenuItem.java
create mode 100644 app/src/main/java/gui/menu/WindowMenu.java
create mode 100644 app/src/main/java/gui/menu/WindowMenuItem.java
create mode 100644 app/src/main/java/gui/menu/XLMenuBar.java
create mode 100644 app/src/main/java/util/Adjustment.java
create mode 100644 app/src/main/java/util/NumberAdjustment.java
create mode 100644 app/src/main/java/util/XLBufferedReader.java
create mode 100644 app/src/main/java/util/XLException.java
create mode 100644 app/src/main/java/util/XLPrintStream.java
diff --git a/app/src/main/java/expr/Add.java b/app/src/main/java/expr/Add.java
new file mode 100644
index 0000000..8a68163
--- /dev/null
+++ b/app/src/main/java/expr/Add.java
@@ -0,0 +1,18 @@
+package xl.expr;
+
+class Add extends BinaryExpr {
+
+ Add(Expr expr1, Expr expr2) {
+ super(expr1, expr2);
+ precedence1 = 0;
+ precedence2 = 0;
+ }
+
+ public double op(double op1, double op2) {
+ return op1 + op2;
+ }
+
+ protected String opString() {
+ return "+";
+ }
+}
diff --git a/app/src/main/java/expr/BinaryExpr.java b/app/src/main/java/expr/BinaryExpr.java
new file mode 100644
index 0000000..85c9989
--- /dev/null
+++ b/app/src/main/java/expr/BinaryExpr.java
@@ -0,0 +1,37 @@
+package xl.expr;
+
+abstract class BinaryExpr extends Expr {
+
+ private Expr expr1;
+ private Expr expr2;
+ protected int precedence1;
+ protected int precedence2;
+
+ protected BinaryExpr(Expr expr1, Expr expr2) {
+ this.expr1 = expr1;
+ this.expr2 = expr2;
+ }
+
+ protected abstract double op(double op1, double op2);
+
+ protected abstract String opString();
+
+ public String toString(int prec) {
+ StringBuilder builder = new StringBuilder();
+ boolean parentheses = prec > precedence1;
+ if (parentheses) {
+ builder.append('(');
+ }
+ builder.append(expr1.toString(precedence1));
+ builder.append(opString());
+ builder.append(expr2.toString(precedence2));
+ if (parentheses) {
+ builder.append(')');
+ }
+ return builder.toString();
+ }
+
+ public double value(Environment env) {
+ return op(expr1.value(env), expr2.value(env));
+ }
+}
diff --git a/app/src/main/java/expr/Div.java b/app/src/main/java/expr/Div.java
new file mode 100644
index 0000000..e2b9def
--- /dev/null
+++ b/app/src/main/java/expr/Div.java
@@ -0,0 +1,21 @@
+package xl.expr;
+
+import xl.util.XLException;
+
+class Div extends BinaryExpr {
+
+ Div(Expr expr1, Expr expr2) {
+ super(expr1, expr2);
+ precedence1 = 1;
+ precedence2 = 2;
+ }
+
+ public double op(double op1, double op2) {
+ if (op2 != 0) return op1 / op2;
+ else throw new XLException("division by zero");
+ }
+
+ protected String opString() {
+ return "/";
+ }
+}
diff --git a/app/src/main/java/expr/Environment.java b/app/src/main/java/expr/Environment.java
new file mode 100644
index 0000000..51a43b7
--- /dev/null
+++ b/app/src/main/java/expr/Environment.java
@@ -0,0 +1,6 @@
+package xl.expr;
+
+public interface Environment {
+
+ public double value(String name);
+}
diff --git a/app/src/main/java/expr/Expr.java b/app/src/main/java/expr/Expr.java
new file mode 100644
index 0000000..7715418
--- /dev/null
+++ b/app/src/main/java/expr/Expr.java
@@ -0,0 +1,38 @@
+package xl.expr;
+
+/**
+ * An Expr
object represents a real valued expression that may contain variables. The
+ * value of a variable is obtained from an Environment
object by specifying the name of
+ * the variable.
+ *
+ * @see Environment
+ * @author Lennart Andersson
+ */
+public abstract class Expr {
+
+ /**
+ * The toString
method returns a String
representation of this
+ * expression without unnecessary parentheses.
+ *
+ * @return the String
representation of this expression.
+ */
+ public String toString() {
+ return toString(0);
+ }
+
+ /*
+ * toString(prec) returns a string representation of this expression without
+ * unnecessary parentheses. The prec argument specifies the precedence level
+ * enclosing expression and is used to control the precedence of
+ * parentheses.
+ */
+ public abstract String toString(int prec);
+
+ /**
+ * The value
method returns the value of this expression.
+ *
+ * @param env is the Environment
containing the values of variables.
+ * @return the double
value of this expression.
+ */
+ public abstract double value(Environment env);
+}
diff --git a/app/src/main/java/expr/ExprParser.java b/app/src/main/java/expr/ExprParser.java
new file mode 100644
index 0000000..f69465c
--- /dev/null
+++ b/app/src/main/java/expr/ExprParser.java
@@ -0,0 +1,136 @@
+package xl.expr;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.regex.Pattern;
+import xl.util.XLException;
+
+/**
+ * An ExprParser
object is a parser provides a factory method for building Expr
+ *
objects from text representations of arithmetic expressions. The text containing the
+ * expression should adhere to the following grammar.
+ *
+ *
+ * + * + * + * expr ::= term {addop term} + * term ::= factor {mulop factor} + * factor ::= number | variable | "(" expr ")" + * addop ::= "+" | "-" + * mulop ::= "*" | "/" + * + * + * + *+ * + * where
number
is an unsigned number according to StreamTokenizer
and
+ * variable
is a string of letters and digits. The first character must be a letter.
+ *
+ * @see Expr
+ * @see StreamTokenizer
+ * @author Lennart Andersson
+ */
+public class ExprParser {
+
+ private int token;
+ private StreamTokenizer tokenizer;
+
+ /**
+ * The build
method returns an Expr
representation of the expression
+ * provided by reader
.
+ *
+ * @param reader a Reader
provided the string to be parsed.
+ * @return an Expr
representation of the string.
+ * @exception IOException if the reader
does not deliver data.
+ * @exception ExprParserException if the reader input violates the grammar.
+ */
+ public Expr build(Reader reader) throws IOException {
+ tokenizer = new StreamTokenizer(reader);
+ tokenizer.ordinaryChar('-');
+ tokenizer.ordinaryChar('/');
+ token = tokenizer.nextToken();
+ Expr e = expr();
+ if (token == StreamTokenizer.TT_EOF) return e;
+ else throw new XLException("trailing garbage");
+ }
+
+ /**
+ * The build
method returns an Expr
representation of the expression
+ * provided by the input
string.
+ *
+ * @param input the String
to be parsed.
+ * @return an Expr
representation of the string.
+ * @exception IOException if the input
does not deliver data.
+ * @exception XLException if the input violates the grammar.
+ */
+ public Expr build(String input) throws IOException {
+ return build(new StringReader(input));
+ }
+
+ private Expr expr() throws IOException {
+ Expr result, term;
+ result = term();
+ while (token == '+' || token == '-') {
+ int op = token;
+ token = tokenizer.nextToken();
+ term = term();
+ switch (op) {
+ case '+':
+ result = new Add(result, term);
+ break;
+ case '-':
+ result = new Sub(result, term);
+ break;
+ }
+ }
+ return result;
+ }
+
+ private Expr factor() throws IOException {
+ Expr e;
+ switch (token) {
+ case '(':
+ token = tokenizer.nextToken();
+ e = expr();
+ if (token != ')') throw new XLException("expecting \")\", found: " + token);
+ token = tokenizer.nextToken();
+ return e;
+ case StreamTokenizer.TT_NUMBER:
+ double x = tokenizer.nval;
+ token = tokenizer.nextToken();
+ return new Num(x);
+ case StreamTokenizer.TT_WORD:
+ String address = tokenizer.sval.toUpperCase();
+ if (!Pattern.matches("[A-Z][0-9]+", address))
+ throw new XLException("illegal address: " + address);
+ token = tokenizer.nextToken();
+ return new Variable(address);
+ case StreamTokenizer.TT_EOF:
+ throw new XLException("unexpected end of text");
+ default:
+ throw new XLException("unexpected " + (char) token);
+ }
+ }
+
+ private Expr term() throws IOException {
+ Expr result, factor;
+ result = factor();
+ while (token == '*' || token == '/') {
+ int op = token;
+ token = tokenizer.nextToken();
+ factor = factor();
+ switch (op) {
+ case '*':
+ result = new Mul(result, factor);
+ break;
+ case '/':
+ result = new Div(result, factor);
+ break;
+ }
+ }
+ return result;
+ }
+}
diff --git a/app/src/main/java/expr/Mul.java b/app/src/main/java/expr/Mul.java
new file mode 100644
index 0000000..2a5cffd
--- /dev/null
+++ b/app/src/main/java/expr/Mul.java
@@ -0,0 +1,18 @@
+package xl.expr;
+
+class Mul extends BinaryExpr {
+
+ Mul(Expr expr1, Expr expr2) {
+ super(expr1, expr2);
+ precedence1 = 1;
+ precedence2 = 1;
+ }
+
+ public double op(double op1, double op2) {
+ return op1 * op2;
+ }
+
+ protected String opString() {
+ return "*";
+ }
+}
diff --git a/app/src/main/java/expr/Num.java b/app/src/main/java/expr/Num.java
new file mode 100644
index 0000000..121b27f
--- /dev/null
+++ b/app/src/main/java/expr/Num.java
@@ -0,0 +1,21 @@
+package xl.expr;
+
+import xl.util.NumberAdjustment;
+
+class Num extends Expr {
+
+ private static NumberAdjustment adjustment = new NumberAdjustment(0, 2);
+ private double value;
+
+ Num(double value) {
+ this.value = value;
+ }
+
+ public String toString(int prec) {
+ return adjustment.right(value);
+ }
+
+ public double value(Environment env) {
+ return value;
+ }
+}
diff --git a/app/src/main/java/expr/Sub.java b/app/src/main/java/expr/Sub.java
new file mode 100644
index 0000000..7108153
--- /dev/null
+++ b/app/src/main/java/expr/Sub.java
@@ -0,0 +1,18 @@
+package xl.expr;
+
+class Sub extends BinaryExpr {
+
+ Sub(Expr expr1, Expr expr2) {
+ super(expr1, expr2);
+ precedence1 = 0;
+ precedence2 = 1;
+ }
+
+ public double op(double op1, double op2) {
+ return op1 - op2;
+ }
+
+ protected String opString() {
+ return "-";
+ }
+}
diff --git a/app/src/main/java/expr/TestExpr.java b/app/src/main/java/expr/TestExpr.java
new file mode 100644
index 0000000..e5b6b1f
--- /dev/null
+++ b/app/src/main/java/expr/TestExpr.java
@@ -0,0 +1,30 @@
+package xl.expr;
+
+import java.io.IOException;
+
+public class TestExpr {
+
+ public static void main(String[] args) {
+ ExprParser parser = new ExprParser();
+ try {
+ Expr expr = parser.build("1+2*3");
+ System.out.println(expr);
+ System.out.println(expr.value(null));
+ expr = parser.build("A3+A2*A1");
+ Environment env =
+ new Environment() {
+ public double value(String name) {
+ if (name.equals("A3")) return 1;
+ if (name.equals("A2")) return 2;
+ if (name.equals("A1")) return 3;
+ System.out.println(name + " is undefined");
+ return 0;
+ }
+ };
+ System.out.println(expr);
+ System.out.println(expr.value(env));
+ } catch (IOException e) {
+ System.err.println(e.getMessage());
+ }
+ }
+}
diff --git a/app/src/main/java/expr/Variable.java b/app/src/main/java/expr/Variable.java
new file mode 100644
index 0000000..b8d272f
--- /dev/null
+++ b/app/src/main/java/expr/Variable.java
@@ -0,0 +1,18 @@
+package xl.expr;
+
+class Variable extends Expr {
+
+ private String name;
+
+ Variable(String name) {
+ this.name = name;
+ }
+
+ public String toString(int prec) {
+ return name.toString();
+ }
+
+ public double value(Environment env) {
+ return env.value(name);
+ }
+}
diff --git a/app/src/main/java/gui/BorderPanel.java b/app/src/main/java/gui/BorderPanel.java
new file mode 100644
index 0000000..002580d
--- /dev/null
+++ b/app/src/main/java/gui/BorderPanel.java
@@ -0,0 +1,13 @@
+package xl.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import javax.swing.JPanel;
+
+public class BorderPanel extends JPanel {
+
+ protected BorderPanel() {
+ super(new BorderLayout(2, 2));
+ setBackground(Color.BLACK);
+ }
+}
diff --git a/app/src/main/java/gui/ColoredLabel.java b/app/src/main/java/gui/ColoredLabel.java
new file mode 100644
index 0000000..408a33f
--- /dev/null
+++ b/app/src/main/java/gui/ColoredLabel.java
@@ -0,0 +1,22 @@
+package xl.gui;
+
+import java.awt.Color;
+import javax.swing.JLabel;
+import javax.swing.SwingConstants;
+
+public class ColoredLabel extends JLabel {
+
+ public ColoredLabel(String text) {
+ this(text, Color.WHITE, SwingConstants.LEFT);
+ }
+
+ public ColoredLabel(String text, Color color) {
+ this(text, color, SwingConstants.LEFT);
+ }
+
+ public ColoredLabel(String text, Color color, int alignment) {
+ super(text, alignment);
+ setBackground(color);
+ setOpaque(true);
+ }
+}
diff --git a/app/src/main/java/gui/CurrentLabel.java b/app/src/main/java/gui/CurrentLabel.java
new file mode 100644
index 0000000..68a78e2
--- /dev/null
+++ b/app/src/main/java/gui/CurrentLabel.java
@@ -0,0 +1,10 @@
+package xl.gui;
+
+import java.awt.Color;
+
+public class CurrentLabel extends ColoredLabel {
+
+ public CurrentLabel() {
+ super("A1", Color.WHITE);
+ }
+}
diff --git a/app/src/main/java/gui/Editor.java b/app/src/main/java/gui/Editor.java
new file mode 100644
index 0000000..1004b4d
--- /dev/null
+++ b/app/src/main/java/gui/Editor.java
@@ -0,0 +1,11 @@
+package xl.gui;
+
+import java.awt.Color;
+import javax.swing.JTextField;
+
+public class Editor extends JTextField {
+
+ public Editor() {
+ setBackground(Color.WHITE);
+ }
+}
diff --git a/app/src/main/java/gui/GridPanel.java b/app/src/main/java/gui/GridPanel.java
new file mode 100644
index 0000000..a9ff152
--- /dev/null
+++ b/app/src/main/java/gui/GridPanel.java
@@ -0,0 +1,13 @@
+package xl.gui;
+
+import java.awt.Color;
+import java.awt.GridLayout;
+import javax.swing.JPanel;
+
+public class GridPanel extends JPanel {
+
+ public GridPanel(int rows, int columns) {
+ super(new GridLayout(rows, columns, 2, 2));
+ setBackground(Color.BLACK);
+ }
+}
diff --git a/app/src/main/java/gui/RowLabels.java b/app/src/main/java/gui/RowLabels.java
new file mode 100644
index 0000000..a2b909f
--- /dev/null
+++ b/app/src/main/java/gui/RowLabels.java
@@ -0,0 +1,15 @@
+package xl.gui;
+
+import static java.awt.Color.LIGHT_GRAY;
+import static javax.swing.SwingConstants.RIGHT;
+
+class RowLabels extends GridPanel {
+
+ RowLabels(int rows) {
+ super(rows + 1, 1);
+ add(new ColoredLabel("", LIGHT_GRAY, RIGHT));
+ for (int i = 1; i <= rows; i++) {
+ add(new ColoredLabel(String.valueOf(i), LIGHT_GRAY, RIGHT));
+ }
+ }
+}
diff --git a/app/src/main/java/gui/SheetPanel.java b/app/src/main/java/gui/SheetPanel.java
new file mode 100644
index 0000000..74ca92d
--- /dev/null
+++ b/app/src/main/java/gui/SheetPanel.java
@@ -0,0 +1,12 @@
+package xl.gui;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.WEST;
+
+public class SheetPanel extends BorderPanel {
+
+ public SheetPanel(int rows, int columns) {
+ add(WEST, new RowLabels(rows));
+ add(CENTER, new SlotLabels(rows, columns));
+ }
+}
diff --git a/app/src/main/java/gui/SlotLabel.java b/app/src/main/java/gui/SlotLabel.java
new file mode 100644
index 0000000..5807b19
--- /dev/null
+++ b/app/src/main/java/gui/SlotLabel.java
@@ -0,0 +1,10 @@
+package xl.gui;
+
+import java.awt.Color;
+
+public class SlotLabel extends ColoredLabel {
+
+ public SlotLabel() {
+ super(" ", Color.WHITE, RIGHT);
+ }
+}
diff --git a/app/src/main/java/gui/SlotLabels.java b/app/src/main/java/gui/SlotLabels.java
new file mode 100644
index 0000000..e1497d8
--- /dev/null
+++ b/app/src/main/java/gui/SlotLabels.java
@@ -0,0 +1,28 @@
+package xl.gui;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.SwingConstants;
+
+public class SlotLabels extends GridPanel {
+
+ private List