Working calculator.
This commit is contained in:
209
.clang-format
Normal file
209
.clang-format
Normal file
@@ -0,0 +1,209 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
QualifierAlignment: Leave
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
PackConstructorInitializers: BinPack
|
||||
BasedOnStyle: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: false
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
RemoveBracesLLVM: false
|
||||
RequiresClausePosition: OwnLine
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
|
||||
509
8By8/8By8.ino
509
8By8/8By8.ino
@@ -1,64 +1,68 @@
|
||||
#include "ListE.h"
|
||||
#include "TimerOne.h"
|
||||
#include <string.h>
|
||||
|
||||
#define TIME_PER_LAYER_IN_US 800
|
||||
#define BUS_START_PIN 22
|
||||
#define CLOCK_START_PIN 30
|
||||
#define SW_START_PIN 38
|
||||
|
||||
#define DEBUG false
|
||||
|
||||
class Cube {
|
||||
private:
|
||||
static int layer_count;
|
||||
static int brightness_count;
|
||||
static int layer_count;
|
||||
static int brightness_count;
|
||||
|
||||
public:
|
||||
// Every int represents a row of 8 LED status.
|
||||
static int LED_status[8][8];
|
||||
// Every int represents a row of 8 LED status.
|
||||
static int LED_status[8][8];
|
||||
|
||||
static void display() {
|
||||
// Serial.println("Here");
|
||||
if (brightness_count >= 2) {
|
||||
digitalWrite(SW_START_PIN + layer_count, LOW);
|
||||
layer_count = (layer_count + 1) % 8;
|
||||
static void display() {
|
||||
// Serial.println("Here");
|
||||
if (brightness_count >= 2) {
|
||||
digitalWrite(SW_START_PIN + layer_count, LOW);
|
||||
layer_count = (layer_count + 1) % 8;
|
||||
}
|
||||
|
||||
brightness_count = (brightness_count + 1) % 3;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
// In LED_status:
|
||||
// 0 = off
|
||||
// 4 = brightest
|
||||
digitalWrite(BUS_START_PIN + j,
|
||||
((LED_status[layer_count][i] >> (j * 2)) & 3) >=
|
||||
(3 - brightness_count));
|
||||
}
|
||||
digitalWrite(CLOCK_START_PIN + i, HIGH);
|
||||
digitalWrite(CLOCK_START_PIN + i, LOW);
|
||||
}
|
||||
|
||||
digitalWrite(SW_START_PIN + layer_count, HIGH);
|
||||
}
|
||||
|
||||
brightness_count = (brightness_count + 1) % 3;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
// In LED_status:
|
||||
// 0 = off
|
||||
// 4 = brightest
|
||||
digitalWrite(BUS_START_PIN + j,
|
||||
((LED_status[layer_count][i] >> (j * 2)) & 3) >=
|
||||
(3 - brightness_count));
|
||||
}
|
||||
digitalWrite(CLOCK_START_PIN + i, HIGH);
|
||||
digitalWrite(CLOCK_START_PIN + i, LOW);
|
||||
static void set_status(int x, int y, int z, int brightness) {
|
||||
if (x >= 8 || x < 0 || y >= 8 || y < 0 || z >= 8 || z < 0) {
|
||||
return;
|
||||
}
|
||||
brightness %= 4;
|
||||
LED_status[z][x] =
|
||||
(LED_status[z][x] & (~(3 << (y * 2)))) | (brightness << (y * 2));
|
||||
}
|
||||
|
||||
digitalWrite(SW_START_PIN + layer_count, HIGH);
|
||||
}
|
||||
|
||||
static void set_status(int x, int y, int z, int brightness) {
|
||||
if (x >= 8 || x < 0 || y >= 8 || y < 0 || z >= 8 || z < 0) {
|
||||
return;
|
||||
static int get_status(int x, int y, int z) {
|
||||
return LED_status[z][x] >> (y * 2) & 3;
|
||||
}
|
||||
brightness %= 4;
|
||||
LED_status[z][x] =
|
||||
(LED_status[z][x] & (~(3 << (y * 2)))) | (brightness << (y * 2));
|
||||
}
|
||||
|
||||
static int get_status(int x, int y, int z) {
|
||||
return LED_status[z][x] >> (y * 2) & 3;
|
||||
}
|
||||
|
||||
static void clear() {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
LED_status[i][j] = 0;
|
||||
}
|
||||
static void clear() {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
LED_status[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int Cube::layer_count = 0;
|
||||
@@ -66,25 +70,420 @@ int Cube::brightness_count = 0;
|
||||
int Cube::LED_status[8][8] = {0};
|
||||
int bright = 3;
|
||||
|
||||
void setup() {
|
||||
for (int i = 22; i < 46; i++) {
|
||||
pinMode(i, OUTPUT);
|
||||
}
|
||||
enum Operators {
|
||||
plus,
|
||||
minus,
|
||||
multiply,
|
||||
divide,
|
||||
power,
|
||||
left_parenthesis,
|
||||
right_parenthesis,
|
||||
};
|
||||
|
||||
Timer1.initialize();
|
||||
Timer1.setPeriod(TIME_PER_LAYER_IN_US);
|
||||
Timer1.attachInterrupt(Cube::display);
|
||||
enum CompareResult {
|
||||
less,
|
||||
equal,
|
||||
greater,
|
||||
};
|
||||
|
||||
Serial.begin(115200);
|
||||
class Symbol {
|
||||
private:
|
||||
bool is_symbol;
|
||||
String name;
|
||||
double value;
|
||||
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
Cube::set_status(x, y, sqrt((x - 3) * (x - 3) + (y - 3) * (y - 3)), 3);
|
||||
public:
|
||||
static double *x_value_ptr, *y_value_ptr;
|
||||
Symbol(String symbol_name) {
|
||||
this->is_symbol = true;
|
||||
this->name = symbol_name;
|
||||
}
|
||||
Symbol(double new_value) {
|
||||
this->is_symbol = false;
|
||||
this->value = new_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double get_value() const {
|
||||
if (this->is_symbol) {
|
||||
if (this->name == "x") {
|
||||
return *x_value_ptr;
|
||||
}
|
||||
else if (this->name == "y") {
|
||||
return *y_value_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return this->value;
|
||||
}
|
||||
};
|
||||
|
||||
class Operator {
|
||||
private:
|
||||
Operators name;
|
||||
|
||||
public:
|
||||
Operator(const char op) {
|
||||
if ('+' == op) {
|
||||
this->name = plus;
|
||||
}
|
||||
else if ('-' == op) {
|
||||
this->name = minus;
|
||||
}
|
||||
else if ('*' == op) {
|
||||
this->name = multiply;
|
||||
}
|
||||
else if ('/' == op) {
|
||||
this->name = divide;
|
||||
}
|
||||
else if ('^' == op) {
|
||||
this->name = power;
|
||||
}
|
||||
else if ('(' == op) {
|
||||
this->name = left_parenthesis;
|
||||
}
|
||||
else if (')' == op) {
|
||||
this->name = right_parenthesis;
|
||||
}
|
||||
}
|
||||
|
||||
CompareResult compare(const Operator &other_operator) {
|
||||
int self_priority, other_priority;
|
||||
if (this->name == plus || this->name == minus) {
|
||||
self_priority = 2;
|
||||
}
|
||||
else if (this->name == multiply || this->name == divide) {
|
||||
self_priority = 4;
|
||||
}
|
||||
else if (this->name == power) {
|
||||
self_priority = 6;
|
||||
}
|
||||
else if (this->name == left_parenthesis) {
|
||||
self_priority = 8;
|
||||
}
|
||||
else if (this->name == right_parenthesis) {
|
||||
self_priority = 1;
|
||||
}
|
||||
|
||||
if (other_operator.name == plus || other_operator.name == minus) {
|
||||
other_priority = 3;
|
||||
}
|
||||
else if (other_operator.name == multiply ||
|
||||
other_operator.name == divide) {
|
||||
other_priority = 5;
|
||||
}
|
||||
else if (other_operator.name == power) {
|
||||
other_priority = 7;
|
||||
}
|
||||
else if (other_operator.name == left_parenthesis) {
|
||||
other_priority = 1;
|
||||
}
|
||||
else if (other_operator.name == right_parenthesis) {
|
||||
other_priority = 9;
|
||||
}
|
||||
|
||||
if (self_priority < other_priority) {
|
||||
return less;
|
||||
}
|
||||
else if (self_priority == other_priority) {
|
||||
return equal;
|
||||
}
|
||||
else {
|
||||
return greater;
|
||||
}
|
||||
}
|
||||
|
||||
Symbol calc(const Symbol first_pop, const Symbol second_pop) {
|
||||
if (this->name == plus) {
|
||||
return Symbol(first_pop.get_value() + second_pop.get_value());
|
||||
}
|
||||
else if (this->name == minus) {
|
||||
return Symbol(second_pop.get_value() - first_pop.get_value());
|
||||
}
|
||||
else if (this->name == multiply) {
|
||||
return Symbol(first_pop.get_value() * second_pop.get_value());
|
||||
}
|
||||
else if (this->name == divide) {
|
||||
if (abs(first_pop.get_value()) <= 1e-5) {
|
||||
return Symbol(atof("inf"));
|
||||
}
|
||||
return Symbol(second_pop.get_value() / first_pop.get_value());
|
||||
}
|
||||
else if (this->name == power) {
|
||||
return Symbol(pow(second_pop.get_value(), first_pop.get_value()));
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
bool operator==(Operators op) {
|
||||
return this->name == op;
|
||||
}
|
||||
|
||||
char display() {
|
||||
switch (this->name) {
|
||||
case plus:
|
||||
return '+';
|
||||
case minus:
|
||||
return '-';
|
||||
case multiply:
|
||||
return '*';
|
||||
case divide:
|
||||
return '/';
|
||||
case power:
|
||||
return '^';
|
||||
case left_parenthesis:
|
||||
return '(';
|
||||
case right_parenthesis:
|
||||
return ')';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Calculator {
|
||||
private:
|
||||
String expression;
|
||||
List<Symbol> number_stack;
|
||||
List<Operator> operator_stack;
|
||||
int left_parenthesis_count;
|
||||
void calculate() {
|
||||
Operator operation = this->operator_stack.pop();
|
||||
// this->operator_stack.pop();
|
||||
Symbol number1 = this->number_stack.pop();
|
||||
// this->number_stack.pop();
|
||||
Symbol number2 = this->number_stack.pop();
|
||||
// this->number_stack.pop();
|
||||
|
||||
this->number_stack.append(operation.calc(number1, number2));
|
||||
}
|
||||
|
||||
public:
|
||||
Calculator(const String expression) {
|
||||
this->expression = expression + ')';
|
||||
}
|
||||
|
||||
double evaluate() {
|
||||
this->number_stack.clear();
|
||||
|
||||
this->operator_stack.clear();
|
||||
|
||||
this->operator_stack.append(Operator('('));
|
||||
this->left_parenthesis_count = 1;
|
||||
|
||||
char operator_chars[] = "+-*/^()";
|
||||
int operator_pos = -1;
|
||||
while (true) {
|
||||
if (DEBUG) {
|
||||
Serial.println("A");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
Serial.println("Number stack: ");
|
||||
for (int i = 0; i < this->number_stack.length(); i++) {
|
||||
Serial.println(this->number_stack[i].get_value());
|
||||
}
|
||||
Serial.println("Operator stack: ");
|
||||
for (int i = 0; i < this->operator_stack.length(); i++) {
|
||||
Serial.println(this->operator_stack[i].display());
|
||||
}
|
||||
}
|
||||
|
||||
bool found_next_operator = false;
|
||||
int first_char_of_num = operator_pos + 1;
|
||||
// operator_pos =
|
||||
// this->expression.indexOf(operator_chars, operator_pos + 1);
|
||||
|
||||
operator_pos = this->expression.length();
|
||||
|
||||
for (int i = 0; i < sizeof(operator_chars); i++) {
|
||||
int current_operator_pos = this->expression.indexOf(
|
||||
operator_chars[i], first_char_of_num);
|
||||
if (current_operator_pos < operator_pos &&
|
||||
current_operator_pos >= 0) {
|
||||
found_next_operator = true;
|
||||
operator_pos = current_operator_pos;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_next_operator) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the operator position
|
||||
if (DEBUG) {
|
||||
Serial.println("B");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
Serial.println("Number stack: ");
|
||||
for (int i = 0; i < this->number_stack.length(); i++) {
|
||||
Serial.println(this->number_stack[i].get_value());
|
||||
}
|
||||
Serial.println("Operator stack: ");
|
||||
for (int i = 0; i < this->operator_stack.length(); i++) {
|
||||
Serial.println(this->operator_stack[i].display());
|
||||
}
|
||||
}
|
||||
|
||||
if (operator_pos != first_char_of_num) {
|
||||
String number =
|
||||
this->expression.substring(first_char_of_num, operator_pos);
|
||||
if (number == "x" || number == "y") {
|
||||
this->number_stack.append(Symbol(number));
|
||||
}
|
||||
else {
|
||||
this->number_stack.append(Symbol(atof(number.c_str())));
|
||||
}
|
||||
}
|
||||
else if (this->expression[operator_pos] == '-' &&
|
||||
this->number_stack.length() ==
|
||||
this->operator_stack.length() -
|
||||
this->left_parenthesis_count) {
|
||||
this->number_stack.append(0.0);
|
||||
}
|
||||
|
||||
// Understand the number and push to stack
|
||||
if (DEBUG) {
|
||||
Serial.println("C");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
Serial.println("Number stack: ");
|
||||
for (int i = 0; i < this->number_stack.length(); i++) {
|
||||
Serial.println(this->number_stack[i].get_value());
|
||||
}
|
||||
Serial.println("Operator stack: ");
|
||||
for (int i = 0; i < this->operator_stack.length(); i++) {
|
||||
Serial.println(this->operator_stack[i].display());
|
||||
}
|
||||
}
|
||||
|
||||
Operator current_operator(this->expression[operator_pos]);
|
||||
if (current_operator == left_parenthesis) {
|
||||
this->left_parenthesis_count += 1;
|
||||
}
|
||||
|
||||
// Understand the operator
|
||||
if (DEBUG) {
|
||||
Serial.println("D");
|
||||
Serial.print("Read operator: ");
|
||||
Serial.println(current_operator.display());
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
Serial.println("Number stack: ");
|
||||
for (int i = 0; i < this->number_stack.length(); i++) {
|
||||
Serial.println(this->number_stack[i].get_value());
|
||||
}
|
||||
Serial.println("Operator stack: ");
|
||||
for (int i = 0; i < this->operator_stack.length(); i++) {
|
||||
Serial.println(this->operator_stack[i].display());
|
||||
}
|
||||
}
|
||||
|
||||
switch (current_operator.compare(this->operator_stack.peek())) {
|
||||
case greater:
|
||||
// Serial.println("Choose greater");
|
||||
this->operator_stack.append(current_operator);
|
||||
break;
|
||||
case equal:
|
||||
// Serial.println("Choose equal");
|
||||
this->operator_stack.pop();
|
||||
this->left_parenthesis_count -= 1;
|
||||
break;
|
||||
case less:
|
||||
// Serial.println("Choose less");
|
||||
if (this->number_stack.length() < 2) {
|
||||
// Error
|
||||
return atof("nan");
|
||||
}
|
||||
// Serial.println("Into Calc");
|
||||
|
||||
this->calculate();
|
||||
|
||||
// Serial.println("Out Calc");
|
||||
// We only dealt with previous operators. Need to go through
|
||||
// this operator again.
|
||||
operator_pos--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Serial.println("E");
|
||||
Serial.print("Operator pos: ");
|
||||
Serial.println(operator_pos);
|
||||
Serial.println("Number stack: ");
|
||||
for (int i = 0; i < this->number_stack.length(); i++) {
|
||||
Serial.println(this->number_stack[i].get_value());
|
||||
}
|
||||
Serial.println("Operator stack: ");
|
||||
for (int i = 0; i < this->operator_stack.length(); i++) {
|
||||
Serial.println(this->operator_stack[i].display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->left_parenthesis_count != 0) {
|
||||
return 0.0;
|
||||
}
|
||||
return this->number_stack.peek().get_value();
|
||||
}
|
||||
};
|
||||
|
||||
double *Symbol::x_value_ptr, *Symbol::y_value_ptr;
|
||||
|
||||
double x, y;
|
||||
|
||||
void setup() {
|
||||
for (int i = 22; i < 46; i++) {
|
||||
pinMode(i, OUTPUT);
|
||||
}
|
||||
|
||||
Timer1.initialize();
|
||||
Timer1.setPeriod(TIME_PER_LAYER_IN_US);
|
||||
Timer1.attachInterrupt(Cube::display);
|
||||
|
||||
Serial.begin(9600);
|
||||
Symbol::x_value_ptr = &x;
|
||||
Symbol::y_value_ptr = &y;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
String input = "";
|
||||
String allowed_chars = "0123456789+-*/^()xy";
|
||||
while (true) {
|
||||
if (Serial.available()) {
|
||||
byte input_char = Serial.read();
|
||||
// Serial.print("Pos: ");
|
||||
// Serial.println(allowed_chars.indexOf(input_char));
|
||||
if (allowed_chars.indexOf(input_char) != -1) {
|
||||
input.concat((char)input_char);
|
||||
// Serial.print("String: ");
|
||||
// Serial.println(input);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input_char == 0x3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Serial.print("Read: ");
|
||||
Serial.println(input);
|
||||
Calculator calculator(input);
|
||||
|
||||
Cube::clear();
|
||||
for (x = 0; x < 8; x++) {
|
||||
for (y = 0; y < 8; y++) {
|
||||
double result = calculator.evaluate();
|
||||
int z;
|
||||
if (!(isinf(result) || isnan(result))) {
|
||||
z = round(result);
|
||||
Cube::set_status(x, y, z, 3);
|
||||
}
|
||||
Serial.print(x);
|
||||
Serial.print(" ");
|
||||
Serial.print(y);
|
||||
Serial.print(" ");
|
||||
Serial.println(z);
|
||||
}
|
||||
}
|
||||
// int z = round(calculator.evaluate());
|
||||
// Serial.println(z);
|
||||
Serial.print("Here");
|
||||
}
|
||||
148
8By8/ListE.h
Normal file
148
8By8/ListE.h
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "Node.h"
|
||||
|
||||
template <class E> class List {
|
||||
private:
|
||||
Node<E> *head;
|
||||
int _length;
|
||||
int getIndexInRange(int index) const;
|
||||
|
||||
public:
|
||||
List();
|
||||
List(const E &newItem);
|
||||
List(const E *newItemList, const int itemCount);
|
||||
List(const List<E> &otherList);
|
||||
~List();
|
||||
// Append _newItem at last. Returns the List itself.
|
||||
List<E> &append(const E &_newItem);
|
||||
// Throws IndexError if index is not in the range of [-_length, _length -
|
||||
// 1]. Returns the List itself.
|
||||
E pop();
|
||||
// Clear all nodes.
|
||||
List<E> &clear();
|
||||
const E &peek() const;
|
||||
List<E> &operator=(const List<E> &otherList);
|
||||
E &operator[](const int index);
|
||||
const E &operator[](const int index) const;
|
||||
|
||||
int length() const;
|
||||
|
||||
bool empty() const;
|
||||
};
|
||||
|
||||
template <class E> int List<E>::getIndexInRange(int index) const {
|
||||
if (index < 0) {
|
||||
index += this->_length;
|
||||
}
|
||||
if (index < 0 || index >= _length) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
template <class E> List<E>::List() : head(NULL), _length(0){};
|
||||
|
||||
template <class E>
|
||||
List<E>::List(const E &newItem) : head(new Node<E>(newItem)), _length(1){};
|
||||
|
||||
template <class E> List<E>::List(const E *newItemList, const int itemCount) {
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
this->append(newItemList[i]);
|
||||
}
|
||||
};
|
||||
|
||||
template <class E> List<E>::List(const List<E> &otherList) {
|
||||
if (otherList.length() > 0) {
|
||||
this->head = new Node<E>(otherList[0]);
|
||||
this->_length = 1;
|
||||
Node<E> *nextPtr = otherList.head->getNextPtr();
|
||||
while (nextPtr != NULL) {
|
||||
this->append((*nextPtr).getContent());
|
||||
nextPtr = (*nextPtr).getNextPtr();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->head = NULL;
|
||||
this->_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <class E> List<E>::~List() {
|
||||
if (this->head != NULL) {
|
||||
this->head->destruct();
|
||||
}
|
||||
head = NULL;
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::append(const E &_newItem) {
|
||||
if (this->head == NULL) {
|
||||
this->head = new Node<E>(_newItem);
|
||||
}
|
||||
else {
|
||||
this->head->getTail().setNext(new Node<E>(_newItem));
|
||||
}
|
||||
this->_length++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> E List<E>::pop() {
|
||||
int index = this->_length - 1;
|
||||
|
||||
Node<E> removed = this->head->getByIndex(index);
|
||||
|
||||
this->_length--;
|
||||
if (index == 0) {
|
||||
Node<E> *newHead = this->head->getNextPtr();
|
||||
delete this->head;
|
||||
this->head = newHead;
|
||||
}
|
||||
else {
|
||||
Node<E> &prev = this->head->getByIndex(index - 1);
|
||||
delete prev.getNextPtr();
|
||||
prev.setNext(removed.getNextPtr());
|
||||
}
|
||||
return removed.getContent();
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::clear() {
|
||||
if (this->_length == 0) {
|
||||
return *this;
|
||||
}
|
||||
this->head->destruct();
|
||||
this->head = NULL;
|
||||
this->_length = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> const E&List<E>::peek() const {
|
||||
return this->head->getByIndex(this->_length - 1).getContent();
|
||||
}
|
||||
|
||||
template <class E> List<E> &List<E>::operator=(const List<E> &otherList) {
|
||||
this->clear();
|
||||
if (otherList.length() > 0) {
|
||||
this->head = new Node<E>(otherList[0]);
|
||||
this->_length = 1;
|
||||
Node<E> *nextPtr = otherList.head->getNextPtr();
|
||||
while (nextPtr != NULL) {
|
||||
this->append((*nextPtr).getContent());
|
||||
nextPtr = (*nextPtr).getNextPtr();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class E> E &List<E>::operator[](const int index) {
|
||||
return this->head->getByIndex(index).getContent();
|
||||
}
|
||||
|
||||
template <class E> const E &List<E>::operator[](const int index) const {
|
||||
return this->head->getByIndex(index).getContent();
|
||||
}
|
||||
|
||||
template <class E> int List<E>::length() const {
|
||||
return this->_length;
|
||||
}
|
||||
|
||||
template <class E> bool List<E>::empty() const {
|
||||
return this->_length == 0;
|
||||
}
|
||||
105
8By8/Node.h
Normal file
105
8By8/Node.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
template <class E> class Node {
|
||||
private:
|
||||
E content;
|
||||
Node *nextNode;
|
||||
|
||||
public:
|
||||
Node();
|
||||
Node(E _content, Node<E> *_nextNode = NULL);
|
||||
~Node();
|
||||
// Returns a reference to the content.
|
||||
E &getContent();
|
||||
// Returns a reference to the next Node. May return NULL if this Node is the
|
||||
// last one.
|
||||
Node<E> *getNextPtr();
|
||||
// Set the next Node _nextNode. Returns original pointer.
|
||||
Node<E> *setNext(Node<E> *_nextNode);
|
||||
// Returns a reference to the Tail.
|
||||
Node<E> &getTail();
|
||||
// Returns a reference to the Node of given index.
|
||||
Node<E> &getByIndex(const int index);
|
||||
// Compare the content with the argument.
|
||||
bool operator==(const E &other);
|
||||
// Destructs the Node itself and all the node behind it.
|
||||
void destruct();
|
||||
};
|
||||
|
||||
template <class E> class Iterator {
|
||||
private:
|
||||
Node<E> *current;
|
||||
|
||||
public:
|
||||
Iterator(Node<E> *pos);
|
||||
bool hasNext();
|
||||
// Return the same as hasNext();
|
||||
operator bool();
|
||||
E &next();
|
||||
};
|
||||
|
||||
template <class E> Node<E>::Node() : content(0), nextNode(NULL){};
|
||||
|
||||
template <class E>
|
||||
Node<E>::Node(E _content, Node *_nextNode)
|
||||
: content(_content), nextNode(_nextNode){};
|
||||
|
||||
template <class E> Node<E>::~Node(){};
|
||||
|
||||
template <class E> E &Node<E>::getContent() {
|
||||
return this->content;
|
||||
}
|
||||
|
||||
template <class E> Node<E> *Node<E>::getNextPtr() {
|
||||
return this->nextNode;
|
||||
}
|
||||
|
||||
template <class E> Node<E> *Node<E>::setNext(Node<E> *_nextNode) {
|
||||
Node<E> *temp = this->nextNode;
|
||||
this->nextNode = _nextNode;
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <class E> Node<E> &Node<E>::getTail() {
|
||||
if (this->nextNode == NULL) {
|
||||
return *this;
|
||||
}
|
||||
return this->nextNode->getTail();
|
||||
}
|
||||
|
||||
template <class E> Node<E> &Node<E>::getByIndex(const int index) {
|
||||
if (index == 0) {
|
||||
return *this;
|
||||
}
|
||||
return this->nextNode->getByIndex(index - 1);
|
||||
}
|
||||
|
||||
template <class E> bool Node<E>::operator==(const E &other) {
|
||||
return this->content == other;
|
||||
}
|
||||
|
||||
template <class E> void Node<E>::destruct() {
|
||||
if (this->nextNode != NULL) {
|
||||
this->nextNode->destruct();
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
template <class E> Iterator<E>::Iterator(Node<E> *start) : current(start){};
|
||||
|
||||
template <class E> bool Iterator<E>::hasNext() {
|
||||
return this->current != NULL;
|
||||
}
|
||||
|
||||
template <class E> Iterator<E>::operator bool() {
|
||||
return this->hasNext();
|
||||
}
|
||||
|
||||
template <class E> E &Iterator<E>::next() {
|
||||
if (!this->hasNext()) {
|
||||
throw(IndexError("Out of bound!"));
|
||||
}
|
||||
E &temp = this->current->getContent();
|
||||
this->current = this->current->getNextPtr();
|
||||
return temp;
|
||||
}
|
||||
Reference in New Issue
Block a user