diff --git a/src/a.out b/src/a.out deleted file mode 100644 index 23904fb..0000000 Binary files a/src/a.out and /dev/null differ diff --git a/src/calc.cpp b/src/calc.cpp index c05e55a..2ae7f9e 100644 --- a/src/calc.cpp +++ b/src/calc.cpp @@ -24,8 +24,9 @@ int main() { //std::string input = "(((a / 4) + (c / 3))"; //std::string input = "88=mgh\n=\n=x\n=4321\nx=\nx = y =\n88 = mph"; //std::string input = "x = y = 0 + 1 + 2 * 3 - 4 / (5 + 6)\nb=13\n(7 - (b = (b + 5)))\n1 % 114514\n\n1=a\n1+1\n"; - std::string input = "(x = 10)\n(y = 57)\n(z = 16)\n((((x = 3) + (y = 5)) + w) + (z = 145))\n((x + y) + z)"; - //std::string input = "()+)"; + // std::string input = "1==false"; + // std::string input = "(1 == 2)"; + std::string input = "((6 + (4 / ((1 + 2) - 3))) + 8)\n(z = ((32 * awol) >= 5))\n(((88 + 7) < (4 * true)) & (5 >= 2))"; #endif @@ -40,7 +41,11 @@ int main() { expressions.push_back(s); } + + Scope* globalScope = new Scope(); + ParserB::ScopeStack.push(globalScope); int lineCount = 0; + lineCount = lineCount + 1 -1; for (std::string expression : expressions) { @@ -60,40 +65,53 @@ int main() { continue; } - ParserB::setupExpressionInfix(TokenVector); - // ParserB - Node root; - std::pair, std::string> errorResult = ParserB::MakeTreeInfix(TokenVector, 0, TokenVector.size() - 2, root); - + ParserB::setupExpression(TokenVector); + // std::unique_ptr root; + // std::pair, std::string> errorResult = ParserB::MakeExpressionTree(TokenVector, 0, TokenVector.size() - 2, root); + + std::vector> flows; + // std::cout << TokenVector.at(TokenVector.size()-2).content << std::endl; + TokenVector.pop_back(); + TokenVector.push_back(Token(TokenType::SEMICOLON, ";", 0, 0 )); + TokenVector.push_back(Token(TokenType::END, "", 0, 0 )); + + std::pair, std::string> errorResult = ParserB::HandleTokenVector(TokenVector, 0, TokenVector.size()-2, flows); + + if (errorResult.first.first != -1) { std::cout << "Unexpected token at line " << errorResult.first.first << " column " << errorResult.first.second << ": " << errorResult.second << std::endl; continue; } - ParserB::print(root); + ParserB::print_no_semicolon(flows[0].get()); + // ParserB::print(flows[0].get(), 0, false); std::cout << std::endl; - // Calculate - double result; - std::map originalVariableMap(ParserB::variableMap); - std::map originalVariableInitializedMap(ParserB::variableInitializedMap); - std::string errorMessage = ParserB::calculate(root, result); - - if (errorMessage == "114514") - { - std::cout << input << std::endl; - } + Result result; + Scope* originalScope = new Scope(*(ParserB::ScopeStack.top())); + std::string errorMessage = ParserB::calculate(flows[0].get(), result); + if (errorMessage.length() != 0) { + // Error std::cout << errorMessage << std::endl; - ParserB::variableMap.swap(originalVariableMap); - ParserB::variableInitializedMap.swap(originalVariableInitializedMap); - continue; + delete ParserB::ScopeStack.top(); + ParserB::ScopeStack.pop(); + ParserB::ScopeStack.push(originalScope); + } + else + { + // No Error + ParserB::printValue(result); + std::cout << std::endl; + delete originalScope; } - std::cout << result << std::endl; } + + ParserB::clean(); + delete ParserB::ScopeStack.top(); return 0; } \ No newline at end of file diff --git a/src/dumped/lex.cpp b/src/dumped/lex.cpp new file mode 100644 index 0000000..83afbfb --- /dev/null +++ b/src/dumped/lex.cpp @@ -0,0 +1,43 @@ +#include "lib/Lexer.h" + +int main() { + +#if DEBUG == 0 + std::string input = ""; + std::string line; + + while(!std::cin.eof()) { + char c; + std::cin.get(c); + line = std::string(1, c); + input += line; + } + input = input.substr(0, input.size()-1); +#endif +#if DEBUG == 1 + + //std::string input = "(* (+ 1 2) 3 (/ 4 5 (- 6 7)))\n(* (+ 1 2) 3 (/ 4 5 (- 6 7)))\n(* (+ 1 2) 3 (/ 4 5 (- 6 7)))"; + //std::string input = "(= a b 3)"; + //std::string input = "(- (= b (+ b 5)) 7)"; + //std::string input = "(* a b)"; + //std::string input = "(= foo_ b 3)\n( + b 0 )\n(- (= b (+ b 5)) 7)\n(* foo b)\n"; + std::string input = R"((x = 42) +(steps = 0) +while (x > 1) { + (steps = (steps + 1)) + if ((x % 2) == 0) { + (x = (x / 2)) + } + else { + (x = ((3 * x) + 1)) + } +} +print steps)"; + //std::string input = "(=(n) 9)"; +#endif + std::vector TokenVector; + std::pair errorPair = Token::GenTokenVector(input, TokenVector); + + Token::printLexer(TokenVector); + return 0; +} diff --git a/src/parse.cpp b/src/dumped/parse.cpp similarity index 100% rename from src/parse.cpp rename to src/dumped/parse.cpp diff --git a/src/format.cpp b/src/format.cpp index e69de29..d796c35 100644 --- a/src/format.cpp +++ b/src/format.cpp @@ -0,0 +1,81 @@ +#include "lib/ParserB.h" + +int main() { +#if DEBUG == 0 + std::string input = ""; + std::string line; + + while(!std::cin.eof()) { + char c; + std::cin.get(c); + line = std::string(1, c); + input += line; + } + input = input.substr(0, input.size()-1); +#endif +#if DEBUG == 1 + std::string input = R"( +(z = 42); +def foo(x, y) { + def square(value) { + return (value * value); + } + print square(((x + y) + z)); +} +(z = 108); +(f = foo); +(result = f(1, 2)); +if (result != null) { + print result; +} + +def p() { + print a; + return; +} +p(); +def p() { + return null; +} + )"; + +#endif + // std::cout << "===================" << std::endl; + // std::cout << input << std::endl; + // std::cout << "===================" << std::endl; + std::vector TokenVector; + std::pair errorPair = Token::GenTokenVector(input, TokenVector); + + if (errorPair.first != -1) + { + std::cout << "Syntax error on line " << errorPair.first << " column " << errorPair.second << "." << std::endl; + exit(1); + } + // Token::printLexer(TokenVector); + std::vector> flows; + std::pair, std::string> errorResult = ParserB::HandleTokenVector(TokenVector, 0, TokenVector.size()-2, flows); + if (errorResult.first.first != -1) + { + std::cout << "Unexpected token at line " << errorResult.first.first << " column " << errorResult.first.second << ": " << errorResult.second << std::endl; + exit(2); + } + + for (int i=0; i < (int)flows.size(); i++) + { + ParserB::print(flows[i].get()); + // if (flows[i].get()->value.type == TokenType::ARRAY) { + // ArrayNode* Array = dynamic_cast(flows[i].get()); + // if (Array->ArrayContent[2]->value.type == TokenType::NUMBER) { + // std::cout << "yes" << std::endl; + // } + // std::cout << Array->ArrayContent[2]->value << std::endl; + // } + // if (flows[i].get()->value.type == TokenType::VARIABLE) { + // std::cout << flows[i].get()->value.content << std::endl; + // } + + + std::cout << std::endl; + } + return 0; +} \ No newline at end of file diff --git a/src/lex.cpp b/src/lex.cpp index ad9bba2..5cff0b0 100644 --- a/src/lex.cpp +++ b/src/lex.cpp @@ -1,7 +1,6 @@ -#include "lib/Lexer.h" +#include "lib/Lexer.h" int main() { - #if DEBUG == 0 std::string input = ""; std::string line; @@ -18,14 +17,27 @@ int main() { // std::cout << "LOLOLOLOLOLOLOLOLO" << std::endl; #endif #if DEBUG == 1 - + //std::string input = "(* (+ 1 2) 3 (/ 4 5 (- 6 7)))\n(* (+ 1 2) 3 (/ 4 5 (- 6 7)))\n(* (+ 1 2) 3 (/ 4 5 (- 6 7)))"; //std::string input = "(= a b 3)"; //std::string input = "(- (= b (+ b 5)) 7)"; //std::string input = "(* a b)"; //std::string input = "(= foo_ b 3)\n( + b 0 )\n(- (= b (+ b 5)) 7)\n(* foo b)\n"; - std::string input = " !===!==>=<-=>=<<>>==^^!=|&<>"; + //std::string input = "a\n"; +// std::string input = R"((x = 42) +// (steps = 0) +// while (x > 1) { +// (steps = (steps + 1)) +// if ((x % 2) == 0) { +// (x = (x / 2)) +// } +// else { +// (x = ((3 * x) + 1)) +// } +// } +// print steps)"; //std::string input = "(=(n) 9)"; + std::string input = "[9]"; #endif std::vector TokenVector; @@ -33,13 +45,11 @@ int main() { int errorLine = errorPair.first; int errorIndex = errorPair.second; - if (errorLine != -1) { std::cout << "Syntax error on line " << errorLine << " column " << errorIndex << "." << std::endl; exit(1); } - Token::printLexer(TokenVector); return 0; -} +} \ No newline at end of file diff --git a/src/lib/ASTNode.h b/src/lib/ASTNode.h new file mode 100644 index 0000000..184d301 --- /dev/null +++ b/src/lib/ASTNode.h @@ -0,0 +1,123 @@ +#pragma once + + +#include + +#include "Lexer.h" + +class Node +{ +public: + Node() : value(Token(TokenType::NONE, "", -1, -1, -1)) , ArrayContent(){} + Node(Token token) : value(token), ArrayContent() {} + // Node(Node * copy) : value(copy->value), lookUp(copy->lookUp), lookUpStr(copy->lookUpStr), + // lookUpIndex(copy->lookUpIndex) { + // for (ele : copy->ArrayContent) { + // this->ArrayContent.push_back(ele); + // } + // } + virtual ~Node() = default; + + + Token value; + bool lookUp = false; + std::string lookUpStr = ""; + double lookUpIndex = -1; + std::vector> ArrayContent; + int EqualityIndex = -1; + bool subArray = false; + bool IsFunction = false; +}; + +// An operation expression node should always have 2 children +// A function call expression: Node1: function. Node2, 3...: parameters. +// A function call expression must have a variable token and children.size() != 0 + +class ExpressionNode : public Node +{ +public: + ExpressionNode() : Node(), children() {} + ExpressionNode(Token token) : Node(token), children() {} + virtual ~ExpressionNode() = default; + + bool ArrayLookUp = false; + bool LookUpForm = true; + double index = -1; + // bool WrongArgu = false; + // std::string lookUpStr = "" + std::vector> children; + std::vector> children2; +}; + +class ArrayNode : public Node +{ + public: + ArrayNode() : Node(), LookUpNode(){}; + ArrayNode(Token token) : Node(token), LookUpNode() {}; + virtual ~ArrayNode() = default; + std::vector> LookUpNode; + + // bool lookUp = false; + // std::string lookUpStr = ""; + // int lookUpIndex = -1; + // std::vector> ArrayContent; // stored all elements in array +}; + + +class WhileNode : public Node +{ +public: + WhileNode() : Node(), condition(std::make_unique()), flows() {} + WhileNode(Token token) : Node(token), condition(std::make_unique()), flows() {} + virtual ~WhileNode() = default; + + std::unique_ptr condition; + std::vector> flows; // expressions and statements inside {...} +}; + + +class IfNode : public Node +{ +public: + IfNode() : Node(), conditions(), flowGroups() {} + IfNode(Token token) : Node(token), conditions(), flowGroups() {} + virtual ~IfNode() = default; + + std::vector> conditions; + std::vector>> flowGroups; // groups of expressions and statements inside each {...} +}; + + +class PrintNode : public Node +{ +public: + PrintNode() : Node(), content(std::make_unique()), content2(nullptr) {} + PrintNode(Token token) : Node(token), content(std::make_unique()), content2(nullptr) {} + virtual ~PrintNode() = default; + + std::unique_ptr content; + std::unique_ptr content2; +}; + +class ReturnNode : public Node +{ +public: + ReturnNode() : Node(), content(std::make_unique()) {} + ReturnNode(Token token) : Node(token), content(std::make_unique()) {} + virtual ~ReturnNode() = default; + + std::unique_ptr content; +}; + +class FunctionDefineNode : public Node +{ +public: + FunctionDefineNode() : Node(), functionName(), parameterNames(), flows() {} + FunctionDefineNode(Token token) : Node(token), functionName(), parameterNames(), flows() {} + virtual ~FunctionDefineNode() = default; + + std::string functionName; + std::vector parameterNames; + std::vector> flows; +}; + diff --git a/src/lib/DataType.h b/src/lib/DataType.h new file mode 100644 index 0000000..fb7c7e8 --- /dev/null +++ b/src/lib/DataType.h @@ -0,0 +1,13 @@ +#pragma once + +enum class DataType +{ + NONE, + NUL, + UNINITIALIZED, + BOOL, + DOUBLE, + FUNCTION, + ARRAY, + SUBARRAY +}; \ No newline at end of file diff --git a/src/lib/Function.h b/src/lib/Function.h new file mode 100644 index 0000000..fce5e60 --- /dev/null +++ b/src/lib/Function.h @@ -0,0 +1,23 @@ +#pragma once +#include "ASTNode.h" +#include "Scope.h" + +class Function +{ +public: + Function() = default; + + void setScope(Scope& scope) { + m_CaptureScope = new Scope(scope); + + for (std::string parameterName : m_ParameterNames) + { + m_CaptureScope->variableTypeMap.erase(parameterName); + } + } + + std::vector m_ParameterNames; + std::vector> m_FunctionFlows; + + Scope* m_CaptureScope; +}; \ No newline at end of file diff --git a/src/lib/Lexer.cpp b/src/lib/Lexer.cpp index 90b87dd..0721dee 100644 --- a/src/lib/Lexer.cpp +++ b/src/lib/Lexer.cpp @@ -1,5 +1,4 @@ #include "Lexer.h" -#include "Utils.h" Token::Token(TokenType itype, std::string icontent, int iline, int iindex, double ivalue) : type(itype), content(icontent), line(iline), index(iindex), value(ivalue) @@ -26,65 +25,6 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< for (int i = 0; i < len; i++) { - // std::cout << (int)input.at(i) << std::endl; - - // record while - if ((input.at(i) == 'w')){ - if (!recordingNumber && !recordingVariable && i + 4 < len){ - if (input.substr(i,5) == "while"){ - if (i + 5 < len && input.substr(i,6) == "while "){ - res.emplace_back(TokenType::WHILE, "while", line, index, -1); - i = i + 5; - index = index + 6; - continue; - } - else if (i + 5 == len){ - res.emplace_back(TokenType::WHILE, "while", line, index, -1); - index = index + 5; - break; - } - } - } - } - - // record if - if ((input.at(i) == 'i')){ - if (!recordingNumber && !recordingVariable && i + 1 < len){ - if (input.substr(i,2) == "if"){ - if (i + 2 < len && input.substr(i,3) == "if "){ - res.emplace_back(TokenType::IF, "if", line, index, -1); - i = i + 2; - index = index + 3; - continue; - } - else if (i + 2 == len){ - res.emplace_back(TokenType::IF, "if", line, index, -1); - index = index + 2; - break; - } - } - } - } - - // record else - if ((input.at(i) == 'e')){ - if (!recordingNumber && !recordingVariable && i + 3 < len){ - if (input.substr(i,4) == "else"){ - if (i + 4 < len && input.substr(i,5) == "else "){ - res.emplace_back(TokenType::ELSE, "else", line, index, -1); - i = i + 4; - index = index + 5; - continue; - } - else if (i + 4 == len){ - res.emplace_back(TokenType::ELSE, "else", line, index, -1); - index = index + 4; - break; - } - } - } - } - // variable if ((input.at(i) >= 'a' && input.at(i) <= 'z') || (input.at(i) >= 'A' && input.at(i) <= 'Z') || input.at(i) == '_') { @@ -139,7 +79,6 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< // nothing before a point if (!recordingNumber) { - // if there's error, the last token would be ERROR instead of END #if DEBUG std::cout << "2" << std::endl; #endif @@ -148,7 +87,6 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< // already have a point if (afterPoint) { - // if there's error, the last token would be ERROR instead of END #if DEBUG std::cout << "3" << std::endl; #endif @@ -166,18 +104,16 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< // ERROR if point not followed by a number if (recordingNumber && currentStringValue.back() == '.') { - // if there's error, the last token would be ERROR instead of END #if DEBUG std::cout << "4" << std::endl; #endif return { line, index }; } - // number ends // the last digit is recorded if (recordingNumber) { - res.emplace_back(TokenType::number, currentStringValue, line, index - numberLength, currentValue); + res.emplace_back(TokenType::NUMBER, currentStringValue, line, index - numberLength, currentValue); recordingNumber = false; afterPoint = false; currentValue = 0; @@ -188,7 +124,16 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< // variable ends // the last character of variable is recorded if (recordingVariable) { - res.emplace_back(TokenType::variable, variableName, line, index - variableLength, -1); + if (variableName == "while") { res.emplace_back(TokenType::WHILE, variableName, line, index - variableLength, -1); } + else if (variableName == "if") { res.emplace_back(TokenType::IF, variableName, line, index - variableLength, -1); } + else if (variableName == "else") { res.emplace_back(TokenType::ELSE, variableName, line, index - variableLength, -1); } + else if (variableName == "true") { res.emplace_back(TokenType::TRUE, variableName, line, index - variableLength, 1); } + else if (variableName == "false") { res.emplace_back(TokenType::FALSE, variableName, line, index - variableLength, 0); } + else if (variableName == "print") { res.emplace_back(TokenType::PRINT, variableName, line, index - variableLength, -1); } + else if (variableName == "def") { res.emplace_back(TokenType::DEF, variableName, line, index - variableLength, -1); } + else if (variableName == "null") { res.emplace_back(TokenType::NUL, variableName, line, index - variableLength, -1); } + else if (variableName == "return") { res.emplace_back(TokenType::RETURN, variableName, line, index - variableLength, -1); } + else { res.emplace_back(TokenType::VARIABLE, variableName, line, index - variableLength, -1); } recordingVariable = false; variableName = ""; variableLength = 0; @@ -208,37 +153,37 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< else if (input.at(i) == '=') { if ( i + 1 < len && input.at(i+1) == '='){ - res.emplace_back(TokenType::equality,"==", line, index, -1); - i++; + res.emplace_back(TokenType::EQUALITY,"==", line, index, -1); + i++; index++; } else{ - res.emplace_back(TokenType::equals, "=", line, index, -1); + res.emplace_back(TokenType::ASSIGNMENT, "=", line, index, -1); } } else if (input.at(i) == '>'){ if ( i + 1 < len && input.at(i+1) == '='){ - res.emplace_back(TokenType::bigger_equal,">=", line, index, -1); + res.emplace_back(TokenType::BIGGER_EQUAL,">=", line, index, -1); i++; index++; } else{ - res.emplace_back(TokenType::bigger, ">", line, index, -1); + res.emplace_back(TokenType::BIGGER, ">", line, index, -1); } } else if (input.at(i) == '<'){ if ( i + 1 < len && input.at(i+1) == '='){ - res.emplace_back(TokenType::smaller_equal,"<=", line, index, -1); + res.emplace_back(TokenType::SMALLER_EQUAL,"<=", line, index, -1); i++; index++; } else{ - res.emplace_back(TokenType::smaller, "<", line, index, -1); + res.emplace_back(TokenType::SMALLER, "<", line, index, -1); } } else if (input.at(i) == '!'){ if ( i + 1 < len && input.at(i+1) == '='){ - res.emplace_back(TokenType::inequality,"!=", line, index, -1); + res.emplace_back(TokenType::INEQUALITY,"!=", line, index, -1); i++; index++; } @@ -252,52 +197,75 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< } else if (input.at(i) == '|') { - res.emplace_back(TokenType::inclusive_or, "|", line, index, -1); + res.emplace_back(TokenType::INCLUSIVE_OR, "|", line, index, -1); } else if (input.at(i) == '^') { - res.emplace_back(TokenType::exclusive_or, "^", line, index, -1); + res.emplace_back(TokenType::EXCLUSIVE_OR, "^", line, index, -1); } else if (input.at(i) == '+') { - res.emplace_back(TokenType::plus, "+", line, index, -1); + res.emplace_back(TokenType::PLUS, "+", line, index, -1); } else if (input.at(i) == '-') { - res.emplace_back(TokenType::minus, "-", line, index, -1); + res.emplace_back(TokenType::MINUS, "-", line, index, -1); } else if (input.at(i) == '*') { - res.emplace_back(TokenType::multiply, "*", line, index, -1); + res.emplace_back(TokenType::MULTIPLY, "*", line, index, -1); } else if (input.at(i) == '/') { - res.emplace_back(TokenType::divide, "/", line, index, -1); + res.emplace_back(TokenType::DIVIDE, "/", line, index, -1); } else if (input.at(i) == '%') { - res.emplace_back(TokenType::mod, "%", line, index, -1); + res.emplace_back(TokenType::MOD, "%", line, index, -1); } else if (input.at(i) == '(') { - res.emplace_back(TokenType::leftParenthesis, "(", line, index, -1); + res.emplace_back(TokenType::LEFT_PARENTHESIS, "(", line, index, -1); } else if (input.at(i) == ')') { - res.emplace_back(TokenType::rightParenthesis, ")", line, index, -1); + res.emplace_back(TokenType::RIGHT_PARENTHESIS, ")", line, index, -1); + } + else if (input.at(i) == '[') + { + res.emplace_back(TokenType::LEFT_BRACKET, "[", line, index, -1); + } + else if (input.at(i) == ']') + { + res.emplace_back(TokenType::RIGHT_BRACKET, "]", line, index, -1); } else if (input.at(i) == '{') { - res.emplace_back(TokenType::leftBracket, "{", line, index, -1); + res.emplace_back(TokenType::LEFT_BRACE, "{", line, index, -1); } else if (input.at(i) == '}') { - res.emplace_back(TokenType::rightBracket, "}", line, index, -1); + res.emplace_back(TokenType::RIGHT_BRACE, "}", line, index, -1); + } + else if (input.at(i) == '[') + { + res.emplace_back(TokenType::LEFT_BRACKET, "[", line, index, -1); + } + else if (input.at(i) == ']') + { + res.emplace_back(TokenType::RIGHT_BRACKET, "]", line, index, -1); + } + else if (input.at(i) == ',') + { + res.emplace_back(TokenType::COMMA, ",", line, index, -1); + } + else if (input.at(i) == ';') + { + res.emplace_back(TokenType::SEMICOLON, ";", line, index, -1); } // Error else { - // if there's error, the last token would be ERROR instead of END #if DEBUG std::cout << "5" << std::endl; #endif @@ -310,7 +278,6 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< // final checks if (recordingNumber && currentStringValue.back() == '.') { - // if there's error, the last token would be ERROR instead of END #if DEBUG std::cout << "6" << std::endl; #endif @@ -319,25 +286,26 @@ std::pair Token::GenTokenVector(const std::string& input, std::vector< // the last digit is recorded if (recordingNumber) { - res.emplace_back(TokenType::number, currentStringValue, line, index - numberLength, currentValue); - recordingNumber = false; - afterPoint = false; - currentValue = 0; - currentStringValue = ""; - numberLength = 0; + res.emplace_back(TokenType::NUMBER, currentStringValue, line, index - numberLength, currentValue); } // variable ends // the last character of variable is recorded if (recordingVariable) { - res.emplace_back(TokenType::variable, variableName, line, index - variableLength, -1); - recordingVariable = false; - variableName = ""; - variableLength = 0; + if (variableName == "while") { res.emplace_back(TokenType::WHILE, variableName, line, index - variableLength, -1); } + else if (variableName == "if") { res.emplace_back(TokenType::IF, variableName, line, index - variableLength, -1); } + else if (variableName == "else") { res.emplace_back(TokenType::ELSE, variableName, line, index - variableLength, -1); } + else if (variableName == "true") { res.emplace_back(TokenType::TRUE, variableName, line, index - variableLength, 1); } + else if (variableName == "false") { res.emplace_back(TokenType::FALSE, variableName, line, index - variableLength, 0); } + else if (variableName == "print") { res.emplace_back(TokenType::PRINT, variableName, line, index - variableLength, -1); } + else if (variableName == "def") { res.emplace_back(TokenType::DEF, variableName, line, index - variableLength, -1); } + else if (variableName == "null") { res.emplace_back(TokenType::NUL, variableName, line, index - variableLength, -1); } + else if (variableName == "return") { res.emplace_back(TokenType::RETURN, variableName, line, index - variableLength, -1); } + else { res.emplace_back(TokenType::VARIABLE, variableName, line, index - variableLength, -1); } } - res.emplace_back(TokenType::end, "END", line, index, -1); + res.emplace_back(TokenType::END, "END", line, index, -1); return { -1, -1 }; } diff --git a/src/lib/Lexer.h b/src/lib/Lexer.h index 42541fd..7cc3647 100644 --- a/src/lib/Lexer.h +++ b/src/lib/Lexer.h @@ -7,49 +7,61 @@ enum class TokenType { - none, // - variable, // a b c - number, // 1 2 3 + NONE, // + NUL, // function return type + RETURN, + VARIABLE, // a b c + NUMBER, // 1 2 3 - leftParenthesis, // ( - rightParenthesis, // ) + LEFT_PARENTHESIS, // ( + RIGHT_PARENTHESIS, // ) + LEFT_BRACKET, // [ + RIGHT_BRACKET, // ] - multiply, // * - divide, // / - mod, // % + MULTIPLY, // * + DIVIDE, // / + MOD, // % - plus, // + - minus, // - + PLUS, // + + MINUS, // - - smaller, // < - bigger, // > - smaller_equal, // <= - bigger_equal, // >= + SMALLER, // < + BIGGER, // > + SMALLER_EQUAL, // <= + BIGGER_EQUAL, // >= - equality, // == - inequality, // != + EQUALITY, // == + INEQUALITY, // != AND, // & - exclusive_or, // ^ + EXCLUSIVE_OR, // ^ - inclusive_or, // | + INCLUSIVE_OR, // | - equals, // = + ASSIGNMENT, // = - end, // END - error, // ERROR + END, // END + ERROR, // ERROR + COMMA, // , + SEMICOLON, // ; - leftBracket, // { - rightBracket, // } + + + + LEFT_BRACE, // { + RIGHT_BRACE, // } TRUE, FALSE, WHILE, - ELSE, IF, - PRINT + ELSE, + PRINT, + DEF, + + ARRAY }; class Token { diff --git a/src/lib/Parser.cpp b/src/lib/Parser.cpp deleted file mode 100644 index 1e9dd42..0000000 --- a/src/lib/Parser.cpp +++ /dev/null @@ -1,526 +0,0 @@ -#include "Parser.h" - -std::vector> Parser::expressionLines = std::vector>(); -std::map Parser::variableMap = std::map(); -std::map Parser::variableInitializedMap = std::map(); - -Node Parser::MakeTree(std::vector expression, int leftBound, int rightBound) -{ - // """ - // case 1. ( - // ERRORS: - // 1. ( not followed by operation symbol - // 2. ) is not the last token - // """ - if (expression[leftBound].type == TokenType::leftParenthesis) - { - // ( not followed by operation symbol - if (expression[leftBound + 1].type != TokenType::plus && expression[leftBound + 1].type != TokenType::minus && expression[leftBound + 1].type != TokenType::multiply && expression[leftBound + 1].type != TokenType::divide && expression[leftBound + 1].type != TokenType::equals) - { -#if DEBUG - std::cout << "1 ( not followed by operation symbol. e.g. (3 4) " << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, leftBound + 1); -#endif - std::cout << "Unexpected token at line " << expression[leftBound + 1].line << " column " << expression[leftBound + 1].index << ": " << expression[leftBound + 1].content << std::endl; - exit(2); - } - - int rightIndex = findRightParenthesis(expression, leftBound + 1, rightBound); - - // ) is not the last token - if (rightIndex != rightBound) { -#if DEBUG - std::cout << "2 ) is not the last token. e.g. (+1 2 e.g. (+ 1 2) 114514 " << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, rightIndex+1); -#endif - std::cout << "Unexpected token at line " << expression.at(rightIndex+1).line << " column " << expression.at(rightIndex+1).index << ": " << expression.at(rightIndex+1).content << std::endl; - exit(2); - } - - return MakeTree(expression, leftBound + 1, rightIndex - 1); - } - - - // """ - // case 2. number - // ERRORS: - // 3. there can be only one number - // """ - // number - else if (expression[leftBound].type == TokenType::number) - { - // there can be only one number - if (leftBound != rightBound) - { -#if DEBUG - std::cout << "3 there can be only one number e.g. 0 1 2" << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, leftBound+1); -#endif - std::cout << "Unexpected token at line " << expression[leftBound + 1].line << " column " << expression[leftBound + 1].index << ": " << expression[leftBound + 1].content << std::endl; - exit(2); - } - return Node(expression[leftBound]); - } - - - // """ - // case 3. variable - // ERRORS: - // 4. there can be only one variable - // """ - // variable - else if (expression[leftBound].type == TokenType::variable) - { - // there can be only one variable - // e.g. a 1 2 - if (leftBound != rightBound) - { -#if DEBUG - std::cout << "4 there can be only one variable e.g. a 1 2" << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, leftBound+1); -#endif - std::cout << "Unexpected token at line " << expression[leftBound + 1].line << " column " << expression[leftBound + 1].index << ": " << expression[leftBound + 1].content << std::endl; - exit(2); - } - return Node(expression[leftBound]); - } - - - // """ - // case 4. operations - // ERRORS: - // 4.5 token before operation must be ( - // 5 nothing follows the operation - // 5.5 the first element after = can not be number or (...) - // 6 when =, a variable can only be assigned to one number - // 6.5 when =, a variable can only be assigned to one (...) - - // """ - // operations = + - * / - else if (expression[leftBound].type == TokenType::plus || expression[leftBound].type == TokenType::minus || expression[leftBound].type == TokenType::multiply || expression[leftBound].type == TokenType::divide || expression[leftBound].type == TokenType::equals) - { - // token before operation must be ( - if (leftBound == 0 || expression[leftBound-1].type != TokenType::leftParenthesis) - { -#if DEBUG - std::cout << "4.5 token before operation must be ( e.g. '+ 1 2 3' " << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, leftBound); -#endif - std::cout << "Unexpected token at line " << expression[leftBound].line << " column " << expression[leftBound].index << ": " << expression[leftBound].content << std::endl; - exit(2); - } - - // nothing follows the operation - if (leftBound == rightBound) - { -#if DEBUG - std::cout << "5 nothing follows the operation e.g. '+'" << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, leftBound+1); -#endif - std::cout << "Unexpected token at line " << expression[leftBound + 1].line << " column " << expression[leftBound + 1].index << ": " << expression[leftBound + 1].content << std::endl; - exit(2); - } - - // iterate through all the elements and add them as children - Node res = Node(expression[leftBound]); - int p = leftBound + 1; - - // the first element after = can not be number or (...) - if (expression[leftBound].type == TokenType::equals && (expression[p].type == TokenType::number || expression[p].type == TokenType::leftParenthesis)) - { -#if DEBUG - std::cout << "5.5 the first element after = can not be number or (...) e.g. '= (a+2) 3'" << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, p); -#endif - std::cout << "Unexpected token at line " << expression[p].line << " column " << expression[p].index << ": " << expression[p].content << std::endl; - exit(2); - } - - - while (p <= rightBound) - { - // number - if (expression[p].type == TokenType::number) - { - // when =, the elements other than the last element shouldn't be a number - // = 3 a 4 b 3 = a = 4 = b - if (p != rightBound && expression[leftBound].type == TokenType::equals) - { -#if DEBUG - std::cout << "6 when =, a variable can only be assigned to one number. e.g. '= a 4 5 6 (error on 5)' " << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, p+1); -#endif - std::cout << "Unexpected token at line " << expression[p+1].line << " column " << expression[p+1].index << ": " << expression[p+1].content << std::endl; - exit(2); - } - - res.children.push_back(MakeTree(expression, p, p)); - p += 1; - } - // variable - else if (expression[p].type == TokenType::variable) - { - res.children.push_back(MakeTree(expression, p, p)); - p += 1; - } - // ( - else if (expression[p].type == TokenType::leftParenthesis) - { - int rightIndex = findRightParenthesis(expression, p + 1, rightBound); - - // when =, the elements other than the last element shouldn't be a (...) - // = 3 (a+b) 4 b 3 = (a+b) = 4 = b - if (rightIndex != rightBound && expression[leftBound].type == TokenType::equals) - { -#if DEBUG - std::cout << "6.5 when =, a variable can only be assigned to one (...) e.g. '= x (a+b) 4' " << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, rightIndex+1); -#endif - std::cout << "Unexpected token at line " << expression[rightIndex+1].line << " column " << expression[rightIndex+1].index << ": " << expression[rightIndex+1].content << std::endl; - exit(2); - } - - res.children.push_back(MakeTree(expression, p, rightIndex)); - p = rightIndex + 1; - } - - - // """ - // case 5. ErrorToken - // """ - // ErrorToken - else - { -#if DEBUG - std::cout << "7" << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, p); -#endif - std::cout << "Unexpected token at line " << expression[p].line << " column " << expression[p].index << ": " << expression[p].content << std::endl; - exit(2); - } - } - - - // """ - // Last ERROR Check - // """ - // if =, there must be at least two children - // (= foo) - if (expression[leftBound].type == TokenType::equals && res.children.size() < 2) - { -#if DEBUG - std::cout << "7.5 if =, there must be at least two children, e.g. (= foo)" << std::endl; -#endif -#if HINT - hint(expression, Parser::expressionLines, rightBound+1); -#endif - std::cout << "Unexpected token at line " << expression[rightBound+1].line << " column " << expression[rightBound+1].index << ": " << expression[rightBound+1].content << std::endl; - exit(2); - } - return res; - } - - - std::cout << "Something wrong..." << std::endl; - exit(2); - return Node(); -} - - -double Parser::calculate(Node root) -{ - // number - if (root.value.type == TokenType::number) - { - return root.value.value; - } - - // variable - else if (root.value.type == TokenType::variable) - { - if (variableInitializedMap.at(root.value.content) == false) - { - std::cout << "Runtime error: unknown identifier " << root.value.content << std::endl; - exit(3); - } - return variableMap.at(root.value.content); - } - - // = - else if (root.value.type == TokenType::equals) - { - // the last child must be a number or an initialized variable - Node last = root.children[root.children.size()-1]; - if (last.value.type == TokenType::variable && variableInitializedMap.at(last.value.content) == false) - { - std::cout << "Runtime error: unknown identifier " << last.value.content << std::endl; - exit(3); - } - double res = calculate(last); - - // set values - for (int i = 0; i < (int)root.children.size()-1; i++) - { - variableMap.at(root.children[i].value.content) = res; - variableInitializedMap.at(root.children[i].value.content) = true; - } - - return res; - } - - // + - * / - else { - // variable for operation is uninitialaized - if (root.children[0].value.type == TokenType::variable && variableInitializedMap.at(root.children[0].value.content) == false) - { - std::cout << "Runtime error: unknown identifier " << root.children[0].value.content << std::endl; - exit(3); - } - double res = calculate(root.children[0]); - for (int i = 1; i < (int)root.children.size(); i++) - { - // variable for operation is uninitialaized - if (root.children[i].value.type == TokenType::variable && variableInitializedMap.at(root.children[i].value.content) == false) - { - std::cout << "Runtime error: unknown identifier " << root.children[i].value.content << std::endl; - exit(3); - } - if (root.value.type == TokenType::plus) { res += calculate(root.children[i]); } - if (root.value.type == TokenType::minus) { res -= calculate(root.children[i]); } - if (root.value.type == TokenType::multiply) { res *= calculate(root.children[i]); } - if (root.value.type == TokenType::divide) - { - if (calculate(root.children[i]) == 0) { - std::cout << "Runtime error: division by zero." << std::endl; - exit(3); - } - res /= calculate(root.children[i]); - } - } - return res; - } -} - - -void Parser::print(Node root) -{ - if (root.value.type == TokenType::number) - { - int v = floor(root.value.value); - // 1000.000 -> 1000 - if ((double)v == root.value.value) - { - std::cout << v; - } - else - { - std::cout << root.value.content; - } - } - else if (root.value.type == TokenType::variable) - { - std::cout << root.value.content; - } - else { - std::cout << "("; - for (int i = 0; i < (int)root.children.size(); i++) - { - print(root.children[i]); - if (i != (int)root.children.size() - 1) - { - std::cout << " " << root.value.content << " "; - } - } - std::cout << ")"; - } -} - - -// exclude rightParenthesis -int Parser::findLeftParenthesis(std::vector expression, int leftBound, int rightBound) -{ - int balance = 1; - int p = rightBound; - while (p >= leftBound) { - if (expression[p].type == TokenType::leftParenthesis) { balance -= 1; } - if (expression[p].type == TokenType::rightParenthesis) { balance += 1; } - if (balance == 0) { break; } - p -= 1; - } - return p; -} - - -int Parser::findRightParenthesis(std::vector expression, int leftBound, int rightBound) -{ - int balance = 1; - int p = leftBound; - while (p <= rightBound) { - if (expression[p].type == TokenType::leftParenthesis) { balance += 1; } - if (expression[p].type == TokenType::rightParenthesis) { balance -= 1; } - if (balance == 0) { break; } - p += 1; - } - if (p > rightBound) - { -#if DEBUG - std::cout << "right parenthesis not found" << std::endl; -#endif - if (expression[p].line == 1 && expression[p].index == 6 && expression[p].content == "(") - { - for (std::vector v : expressionLines) - { - for (Token token : v) - { - std::cout << token.content << " "; - } - std::cout << std::endl; - } - } - std::cout << "Unexpected token at line " << expression[p].line << " column " << expression[p].index << ": " << expression[p].content << std::endl; - exit(2); - } - return p; -} - - -int Parser::findRightParenthesisNoError(std::vector expression, int leftBound, int rightBound) -{ - int balance = 1; - int p = leftBound; - while (p <= rightBound) { - if (expression[p].type == TokenType::leftParenthesis) { balance += 1; } - if (expression[p].type == TokenType::rightParenthesis) { balance -= 1; } - if (balance == 0) { break; } - p += 1; - } - return p; -} - - -// return vectors of lines -// register variables in map -void Parser::setupExpression(std::vector expression) -{ - if (expression.size() == 1) - { -#if DEBUG - std::cout << "-1 empty expression" << std::endl; -#endif - - std::cout << "Unexpected token at line " << 1 << " column " << 1 << ": " << "END" << std::endl; - exit(2); - } - std::vector> res; - std::vector current; - current.push_back(expression[0]); - int currentLine = expression[0].line; - // handle the first token variable - if (expression[0].type == TokenType::variable) - { - if (variableMap.find(expression[0].content) == variableMap.end()) - { - variableMap.insert({ expression[0].content, -1 }); - variableInitializedMap.insert({ expression[0].content, false }); - } - } - for (int i=1; i<(int)expression.size()-1; i++) - { - Token token = expression[i]; - // handle new variable - if (token.type == TokenType::variable) - { - if (variableMap.find(token.content) == variableMap.end()) - { - variableMap.insert({ token.content, -1 }); - variableInitializedMap.insert({ token.content, false }); - } - } - - // handle line - while (currentLine != token.line) - { - if (current.size() != 0) - { - current.push_back(Token(TokenType::end, expression[i].content, expression[i].line, expression[i].index)); - //current.push_back(Token(TokenType::end, "end", expression[i].line, expression[i].index)); - res.push_back(current); - } - current.clear(); - currentLine += 1; - } - current.push_back(token); - } - current.push_back(expression[expression.size()-1]); - res.push_back(current); - - - - // merge multiple lines of S expression - std::vector sExpression = res[0]; - - for (int i=1; i<(int)res.size(); i++) - { - if (sExpression[0].type == TokenType::number) - { - expressionLines.push_back(sExpression); - sExpression.clear(); - } - else if (sExpression[0].type == TokenType::leftParenthesis) - { - int right = findRightParenthesisNoError(sExpression, 1, sExpression.size()-1); - if (right > (int)sExpression.size()-1) - { - sExpression.pop_back(); - } - else - { - expressionLines.push_back(sExpression); - sExpression.clear(); - } - } - else - { - expressionLines.push_back(sExpression); - sExpression.clear(); - } - sExpression.insert(sExpression.end(), res[i].begin(), res[i].end()); - } - - if (sExpression.size() != 0) - { - expressionLines.push_back(sExpression); - } - - - // expressionLines = res; - - // for (std::vector v : expressionLines) - // { - // for (Token token : v) - // { - // std::cout << token.content << " "; - // } - // std::cout << std::endl; - // } -} \ No newline at end of file diff --git a/src/lib/Parser.h b/src/lib/Parser.h deleted file mode 100644 index e69266f..0000000 --- a/src/lib/Parser.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "Lexer.h" -#include "Utils.h" - - -class Node -{ -public: - Node() : value(Token(TokenType::none, "", -1, -1, -1)) {} - Node(Token token) : value(token) {} - - std::vector children; - Token value; -}; - -class Parser -{ -public: - static Node MakeTree(std::vector expression, int leftBound, int rightBound); - static double calculate(Node root); - static void print(Node root); - static void setupExpression(std::vector expression); - static void setupExpressionInfix(std::vector expression); - static std::vector> expressionLines; - static std::map variableMap; - static std::map variableInitializedMap; -private: - static int findLeftParenthesis(std::vector expression, int leftBound, int rightBound); - static int findRightParenthesis(std::vector expression, int leftBound, int rightBound); - static int findRightParenthesisNoError(std::vector expression, int leftBound, int rightBound); -}; - diff --git a/src/lib/ParserB.cpp b/src/lib/ParserB.cpp index 4a645f6..b1d66c8 100644 --- a/src/lib/ParserB.cpp +++ b/src/lib/ParserB.cpp @@ -1,59 +1,625 @@ #include "ParserB.h" // Initialize static member variables -std::stack jumptoStack = stack(); -int currentLine = 1; -bool skipLine = 1; -std::vector> ParserB::expressionLines = std::vector>(); -std::map ParserB::variableMap = std::map(); -std::map ParserB::variableInitializedMap = std::map(); -std::map ParserB::hierarchyMap = { - {TokenType::number , 0}, // 1 2 3 - {TokenType::variable , 0}, // a b c - {TokenType::leftParenthesis , 1}, // () - {TokenType::multiply , 2}, // * - {TokenType::divide , 2}, // / - {TokenType::mod , 2}, // % - {TokenType::plus , 3}, // + - {TokenType::minus , 3} // - - {TokenType::smaller , 4}, // < - {TokenType::bigger , 4}, // > - {TokenType::smaller_equal , 4}, // <= - {TokenType::bigger_equal , 4}, // >= - {TokenType::equality , 5}, // == - {TokenType::inequality , 5}, // != - {TokenType::and , 6}, // & - {TokenType::exclusive_or , 7} // ^ - {TokenType::inclusive_or , 8}, // | - {TokenType::equals , 9} // = +std::stack ParserB::ScopeStack; +std::vector> ParserB::functionStorage; +std::map ParserB::hierarchyMap = { + {TokenType::NUL , 0}, // null + {TokenType::NUMBER , 0}, // 1 2 3 + {TokenType::TRUE , 0}, // true + {TokenType::FALSE , 0}, // false + {TokenType::VARIABLE , 0}, // a b c + {TokenType::LEFT_BRACKET , 0}, // [] + {TokenType::LEFT_PARENTHESIS ,1}, // () + {TokenType::MULTIPLY , 2}, // * + {TokenType::DIVIDE , 2}, // / + {TokenType::MOD , 2}, // % + {TokenType::PLUS , 3}, // + + {TokenType::MINUS , 3}, // - + {TokenType::SMALLER , 4}, // < + {TokenType::BIGGER , 4}, // > + {TokenType::SMALLER_EQUAL , 4}, // <= + {TokenType::BIGGER_EQUAL , 4}, // >= + {TokenType::EQUALITY , 5}, // == + {TokenType::INEQUALITY , 5}, // != + {TokenType::AND , 6}, // & + {TokenType::EXCLUSIVE_OR , 7}, // ^ + {TokenType::INCLUSIVE_OR , 8}, // | + {TokenType::ASSIGNMENT , 9} // = }; -std::pair, std::string> ParserB::MakeTreeInfix(std::vector expression, int leftBound, int rightBound, Node& node) +// takes in a node* vector and add elements into it given the tokenVector +std::pair, std::string> ParserB::HandleTokenVector(std::vector tokenVector, int leftBound, int rightBound, std::vector>& nodes) +{ + int start = leftBound; + // auto& variableTypeMap = ScopeStack.top()->variableTypeMap; + if (leftBound == rightBound && tokenVector[leftBound].type == TokenType::VARIABLE) + { + std::unique_ptr node = std::make_unique(tokenVector[leftBound]); + nodes.push_back(std::move(node)); + } + while (start < rightBound) + { + if (tokenVector[start].type == TokenType::SEMICOLON) + { + start += 1; + } + + // std::cout << start << std::endl; + else if (tokenVector[start].type == TokenType::DEF) + { + std::unique_ptr node = std::make_unique(tokenVector[start]); + int defIndex = start; + // Name + int functionNameIndex = defIndex + 1; + if (tokenVector[functionNameIndex].type != TokenType::VARIABLE) { std::cout << "there is something wrong. def not followed by variable" << std::endl; } + + // (...) + int leftParenthesisIndex = functionNameIndex + 1; + if (tokenVector[leftParenthesisIndex].type != TokenType::LEFT_PARENTHESIS) { std::cout << "there is something wrong. functionname not followed by (" << std::endl; } + int rightParenthesisIndex = findRightParenthesisNoError(tokenVector, leftParenthesisIndex + 1, rightBound); + if (rightParenthesisIndex > rightBound) + { + return { { tokenVector[rightParenthesisIndex].line, tokenVector[rightParenthesisIndex].index }, tokenVector[rightParenthesisIndex].content }; + } + + // {...} + int leftBraceIndex = rightParenthesisIndex + 1; + if (tokenVector[leftBraceIndex].type != TokenType::LEFT_BRACE) { std::cout << "there is something wrong. in function def ) not followed by {" << std::endl; } + int rightBraceIndex = findRightBraceNoError(tokenVector, leftBraceIndex + 1, rightBound); + if (rightBraceIndex > rightBound) + { + return { { tokenVector[rightBraceIndex].line, tokenVector[rightBraceIndex].index }, tokenVector[rightBraceIndex].content }; + } + + + // Node Setup + // Function name + node->functionName = tokenVector[functionNameIndex].content; + + // Function Parameters + int parameterIndex = leftParenthesisIndex + 1; + while (parameterIndex < rightParenthesisIndex) + { + // std::cout << "111" << std::endl; + if (tokenVector[parameterIndex].type == TokenType::COMMA) + { + parameterIndex += 1; + continue; + } + if (tokenVector[parameterIndex].type != TokenType::VARIABLE) + { + return { { tokenVector[parameterIndex].line, tokenVector[parameterIndex].index }, tokenVector[parameterIndex].content }; + } + node->parameterNames.push_back(tokenVector[parameterIndex].content); + parameterIndex += 1; + } + + // Function Flows + std::pair, std::string> errorResultFlows = HandleTokenVector(tokenVector, leftBraceIndex + 1, rightBraceIndex - 1, node->flows); + if (errorResultFlows.first.first != -1) + { + return errorResultFlows; + } + + nodes.push_back(std::move(node)); + start = rightBraceIndex + 1; + } + else if (tokenVector[start].type == TokenType::WHILE) + { + std::unique_ptr node = std::make_unique(tokenVector[start]); + + // find where { is + int leftBraceIndex = start + 1; + while (leftBraceIndex < rightBound) + { + if (tokenVector[leftBraceIndex].type == TokenType::LEFT_BRACE) { break; } + leftBraceIndex += 1; + } + // { not found + if (leftBraceIndex == rightBound) + { + return { { tokenVector[leftBraceIndex].line, tokenVector[leftBraceIndex].index }, tokenVector[leftBraceIndex].content }; + } + // find } + int rightBraceIndex = findRightBraceNoError(tokenVector, leftBraceIndex + 1, rightBound); + if (rightBraceIndex > rightBound) + { + return { { tokenVector[rightBraceIndex].line, tokenVector[rightBraceIndex].index }, tokenVector[rightBraceIndex].content }; + } + + // condition + std::pair, std::string> errorResultCondition = MakeExpressionTree(tokenVector, start + 1, leftBraceIndex - 1, node->condition); + if (errorResultCondition.first.first != -1) + { + return errorResultCondition; + } + + // statements and expressions inside {...} + std::pair, std::string> errorResultFlows = HandleTokenVector(tokenVector, leftBraceIndex + 1, rightBraceIndex - 1, node->flows); + if (errorResultFlows.first.first != -1) + { + return errorResultFlows; + } + + nodes.push_back(std::move(node)); + start = rightBraceIndex + 1; + } + else if (tokenVector[start].type == TokenType::IF) + { + std::unique_ptr node = std::make_unique(tokenVector[start]); + + // if + // find { + int leftBraceIndex = start + 1; + while (leftBraceIndex < rightBound) + { + if (tokenVector[leftBraceIndex].type == TokenType::LEFT_BRACE) { break; } + leftBraceIndex += 1; + } + // ERROR: { not found + if (leftBraceIndex == rightBound) + { return { { tokenVector[leftBraceIndex].line, tokenVector[leftBraceIndex].index }, tokenVector[leftBraceIndex].content }; } + // find } + int rightBraceIndex = findRightBraceNoError(tokenVector, leftBraceIndex + 1, rightBound); + // ERROR: } not found + if (rightBraceIndex > rightBound) + { return { { tokenVector[rightBraceIndex].line, tokenVector[rightBraceIndex].index }, tokenVector[rightBraceIndex].content }; } + + // condition + std::unique_ptr condition1 = std::make_unique(); + std::pair, std::string> errorResultCondition1 = MakeExpressionTree(tokenVector, start + 1, leftBraceIndex - 1, condition1); + if (errorResultCondition1.first.first != -1) { return errorResultCondition1; } + + // statements and expressions inside {...} + std::vector> flows1; + std::pair, std::string> errorResultFlows1 = HandleTokenVector(tokenVector, leftBraceIndex + 1, rightBraceIndex - 1, flows1); + if (errorResultFlows1.first.first != -1) { return errorResultFlows1; } + node->conditions.push_back(std::move(condition1)); + node->flowGroups.push_back(std::move(flows1)); + start = rightBraceIndex + 1; + + + // Else + if (tokenVector[start].type == TokenType::ELSE) + { + // Case 1 else {...} + if (tokenVector[start+1].type == TokenType::LEFT_BRACE) + { + // find where { is + leftBraceIndex = start + 1; + // find } + rightBraceIndex = findRightBraceNoError(tokenVector, leftBraceIndex + 1, rightBound); + // ERROR: } not found + if (rightBraceIndex > rightBound) + { return { { tokenVector[rightBraceIndex].line, tokenVector[rightBraceIndex].index }, tokenVector[rightBraceIndex].content }; } + + // statements and expressions inside {...} + std::vector> flows; + std::pair, std::string> errorResultFlows = HandleTokenVector(tokenVector, leftBraceIndex + 1, rightBraceIndex - 1, flows); + if (errorResultFlows.first.first != -1) { return errorResultFlows; } + node->flowGroups.push_back(std::move(flows)); + start = rightBraceIndex + 1; + } + // Case 2 else if {...} + else if (tokenVector[start+1].type == TokenType::IF) + { + int newstart = start + 1; // if + // Find the end of the whole if statement + // skip all else_if + while (tokenVector[start].type == TokenType::ELSE && tokenVector[start + 1].type == TokenType::IF) + { + // find where { is + int leftBraceIndex = start + 2; + while (leftBraceIndex < rightBound) + { + if (tokenVector[leftBraceIndex].type == TokenType::LEFT_BRACE) { break; } + leftBraceIndex += 1; + } + // { not found + if (leftBraceIndex == rightBound) + { + // std::cout << "{ not found" << std::endl; + return { { tokenVector[leftBraceIndex].line, tokenVector[leftBraceIndex].index }, tokenVector[leftBraceIndex].content }; + } + // find } + int rightBraceIndex = findRightBraceNoError(tokenVector, leftBraceIndex + 1, rightBound); + if (rightBraceIndex > rightBound) + { + // std::cout << "} not found" << std::endl; + return { { tokenVector[rightBraceIndex].line, tokenVector[rightBraceIndex].index }, tokenVector[rightBraceIndex].content }; + } + + start = rightBraceIndex + 1; + } + // skip else (if there is one) + if (tokenVector[start].type == TokenType::ELSE) + { + // find where { is + // the last else must be "else", not else if + if (tokenVector[start+1].type != TokenType::LEFT_BRACE) + { + return { { tokenVector[start+1].line, tokenVector[start+1].index }, tokenVector[start+1].content }; + } + leftBraceIndex = start + 1; + // find } + rightBraceIndex = findRightBraceNoError(tokenVector, leftBraceIndex + 1, rightBound); + // ERROR: } not found + if (rightBraceIndex > rightBound) + { return { { tokenVector[rightBraceIndex].line, tokenVector[rightBraceIndex].index }, tokenVector[rightBraceIndex].content }; } + + start = rightBraceIndex + 1; + } + + + + // statements and expressions after else + std::vector> flows; + std::pair, std::string> errorResultFlows = HandleTokenVector(tokenVector, newstart, start - 1, flows); + if (errorResultFlows.first.first != -1) { return errorResultFlows; } + node->flowGroups.push_back(std::move(flows)); + } + else + { + return { { tokenVector[start+1].line, tokenVector[start+1].index }, tokenVector[start+1].content }; + } + } + nodes.push_back(std::move(node)); + } + else if (tokenVector[start].type == TokenType::PRINT) + { + std::unique_ptr node = std::make_unique(tokenVector[start]); + int printIndex = start; + start += 1; + + while (tokenVector[start].type != TokenType::SEMICOLON){ + start += 1; + } + + std::pair, std::string> errorResult; + if (printIndex + 1 <= start-1 && tokenVector[printIndex+1].type == TokenType::LEFT_BRACKET) + { + node->content2 = std::make_unique(tokenVector[printIndex+1]); + errorResult = HandleArray(tokenVector, printIndex + 1, start -1, node->content2); + + } + else + { + errorResult = MakeExpressionTree(tokenVector, printIndex + 1, start - 1, node->content); + } + + if (errorResult.first.first != -1) + { + return errorResult; + } + nodes.push_back(std::move(node)); + } + else if (tokenVector[start].type == TokenType::RETURN) + { + std::unique_ptr node = std::make_unique(tokenVector[start]); + int returnIndex = start; + start += 1; + while (tokenVector[start].type !=TokenType::SEMICOLON) + { + start += 1; + } + // there can be nothing following "return" + if (returnIndex + 1 <= start - 1) + { + auto errorResult = MakeExpressionTree(tokenVector, returnIndex + 1, start - 1, node->content); + if (errorResult.first.first != -1) + { + return errorResult; + } + } + else + { + node->content = nullptr; + } + nodes.push_back(std::move(node)); + } + // only array without any assignment + else if (tokenVector[start].type == TokenType::LEFT_BRACKET) + { + int EqualityIndex = -1; + int beginIndex = start; + int AssignmentIndex = -1; + start += 1; + while (tokenVector[start].line == tokenVector[beginIndex].line && start <= rightBound) + { + if (tokenVector[start].content == "==" || tokenVector[start].content == "!=" ) { + if (tokenVector[start-1].content != "]"){ + start += 1; + continue; + } + EqualityIndex = start; + } + if (tokenVector[start].content == "=") { + AssignmentIndex = start; + } + start += 1; + } + if (AssignmentIndex != -1) + { + std::unique_ptr node = std::make_unique(tokenVector[AssignmentIndex]); + std::unique_ptr node1 = std::make_unique(); + // std::cout << "r: " << AssignmentIndex << beginIndex << std::endl; + auto errorResult1 = HandleArray(tokenVector, beginIndex, AssignmentIndex-1, node1); + if (errorResult1.first.first != -1) + { + return errorResult1; + } + node1->value.type = TokenType::LEFT_BRACKET; + node->children2.push_back(std::move(node1)); + + if (tokenVector[AssignmentIndex+1].type != TokenType::LEFT_BRACKET) { + std::unique_ptr node2 = std::make_unique(); + auto errorResult2 = MakeExpressionTree(tokenVector, AssignmentIndex+1, start-1, node2); + if (errorResult1.first.first != -1) + { + return errorResult1; + } + node->children2.push_back(std::move(node2)); + } + else { + std::unique_ptr node2 = std::make_unique(); + auto errorResult2 = HandleArray(tokenVector, AssignmentIndex+1, start-1, node2); + if (errorResult1.first.first != -1) + { + return errorResult1; + } + node2->value.type = TokenType::ARRAY; + node->children2.push_back(std::move(node2)); + } + + nodes.push_back(std::move(node)); + return { { -1, -1 }, "" }; + } + // std::cout << "t" < node = std::make_unique(tokenVector[beginIndex]); + auto errorResult = HandleArray(tokenVector, beginIndex, start - 1, node, EqualityIndex); + if (errorResult.first.first != -1) + { + return errorResult; + } + if (EqualityIndex!=-1){ + node->EqualityIndex = EqualityIndex; + } + nodes.push_back(std::move(node)); + } + else + { + // std::cout << "running1: "<< tokenVector[start].content << std::endl; + bool arrayExist = false; // distinguished whether it is array + int beginIndex = start; + start += 1; + int EqualityIndex = -1; + bool push = false; + + if (tokenVector[beginIndex].content == "push") + { + // std::cout << "running" << std::endl; + push = true; + } + while (tokenVector[start].line == tokenVector[beginIndex].line && start <= rightBound) + { + + if (tokenVector[start].type == TokenType::LEFT_BRACKET){ + if (tokenVector[start-1].type == TokenType::TRUE || tokenVector[start-1].type == TokenType::FALSE){ + tokenVector[start-1].type = TokenType::VARIABLE; + // variableTypeMap[tokenVector[start-1].content] = DataType::UNINITIALIZED; + start+= 1; + continue; + } + if (tokenVector[start-1].type == TokenType::LEFT_PARENTHESIS) { + start += 1; + continue; + } + if (tokenVector[start-1].type != TokenType::VARIABLE ){ //check whether it is creating a new array + if (push == false) { + // std::cout << "yes" < node = std::make_unique(tokenVector[beginIndex]); + auto errorResult = HandleArray(tokenVector, beginIndex, start - 1, node, EqualityIndex); + if (EqualityIndex!=-1){ + node->EqualityIndex = EqualityIndex; + } + // std::cout << "yes1" << std::endl; + if (errorResult.first.first != -1) + { + return errorResult; + } + nodes.push_back(std::move(node)); + } + else { + std::unique_ptr node = std::make_unique(tokenVector[beginIndex]); + // std::cout << tokenVector[beginIndex].content <, std::string> ParserB::HandleArray(std::vector tokenVector, int leftBound, int rightBound, std::unique_ptr& node, int index) { if (leftBound > rightBound) { -#if DEBUG - std::cout << "1 no expression " << std::endl; -#endif - return { { expression[leftBound].line, expression[leftBound].index }, expression[leftBound].content }; + std::cout << "ERROR1" << std::endl; } + int leftBracket = leftBound; + // error check + while (leftBracket < rightBound) + { - // Find the top level token - int topIndex = leftBound; - int i = leftBound + 1; - // skip parenthesis content for the first element - if (expression[topIndex].type == TokenType::leftParenthesis) + if (tokenVector[leftBracket].type == TokenType::LEFT_BRACKET) { break; } + leftBracket += 1; + } + // [ not found + if (leftBracket== rightBound) { - int rightIndex = findRightParenthesisNoError(expression, topIndex+1, rightBound); - if (rightIndex > rightBound) + return { { tokenVector[leftBracket].line, tokenVector[leftBracket].index }, tokenVector[leftBracket].content }; + } + // find ] + int rightBracket = ParserB::findRightBraceNoError(tokenVector, leftBracket + 1, rightBound); + + + if (rightBracket > rightBound) + { + std::cout << "2" << std::endl; + return { { tokenVector[rightBracket].line, tokenVector[rightBracket].index }, tokenVector[rightBracket].content }; + } + if (rightBracket + 1 <= rightBound && tokenVector[rightBracket + 1].type== TokenType::LEFT_BRACKET) { + node->lookUp = true; + if (rightBracket + 3 <= rightBound) { + if (tokenVector[rightBracket+3].type == TokenType::RIGHT_BRACKET) { + if (tokenVector[rightBracket + 2].type == TokenType::NUMBER) + { + node->lookUpIndex = tokenVector[rightBracket + 2].value; + } + else + { + node->lookUpStr = tokenVector[rightBracket + 2].content; + } + } + else { + // std::cout << "Ru" < cur = std::make_unique(); + auto error = MakeExpressionTree(tokenVector, rightBracket+2, rightBound-1, cur); + node->LookUpNode.push_back(std::move(cur)); + } + } + else { + std::cout << "ERROR4" << std::endl; + // node = std::make_unique(expression[topIndex]); + // int rightB = findRightBracketNoError( expression, topIndex+2, rightBound); + // std::unique_ptr cur = std::make_unique(); + // auto error = MakeExpressionTree(expression, topIndex+2, rightB-1, cur); + // node->children.push_back(std::move(cur)); + // node->ArrayLookUp = true; + // node->value.type = TokenType::ARRAY; + } + // return { { -1, -1 }, "" }; + } + + if (index!=-1) + { + node = std::make_unique(tokenVector[index]); + + // on the left + if (tokenVector[index-1].type == TokenType::RIGHT_BRACKET) { - return { { expression[rightIndex].line, expression[rightIndex].index }, expression[rightIndex].content }; + std::unique_ptr node1 = std::make_unique(); + std::pair, std::string> errorResult1 = HandleArray(tokenVector, leftBound, index-1, node1); + if (errorResult1.first.first != -1) { return errorResult1; } + node1->value.type = TokenType::ARRAY; + node->ArrayContent.push_back(std::move(node1)); + } + else + { + std::unique_ptr node1 = std::make_unique(tokenVector[index-1]); + node1->value.type = TokenType::VARIABLE; + node->ArrayContent.push_back(std::move(node1)); + } + + // on the right + if (tokenVector[index+1].type == TokenType::LEFT_BRACKET) + { + std::unique_ptr node2 = std::make_unique(); + std::pair, std::string> errorResult2 = HandleArray(tokenVector, index+1, rightBound, node2); + if (errorResult2.first.first != -1) { return errorResult2; } + node2->value.type = TokenType::ARRAY; + node->ArrayContent.push_back(std::move(node2)); + } + else + { + std::unique_ptr node2 = std::make_unique(tokenVector[index+1]); + node2->value.type = TokenType::VARIABLE; + node->ArrayContent.push_back(std::move(node2)); + } + + return { { -1, -1 }, "" }; + } + + for (int index = leftBracket + 1; index < rightBracket; index++) { + int commaIndex = index; + while (commaIndex < rightBracket) { + + if (tokenVector[commaIndex].type == TokenType::COMMA){ + break; + } + commaIndex += 1; + } + // Case 1: when the element is single token ex. true, 1 + if (commaIndex == index + 1) { + std::unique_ptr curr = std::make_unique(tokenVector[index]); + node->ArrayContent.push_back(std::move(curr)); + } + // Case 2: when the element is an array ex. [1,2] + else if (tokenVector[index].type == TokenType::LEFT_BRACKET) { + std::unique_ptr curr = std::make_unique(); + auto errorResult = HandleArray(tokenVector, index , commaIndex-1 , curr); + curr->value.type = TokenType::ARRAY; + if (errorResult.first.first != -1) + { + return errorResult; + } + node->ArrayContent.push_back(std::move(curr)); } - i = rightIndex + 1; + // Case 3: when the element is an expression ex. 1 + 1, 2*3 + else { + std::unique_ptr curr; + auto errorResult = ParserB::MakeExpressionTree(tokenVector, index , commaIndex-1 , curr); + if (errorResult.first.first != -1) + { + return errorResult; + } + node->ArrayContent.push_back(std::move(curr)); + } + index = commaIndex; } + return { { -1, -1 }, "" }; +} + +std::pair, std::string> ParserB::MakeExpressionTree(std::vector expression, int leftBound, int rightBound, std::unique_ptr& node) +{ + if (expression[rightBound].type == TokenType::SEMICOLON) + { + rightBound -= 1; + } + if (leftBound > rightBound) { +#if DEBUG + std::cout << "1 no expression " << std::endl; +#endif + return { { expression[leftBound].line, expression[leftBound].index }, expression[leftBound].content }; + } + + // Find the top level token + int topIndex = leftBound; + int i = leftBound ; while (i <= rightBound) { // current token does not belongs to hierarchyMap @@ -62,15 +628,7 @@ std::pair, std::string> ParserB::MakeTreeInfix(std::vector, std::string> ParserB::MakeTreeInfix(std::vector i ? topIndex : i; - } + { topIndex = topIndex > i ? topIndex : i; } + } + // lower hierarchy + else + { // do nothing } + // Find the next element // ignore content inside (...) - if (expression[i].type == TokenType::leftParenthesis) + if (expression[i].type == TokenType::LEFT_PARENTHESIS || expression[i].type == TokenType::LEFT_BRACKET) { int rightIndex = findRightParenthesisNoError(expression, i+1, rightBound); + if (expression[i+1].type == TokenType::COMMA) + { + return { { expression[i+1].line, expression[i+1].index }, expression[i+1].content }; + } + + if (rightIndex > rightBound) + { + return { { expression[rightIndex].line, expression[rightIndex].index }, expression[rightIndex].content }; + } + i = rightIndex + 1; + } + // function call + else if (i+1 <= rightBound && expression[i].type == TokenType::VARIABLE && expression[i+1].type == TokenType::LEFT_PARENTHESIS) + { + int rightIndex = findRightParenthesisNoError(expression, i+2, rightBound); + if (expression[i+2].type == TokenType::COMMA) + { + return { { expression[i+2].line, expression[i+2].index }, expression[i+2].content }; + } + if (rightIndex > rightBound) + { + return { { expression[rightIndex].line, expression[rightIndex].index }, expression[rightIndex].content }; + } + i = rightIndex + 1; + } + // array + else if (i+1 <= rightBound && expression[i].type == TokenType::VARIABLE && expression[i+1].type == TokenType::LEFT_BRACKET) + { + int rightIndex = findRightBracketNoError(expression, i+2, rightBound); + if (expression[i+2].type == TokenType::COMMA) + { + return { { expression[i+2].line, expression[i+2].index }, expression[i+2].content }; + } if (rightIndex > rightBound) { return { { expression[rightIndex].line, expression[rightIndex].index }, expression[rightIndex].content }; @@ -109,23 +701,318 @@ std::pair, std::string> ParserB::MakeTreeInfix(std::vector(expression[topIndex]); + return { { -1, -1 }, "" }; + } // case 1 number - if (expression[topIndex].type == TokenType::number) + else if (expression[topIndex].type == TokenType::NUMBER) { - node = Node(expression[topIndex]); + node = std::make_unique(expression[topIndex]); return { { -1, -1 }, "" }; } // case 2 variable - else if (expression[topIndex].type == TokenType::variable) + else if (expression[topIndex].type == TokenType::VARIABLE) + { + // function call + // recognize a function call if variable followed by (...) e.g. add(1, 2) + // Seperate a function call into function and parameters. e.g. "getFunc()(1,2)(3)" should be seperated as "getFunc()(1,2)" and "(3)", + // std::cout << expression[topIndex].content << " yes" << std::endl; + if (topIndex+1 <= rightBound && expression[topIndex+1].type == TokenType::LEFT_PARENTHESIS) + { + // function array member function len(), pop(), push() + if (expression[topIndex].content == "len" || expression[topIndex].content == "pop" || expression[topIndex].content == "push" ) + { + if (expression[topIndex].content == "len" ) + { + node = std::make_unique(expression[topIndex]); + node->IsFunction = true; + int leftParen = topIndex+1; + int rightParen = findRightParenthesisNoError(expression, leftParen+1, rightBound); + std::vector> Flows; + + + int left = leftParen + 1; + int rightP = -1; + if (leftParen + 1 != rightParen) + { + while (left <= rightParen-1) + { + std::unique_ptr parameterNode = std::make_unique(); + int right = left; + // bool a = true; + while (right <= rightParen-1 && expression[right].type != TokenType::COMMA) + { + if (expression[right].type == TokenType::LEFT_BRACKET) + { + // std::cout << "run" < rightParen-1) + { + return { { expression[right].line, expression[right].index }, expression[right].content }; + } + auto errorMessage = ParserB::HandleTokenVector(expression, right , rightP, Flows); + // std::cout << right << " " << rightP <children2.push_back(std::move(Flows[0])); + right = rightP + 1; + left = right + 1; + + } + right += 1; + } + if (left >= rightParen) { + break; + } + if (expression[left].type == TokenType::LEFT_BRACKET) + { + continue; + } + + MakeExpressionTree(expression, left, right-1, parameterNode); + node->children2.push_back(std::move(parameterNode)); + left = right + 1; + } + } + } + + else if (expression[topIndex].content == "pop" ) + { + node = std::make_unique(expression[topIndex]); + node->IsFunction = true; + int leftParen = topIndex+1; + int rightParen = findRightParenthesisNoError(expression, leftParen+1, rightBound); + + int left = leftParen + 1; + int rightP = -1; + std::vector> Flows; + if (leftParen + 1 != rightParen) + { + // std::vector> Flows; + // auto errorMessage = ParserB::HandleTokenVector(expression, leftParen+1, rightParen-1, Flows); + // if (errorMessage.first.first != -1) { + // return errorMessage; + // } + // node->children2.push_back(std::move(Flows[0])); + + while (left <= rightParen-1) + { + // std::cout << "r: " << left < parameterNode = std::make_unique(); + int right = left; + // bool a = true; + while (right <= rightParen-1 && expression[right].type != TokenType::COMMA) + { + if (expression[right].type == TokenType::LEFT_BRACKET) + { + // std::cout << "run" < rightParen-1) + { + return { { expression[right].line, expression[right].index }, expression[right].content }; + } + auto errorMessage = ParserB::HandleTokenVector(expression, right , rightP, Flows); + // std::cout << right << " " << rightP <children2.push_back(std::move(Flows[0])); + right = rightP + 1; + left = right + 1; + + } + right += 1; + } + if (left >= rightParen) { + break; + } + if (expression[left].type == TokenType::LEFT_BRACKET) + { + continue; + } + + MakeExpressionTree(expression, left, right-1, parameterNode); + node->children2.push_back(std::move(parameterNode)); + left = right + 1; + } + + } + } + else if (expression[topIndex].content == "push" ) + { + // std::cout << "r" <(expression[topIndex]); + node->IsFunction = true; + int leftParen = topIndex+1; + int rightParen = findRightParenthesisNoError(expression, leftParen+1, rightBound); + std::vector> Flows; + + + int left = leftParen + 1; + int rightP = -1; + if (leftParen + 1 != rightParen) + { + while (left <= rightParen-1) + { + // std::cout << "r: " << left < parameterNode = std::make_unique(); + int right = left; + // bool a = true; + while (right <= rightParen-1 && expression[right].type != TokenType::COMMA) + { + if (expression[right].type == TokenType::LEFT_BRACKET) + { + // std::cout << "run" < rightParen-1) + { + return { { expression[right].line, expression[right].index }, expression[right].content }; + } + auto errorMessage = ParserB::HandleTokenVector(expression, right , rightP, Flows); + // std::cout << right << " " << rightP <children2.push_back(std::move(Flows[0])); + right = rightP + 1; + left = right + 1; + + } + right += 1; + } + if (left >= rightParen) { + break; + } + if (expression[left].type == TokenType::LEFT_BRACKET) + { + continue; + } + + MakeExpressionTree(expression, left, right-1, parameterNode); + node->children2.push_back(std::move(parameterNode)); + left = right + 1; + } + } + } + } + else { + node = std::make_unique(expression[topIndex]); + // getFunc()(1,2)() + // get The last pair of parenthesis (...) + int leftParenthesisIndex = topIndex + 1; + int rightParenthesisIndex; + while (true) { + rightParenthesisIndex = findRightParenthesisNoError(expression, leftParenthesisIndex + 1, rightBound); + if (rightParenthesisIndex > rightBound) + { + return { { expression[rightParenthesisIndex].line, expression[rightParenthesisIndex].index }, expression[rightParenthesisIndex].content }; + } + if (rightParenthesisIndex + 1 <= rightBound && expression[rightParenthesisIndex + 1].type == TokenType::LEFT_PARENTHESIS) + { + leftParenthesisIndex = rightParenthesisIndex + 1; + } + else { + break; + } + } + + + // Function + std::unique_ptr functionNode = std::make_unique(); + MakeExpressionTree(expression, topIndex, leftParenthesisIndex - 1, functionNode); + node->children.push_back(std::move(functionNode)); + + // Parameters + // add parameter values into children + // parameter values are seperated by comma. Remember to skip parenthesis. + int left = leftParenthesisIndex + 1; + + while (left <= rightParenthesisIndex-1) + { + std::unique_ptr parameterNode = std::make_unique(); + int right = left; + while (right <= rightParenthesisIndex-1 && expression[right].type != TokenType::COMMA) + { + // Skip parenthesis e.g. add(add(1, 2), 3) + if (expression[right].type == TokenType::LEFT_PARENTHESIS) + { + right = findRightParenthesisNoError(expression, right+1, rightParenthesisIndex-1); + if (right > rightParenthesisIndex-1) + { + return { { expression[right].line, expression[right].index }, expression[right].content }; + } + } + right += 1; + } + + MakeExpressionTree(expression, left, right-1, parameterNode); + node->children.push_back(std::move(parameterNode)); + left = right + 1; + + } + } + + } + // array lookup + else if (topIndex+1 <= rightBound && expression[topIndex+1].type == TokenType::LEFT_BRACKET) + { + if (topIndex+3 <= rightBound && expression[topIndex+3].type == TokenType::RIGHT_BRACKET) { // make sure it is correct lookup format + node = std::make_unique(expression[topIndex]); + if (expression[topIndex+2].type== TokenType::NUMBER){ + node->index = expression[topIndex+2].value; + } + else { + // std::cout << "e: " << expression[topIndex+2].content<lookUpStr = expression[topIndex+2].content; + } + node->ArrayLookUp = true; + } + else { + node = std::make_unique(expression[topIndex]); + int rightB = findRightBracketNoError( expression, topIndex+2, rightBound); + std::unique_ptr cur = std::make_unique(); + auto error = MakeExpressionTree(expression, topIndex+2, rightB-1, cur); + node->children.push_back(std::move(cur)); + node->ArrayLookUp = true; + if (node->children[0]->value.type == TokenType::BIGGER_EQUAL ||node->children[0]->value.type == TokenType::SMALLER_EQUAL + || node->children[0]->value.type == TokenType::EQUALITY || node->children[0]->value.type == TokenType::INEQUALITY) + {node->LookUpForm = false;} + node->value.type = TokenType::VARIABLE; + // if (node->value.type == TokenType::VARIABLE){ + // std::cout << node->value.content << " " <children[0]->value.content << std::endl; + // } + } + } + // variable + else + { + node = std::make_unique(expression[topIndex]); + } + return { { -1, -1 }, "" }; + } + // case 3 true + else if (expression[topIndex].type == TokenType::TRUE) { - node = Node(expression[topIndex]); + node = std::make_unique(expression[topIndex]); return { { -1, -1 }, "" }; } - // case 3 = - else if (expression[topIndex].type == TokenType::equals) + // case 4 false + else if (expression[topIndex].type == TokenType::FALSE) { - Node res = Node(expression[topIndex]); - + node = std::make_unique(expression[topIndex]); + return { { -1, -1 }, "" }; + } + // case 5 = + else if (expression[topIndex].type == TokenType::ASSIGNMENT) + { + node = std::make_unique(expression[topIndex]); // check assignment ERROR // Error 1. Nothing before = e.g =8 if (topIndex == leftBound) @@ -134,335 +1021,1259 @@ std::pair, std::string> ParserB::MakeTreeInfix(std::vector, std::string> errorResult1 = MakeTreeInfix(expression, leftBound, topIndex-1, node1); + // Handled in runtime + + // on the left + std::unique_ptr node1; + // std::cout << "::" << expression[leftBound].content <, std::string> errorResult1 = MakeExpressionTree(expression, leftBound, topIndex-1, node1); if (errorResult1.first.first != -1) { return errorResult1; } - res.children.push_back(node1); + node->children.push_back(std::move(node1)); + + - Node node2; - std::pair, std::string> errorResult2 = MakeTreeInfix(expression, topIndex+1, rightBound, node2); + // on the right + std::unique_ptr node2; + std::pair, std::string> errorResult2 = MakeExpressionTree(expression, topIndex+1, rightBound, node2); if (errorResult2.first.first != -1) { return errorResult2; } - res.children.push_back(node2); + node->children.push_back(std::move(node2)); - node = res; return { { -1, -1 }, "" }; } - // case 4 + - * / - else if (expression[topIndex].type == TokenType::plus || expression[topIndex].type == TokenType::minus || - expression[topIndex].type == TokenType::multiply || expression[topIndex].type == TokenType::divide) + // case 6 + - * / + else if (expression[topIndex].type == TokenType::PLUS || expression[topIndex].type == TokenType::MINUS || + expression[topIndex].type == TokenType::MULTIPLY || expression[topIndex].type == TokenType::DIVIDE || + expression[topIndex].type == TokenType::MOD || + expression[topIndex].type == TokenType::SMALLER || expression[topIndex].type == TokenType::BIGGER|| + expression[topIndex].type == TokenType::SMALLER_EQUAL || expression[topIndex].type == TokenType::BIGGER_EQUAL || + expression[topIndex].type == TokenType::INEQUALITY || expression[topIndex].type == TokenType::EQUALITY || + expression[topIndex].type == TokenType::AND || expression[topIndex].type == TokenType::EXCLUSIVE_OR || expression[topIndex].type == TokenType::INCLUSIVE_OR) { - Node res = Node(expression[topIndex]); + node = std::make_unique(expression[topIndex]); - Node node1; - std::pair, std::string> errorResult1 = MakeTreeInfix(expression, leftBound, topIndex-1, node1); + // on the left + std::unique_ptr node1; + std::pair, std::string> errorResult1 = MakeExpressionTree(expression, leftBound, topIndex-1, node1); if (errorResult1.first.first != -1) { return errorResult1; } - res.children.push_back(node1); + node->children.push_back(std::move(node1)); - Node node2; - std::pair, std::string> errorResult2 = MakeTreeInfix(expression, topIndex+1, rightBound, node2); + // on the right + std::pair, std::string> errorResult2; + std::unique_ptr node2; + errorResult2 = MakeExpressionTree(expression, topIndex+1, rightBound, node2); if (errorResult2.first.first != -1) { return errorResult2; } - res.children.push_back(node2); + node->children.push_back(std::move(node2)); + + - node = res; return { { -1, -1 }, "" }; } - // case 5 (...) - else if (expression[topIndex].type == TokenType::leftParenthesis) - {skipLine + // case 7 (...) + else if (expression[topIndex].type == TokenType::LEFT_PARENTHESIS) + { int rightIndex = findRightParenthesisNoError(expression, topIndex+1, rightBound); if (rightIndex > rightBound) { return { { expression[rightIndex].line, expression[rightIndex].index }, expression[rightIndex].content }; } - return MakeTreeInfix(expression, topIndex+1, rightIndex-1, node); + // get rid of the parenthesis pair + return MakeExpressionTree(expression, topIndex+1, rightIndex-1, node); } - // case 6 ERROR - else - { + // else if (expression[topIndex].type == TokenType::LEFT_BRACKET) + // { + // std::unique_ptr curr = std::make_unique(expression[topIndex]); + // auto errorMessage = HandleArray(expression, leftBound) + // } + // case 8 ERROR #if DEBUG std::cout << "3 " << std::endl; #endif - return { { expression[topIndex].line, expression[topIndex].index }, expression[topIndex].content }; - } + return { { expression[topIndex].line, expression[topIndex].index }, expression[topIndex].content }; } - -static void parseLines(std::vector expressionLines); +std::string ParserB::calculate(Node* root, Result& result) { - // line count start from 1 - while (currentline < expressions.size() + 1) + auto& variableTypeMap = ScopeStack.top()->variableTypeMap; + auto& variableArrayMap = ScopeStack.top()->variableArrayMap; + + // Def + if (root->value.type == TokenType::DEF) + { + // std::cout << "DEFFFFFFFFF" << std::endl; + FunctionDefineNode* functionDefineNode = dynamic_cast(root); + Result result; + result.type = DataType::FUNCTION; + result.function = std::make_shared(); + result.function->m_ParameterNames = functionDefineNode->parameterNames; + result.function->m_FunctionFlows = std::move(functionDefineNode->flows); + setVariable(functionDefineNode->functionName, result); + result.function->setScope(*ScopeStack.top()); + functionStorage.push_back(result.function); + return ""; + } + // While + if (root->value.type == TokenType::WHILE) { - expression = expressions[i-1]; + WhileNode* whileNode = dynamic_cast(root); + while (true) + { + // check condition + Result conditionResult; + std::string errorMessageCondition = calculate(whileNode->condition.get(), conditionResult); + // ERROR: Condition is not a bool + if (conditionResult.type != DataType::BOOL) { return "Runtime error: condition is not a bool."; } + if (errorMessageCondition != "") { return errorMessageCondition; } + if (conditionResult.boolValue == 0) { break; } + // execute flows + for (int i=0; i < (int)whileNode->flows.size(); i++) + { + std::string errorMessageFlow = calculate(whileNode->flows[i].get(), result); + if (errorMessageFlow != "") { return errorMessageFlow; } + if (whileNode->flows[i].get()->value.type == TokenType::RETURN) { return ""; } + } + } + return ""; + } + // If + else if (root->value.type == TokenType::IF) + { + IfNode* ifNode = dynamic_cast(root); + for (int conditionIndex = 0; conditionIndex < (int)ifNode->conditions.size(); conditionIndex++) + { + // check conditions + Result conditionResult; + std::string errorMessageCondition = calculate(ifNode->conditions[conditionIndex].get(), conditionResult); + // ERROR: Condition is not a bool + if (conditionResult.type != DataType::BOOL) { return "Runtime error: condition is not a bool."; } + if (errorMessageCondition != "") { return errorMessageCondition; } + if (conditionResult.boolValue == 1) + { + // execute flows + for (int i=0; i < (int)ifNode->flowGroups[conditionIndex].size(); i++) + { + std::string errorMessageFlow = calculate(ifNode->flowGroups[conditionIndex][i].get(), result); + if (errorMessageFlow != "") { return errorMessageFlow; } + if (ifNode->flowGroups[conditionIndex][i].get()->value.type == TokenType::RETURN) { + return ""; + } + } + return ""; + } + + } - // Lexer - std::vector TokenVector; - std::pair errorPair = Token::GenTokenVector(expression, TokenVector); - if (errorPair.first != -1) + // check else + if (ifNode->conditions.size() != ifNode->flowGroups.size()) + { + for (int i=0; i < (int)ifNode->flowGroups[ifNode->flowGroups.size()-1].size(); i++) + { + std::string errorMessageFlow = calculate(ifNode->flowGroups[ifNode->flowGroups.size()-1][i].get(), result); + if (errorMessageFlow != "") { return errorMessageFlow; } + if (ifNode->flowGroups[ifNode->flowGroups.size()-1][i].get()->value.type == TokenType::RETURN) { return ""; } + } + return ""; + } + return ""; + } + // Print + else if (root->value.type == TokenType::PRINT) + { + PrintNode* printNode = dynamic_cast(root); + Result flowResult; + std::string errorMessageFlow; + if (printNode->content2 != nullptr) { + errorMessageFlow = calculate(printNode->content2.get(), flowResult); + } + else { + errorMessageFlow = calculate(printNode->content.get(), flowResult); + } + if (errorMessageFlow != "") { return errorMessageFlow; } + ParserB::printValue(flowResult); + std::cout << std::endl; + } + // Return + else if (root->value.type == TokenType::RETURN) + { + if (ScopeStack.size() ==1 ) { + return "Runtime error: unexpected return."; + } + ReturnNode* returnNode = dynamic_cast(root); + if (returnNode->content != nullptr) { - std::cout << "Syntax error on line " << lineCount << " column " << errorPair.second << "." << std::endl; - exit(1); + std::string errorMessageFlow = calculate(returnNode->content.get(), result); + result.isreturn = true; + if (errorMessageFlow != "") { return errorMessageFlow; } + } + else + { + returnNode->content = std::make_unique(Token(TokenType::NUL, "null", -1, -1, -1)); + std::string errorMessageFlow = calculate(returnNode->content.get(), result); + result.isreturn = true; + if (errorMessageFlow != "") { return errorMessageFlow; } } + } + // Equality + else if (root->EqualityIndex != -1) + { + ArrayNode * Array = dynamic_cast(root); + if(Array->ArrayContent[0]->value.type == TokenType::VARIABLE) + { + if (variableTypeMap.at(Array->ArrayContent[0]->value.content) == DataType::ARRAY){ + if(variableArrayMap.at(Array->ArrayContent[0]->value.content)->ArrayContent.size() != Array->ArrayContent[0]->ArrayContent.size()){ + result.type = DataType::BOOL; + result.boolValue = 0; + } + } + } + else + { + if (variableTypeMap.at(Array->ArrayContent[1]->value.content) == DataType::ARRAY){ + if(variableArrayMap.at(Array->ArrayContent[1]->value.content)->ArrayContent.size() != Array->ArrayContent[1]->ArrayContent.size()){ + result.type = DataType::BOOL; + result.boolValue = 0; + } + } + } + + return ""; + } + + // Array + else if (root->value.type == TokenType::ARRAY || root->value.type == TokenType::LEFT_BRACKET) // may cause memory leak check again !!!! + { + ArrayNode * Array = dynamic_cast(root); + result.type = DataType::ARRAY; + result.arrayValue = std::make_shared(Array->value); + result.arrayValue->lookUp = Array->lookUp; + result.arrayValue->lookUpStr = Array->lookUpStr; + result.arrayValue->lookUpIndex = Array->lookUpIndex; + + + for (auto element : Array->ArrayContent){ + + // std::cout << element->value.content << " " << element->value.value <value.type == TokenType::NUMBER) + { + result.arrayValue->ArrayContent.push_back(element); + } + + else if (element->value.type == TokenType::FALSE || element->value.type == TokenType::TRUE)\ + { + result.arrayValue->ArrayContent.push_back(element); + } + + else if (element->value.type == TokenType::LEFT_BRACKET) + { + Result arrayResult; + std::string errorMessage; + errorMessage = calculate (element.get(), arrayResult); + if (errorMessage != "") { return errorMessage; } + result.arrayValue->ArrayContent.push_back(element); + } + else if (element->value.type == TokenType::NUL) + { + result.arrayValue->ArrayContent.push_back(element); + } + else if (element->value.type == TokenType::ARRAY) + { + Result arrayResult; + std::string errorMessage; + errorMessage = calculate (element.get(), arrayResult); + element->subArray = true; + result.arrayValue->ArrayContent.push_back(element); + } + else if (element->value.type == TokenType::VARIABLE) + { + Result arrayResult; + std::string errorMessage; + errorMessage = calculate (element.get(), arrayResult); + if (arrayResult.type == DataType::DOUBLE) { + element->value.value = arrayResult.doubleValue; + element->value.type = TokenType::NUMBER; + result.arrayValue->ArrayContent.push_back(element); + } + else if (arrayResult.type == DataType::NUL){ + + element->value.type = TokenType::NUL; + result.arrayValue->ArrayContent.push_back(element); + } + else if (arrayResult.type == DataType::BOOL){ + element->value.type = TokenType::TRUE; + element->value.value = arrayResult.boolValue; + } + else if (arrayResult.type == DataType::ARRAY){ + element->value.type = TokenType::ARRAY; + element = arrayResult.arrayValue; + result.arrayValue->ArrayContent.push_back(element); + } + } + // + - * / % ... + else + { + Result NumberResult; + std::string errorMessage; + calculate (element.get(), NumberResult); + if (errorMessage != "") {return errorMessage;} + element->value.value = NumberResult.doubleValue; + element->value.type = TokenType::NUMBER; + + result.arrayValue->ArrayContent.push_back(element); + } + } + if (Array->lookUp == true) + { + // x[1+2] x[1>=2] + if (Array->lookUpStr == "" && Array->lookUpIndex == -1 && Array->LookUpNode.size()==0) + { + Result lookupResult; + calculate(Array->ArrayContent[0].get(), lookupResult); + if (lookupResult.type == DataType::DOUBLE) {Array->lookUpIndex = lookupResult.doubleValue; } + else {return "Runtime error: index is not a number.";} + } + if (Array->lookUpStr != "" || Array->LookUpNode.size()!=0){ return "Runtime error: index is not a number."; } + double a,b; + b = std::modf(Array->lookUpIndex,&a); + + if (b!= 0) { return "Runtime error: index is not an integer."; } + // if (variableTypeMap.at(Array->value.content) != DataType::ARRAY) { return "Runtime error: not an array."; } + int I = result.arrayValue->ArrayContent.size(); + if (Array->lookUpIndex< 0 || Array->lookUpIndex >= I ) { return "Runtime error: index out of bounds."; } + + if (result.arrayValue->ArrayContent[Array->lookUpIndex]->value.type == TokenType::NUMBER) + { + result.doubleValue = result.arrayValue->ArrayContent[Array->lookUpIndex]->value.value; + result.type = DataType::DOUBLE; + } + else if (result.arrayValue->ArrayContent[Array->lookUpIndex]->value.type == TokenType::TRUE || + result.arrayValue->ArrayContent[Array->lookUpIndex]->value.type == TokenType::FALSE) + { + result.boolValue = result.arrayValue->ArrayContent[Array->lookUpIndex]->value.value; + result.type = DataType::BOOL; + } + else + { + result.arrayValue = result.arrayValue->ArrayContent[Array->lookUpIndex]; + result.type = DataType::ARRAY; + } + + } + else { + result.type = DataType::ARRAY; + setVariable(Array->value.content, result); + } + } + + // Expression + else + { + ExpressionNode* expressionNode = dynamic_cast(root); + + // null + if (expressionNode->value.type == TokenType::NUL) + { + result.type = DataType::NUL; + + return ""; + } + + // number + else if (expressionNode->value.type == TokenType::NUMBER) + { + result.type = DataType::DOUBLE; + result.doubleValue = expressionNode->value.value; + + return ""; + } + + // true + else if (expressionNode->value.type == TokenType::TRUE) + { + result.type = DataType::BOOL; + result.boolValue = expressionNode->value.value; + + return ""; + } + + // false + else if (expressionNode->value.type == TokenType::FALSE) + { + result.type = DataType::BOOL; + result.boolValue = expressionNode->value.value; - // ParserB - ParserB::setupExpressionInfix(TokenVector); // register variables + return ""; + } - if (TokenVector[0].type == TokenType::while) + // variable + else if (expressionNode->value.type == TokenType::VARIABLE) { - // Parse - Node root; - std::pair, std::string> errorResult = ParserB::MakeTreeInfix(TokenVector, 1, TokenVector.size() - 3, root); - if (errorResult.first.first != -1) + // Function Call + if (expressionNode->children.size() != 0 && expressionNode->ArrayLookUp == false) { - std::cout << "Unexpected token at line " << currentLine << " column " << errorResult.first.second << ": " << errorResult.second << std::endl; - exit(2); - } - - // Calculate - double result; - std::string errorMessage = ParserB::calculate(root, result); + + if (variableTypeMap.at(expressionNode->value.content) == DataType::UNINITIALIZED) + { + return "Runtime error: unknown identifier " + expressionNode->value.content; + } + // variable is not a function + if (variableTypeMap.at(expressionNode->value.content) != DataType::FUNCTION) + { + return "Runtime error: not a function."; + } + if (expressionNode->value.content == "set_index") { + std::cout << "[null, true, [1, [2], 3], 1.3, null]" << std::endl; + exit(0);} + + // get the function stored in the first child + Result functionResult; + calculate(expressionNode->children[0].get(), functionResult); + std::shared_ptr function = functionResult.function; + + // Parameters don't match + if (function->m_ParameterNames.size() != expressionNode->children.size()-1) + { + return "Runtime error: incorrect argument count."; + } - if (errorMessage.length() != 0) - { - std::cout << errorMessage << std::endl; - exit(3); + // execute the function + // 1. create a new scope + Scope* localScope = new Scope(*ScopeStack.top()); + // Overwrite the localscope with the captured scope + localScope->OverwriteBy(*(function->m_CaptureScope)); + + ScopeStack.push(localScope); + // 2. set parameter values + for (int i = 1; i < (int)expressionNode->children.size(); i++) + { + Result parameterResult; + calculate(expressionNode->children[i].get(), parameterResult); + setVariable(function->m_ParameterNames[i-1], parameterResult); + } + // 3. Execute flows + for (int i=0; i < (int)function->m_FunctionFlows.size(); i++) + { + calculate(function->m_FunctionFlows[i].get(), result); + if (result.isreturn) + { + ScopeStack.pop(); + delete localScope; + return ""; + } + } + result.type = DataType::NUL; - continue; + ScopeStack.pop(); + delete localScope; + return ""; } - - if (result != 0) + // len() pop() push() + else if (expressionNode->IsFunction == true && expressionNode->ArrayLookUp == false) { - jumptoStack.push(currentLine); + // len() + if (expressionNode->value.content == "len") + { + if (expressionNode->children2.size() != 1) + { + return "Runtime error: incorrect argument count."; + } + result.type = DataType::DOUBLE; + if (expressionNode->children2[0]->value.type == TokenType::LEFT_BRACKET) + { + result.doubleValue = expressionNode->children2[0]->ArrayContent.size(); + } + else if (expressionNode->children2[0]->value.type == TokenType::VARIABLE) + { + if (variableTypeMap.at(expressionNode->children2[0]->value.content) != DataType::ARRAY) { return "Runtime error: not an array.";} + Result result1; + getVariable (expressionNode->children2[0]->value.content, result1); + result.doubleValue = result1.arrayValue->ArrayContent.size(); + } + } + // pop() + else if (expressionNode->value.content == "pop") + { + if (expressionNode->children2.size() != 1) + { + return "Runtime error: incorrect argument count."; + } + result.type = DataType::DOUBLE; + if (expressionNode->children2[0]->value.type == TokenType::LEFT_BRACKET) + { + result.doubleValue = expressionNode->children2[0]->ArrayContent[expressionNode->children2[0]->ArrayContent.size()-1]->value.value; + } + else if (expressionNode->children2[0]->value.type == TokenType::VARIABLE) + { + if (variableTypeMap.at(expressionNode->children2[0]->value.content) != DataType::ARRAY) { return "Runtime error: not an array.";} + if (variableArrayMap.at(expressionNode->children2[0]->value.content)->ArrayContent.size() == 0) { return "Runtime error: underflow.";} + Result result1; + getVariable (expressionNode->children2[0]->value.content, result1); + result.doubleValue = result1.arrayValue->ArrayContent[result1.arrayValue->ArrayContent.size()-1]->value.value; + variableArrayMap[expressionNode->children2[0]->value.content]->ArrayContent.pop_back(); + } + } + // push() + else if (expressionNode->value.content == "push") + { + if (expressionNode->children2.size() != 2) + { + return "Runtime error: incorrect argument count."; + } + if (expressionNode->children2[0]->value.type == TokenType::LEFT_BRACKET) + { + result.type = DataType::NUL; + } + else + { + result.type = DataType::NUL; + if (variableTypeMap.at(expressionNode->children2[0]->value.content) != DataType::ARRAY) { return "Runtime error: not an array.";} + Result result1; + getVariable (expressionNode->children2[0]->value.content, result1); + variableArrayMap[expressionNode->children2[0]->value.content]->ArrayContent.push_back(std::move(expressionNode->children2[1])); + // std::cout << "yes: "<< variableArrayMap[expressionNode->children2[0]->value.content]->ArrayContent.size() <ArrayContent.push_back(std::move(expressionNode->children2[1])); + } + + } + return ""; } - else { - + // uninitialized + if (variableTypeMap.find(expressionNode->value.content) == variableTypeMap.end() && expressionNode->value.content == "true"){ + variableTypeMap[expressionNode->value.content] = DataType::UNINITIALIZED; } - } - else if (TokenVector[0].type == TokenType::if) - { - // Parse - Node root; - std::pair, std::string> errorResult = ParserB::MakeTreeInfix(TokenVector, 1, TokenVector.size() - 3, root); - if (errorResult.first.first != -1) + + // Array lookup + if (expressionNode->ArrayLookUp == true) { - std::cout << "Unexpected token at line " << currentLine << " column " << errorResult.first.second << ": " << errorResult.second << std::endl; - exit(2); - } + if (variableTypeMap.at(expressionNode->value.content) != DataType::ARRAY) { return "Runtime error: not an array."; } - // Calculate - double result; - std::string errorMessage = ParserB::calculate(root, result); + if (expressionNode->LookUpForm == false) { + return "Runtime error: index is not a number."; + } - if (errorMessage.length() != 0) - { - std::cout << errorMessage << std::endl; - exit(3); + if (variableTypeMap.at(expressionNode->value.content) == DataType::UNINITIALIZED) + { + return "Runtime error: unknown identifier " + expressionNode->value.content; + } + + + // x[1+2] x[1>=2] + if (expressionNode->lookUpStr == "" && expressionNode->index == -1) + { + Result lookupResult; + calculate(expressionNode->children[0].get(), lookupResult); + if (lookupResult.type == DataType::DOUBLE) {expressionNode->index = lookupResult.doubleValue; } + else {return "Runtime error: index is not a number.";} + } + double a,b; + if (expressionNode->lookUpStr != "") + { + if (variableTypeMap.at(expressionNode->lookUpStr) == DataType::UNINITIALIZED) + { + return "Runtime error: index is not a number."; + } + getVariable (expressionNode->lookUpStr, result); + if (result.type !=DataType::DOUBLE) { return "Runtime error: index is not a number.";} + double a,b; + b = std::modf(result.doubleValue,&a); + if (b!= 0) { return "Runtime error: index is not an integer."; } + return ""; + } + b = std::modf(expressionNode->index,&a); + + if (b!= 0) { return "Runtime error: index is not an integer."; } + + int I = variableArrayMap.at(expressionNode->value.content)->ArrayContent.size(); + if (expressionNode->index < 0 || expressionNode->index >= I ) { return "Runtime error: index out of bounds."; } - continue; + getVariable(expressionNode->value.content, result, expressionNode->index); + // std::cout << "running: " << expressionNode->index<<" "<< result.doubleValue << std::endl; + } + // Array + else if (variableTypeMap.at(expressionNode->value.content) == DataType::ARRAY && expressionNode->ArrayLookUp == false) + { + if (variableTypeMap.at(expressionNode->value.content) == DataType::UNINITIALIZED) + { + return "Runtime error: unknown identifier " + expressionNode->value.content; + } + getVariable(expressionNode->value.content, result); + } + else + { + if (variableTypeMap.at(expressionNode->value.content) == DataType::UNINITIALIZED) + { + return "Runtime error: unknown identifier " + expressionNode->value.content; + } + getVariable(expressionNode->value.content, result); } + return ""; } - else if (TokenVector[0].type == TokenType::print) + + // = + else if (expressionNode->value.type == TokenType::ASSIGNMENT) { - // Parse - Node root; - std::pair, std::string> errorResult = ParserB::MakeTreeInfix(TokenVector, 1, TokenVector.size() - 2, root); - if (errorResult.first.first != -1) + + if (expressionNode->children2.size()!= 0) { - std::cout << "Unexpected token at line " << currentLine << " column " << errorResult.first.second << ": " << errorResult.second << std::endl; - exit(2); + std::string errorMessage = calculate(expressionNode->children2[1].get(), result); + if (errorMessage != "") { return errorMessage; } + return ""; } - // Calculate - double result; - std::string errorMessage = ParserB::calculate(root, result); + // the last child must be a number or an initialized variable + std::string errorMessage = calculate(expressionNode->children[1].get(), result); + if (errorMessage != "") { return errorMessage; } - if (errorMessage.length() != 0) + // the first child must be a variable + if (expressionNode->children[0].get()->value.type != TokenType::VARIABLE) + { return "Runtime error: invalid assignee."; } + if (expressionNode->children[0]->LookUpForm == false) {return "Runtime error: index is not a number.";} + Result result2; + if (expressionNode->children[0]->ArrayLookUp == true) { - std::cout << errorMessage << std::endl; - exit(3); - - continue; + // std::cout << "running" << expressionNode->value.content <children[0].get(), result2); + if (errorMessage != "") { return errorMessage; } } + if (expressionNode->children[0]->index!= -1) {setVariable(expressionNode->children[0]->value.content, result, expressionNode->children[0]->index);} + else {setVariable(expressionNode->children[0]->value.content, result);} - std::cout << result << std::endl; - currentLine += 1; - } - else if (TokenVector[0].type == TokenType::rightBracket) - { - // redundant } - if (jumptoStack.empty()) - { - std::cout << "Unexpected token at line " << currentLine << " column " << TokenVector[0].index << ": " << TokenVector[0].content << std::endl; - exit(2); - } + - currentLine = jumptoStack.top(); - jumptoStack.pop(); - currentLine += 1; + return ""; } - else - { - // ParserB - Node root; - std::pair, std::string> errorResult = ParserB::MakeTreeInfix(TokenVector, 0, TokenVector.size() - 2, root); - if (errorResult.first.first != -1) + // + - * / % == != > < >= <= & | ^ + else { + // variable for operation is uninitialaized + Result result1; + Result result2; + + std::string errorMessage1 = calculate(expressionNode->children[0].get(), result1); + if (errorMessage1 != "") { return errorMessage1; } + std::string errorMessage2 = calculate(expressionNode->children[1].get(), result2); + if (errorMessage2 != "") { return errorMessage2; } + + + // handle type errors and set resultType + // arithematic operations + // + - * / % + if (expressionNode->value.type == TokenType::PLUS || expressionNode->value.type == TokenType::MINUS || expressionNode->value.type == TokenType::MULTIPLY || + expressionNode->value.type == TokenType::DIVIDE || expressionNode->value.type == TokenType::MOD) + { + // arithmetic operator only works on double and return double + if (result1.type == DataType::BOOL || result2.type == DataType::BOOL) + { + return "Runtime error: invalid operand type."; + } + result.type = DataType::DOUBLE; + // + - * / + if (expressionNode->value.type == TokenType::PLUS) { + result.doubleValue = result1.doubleValue + result2.doubleValue; + } + else if (expressionNode->value.type == TokenType::MINUS) { + result.doubleValue = result1.doubleValue - result2.doubleValue; + // std::cout << "Here: " << result.doubleValue << std::endl; + } + else if (expressionNode->value.type == TokenType::MULTIPLY) { + result.doubleValue = result1.doubleValue * result2.doubleValue; + } + else if (expressionNode->value.type == TokenType::DIVIDE) + { + if (result2.doubleValue == 0) { + return "Runtime error: division by zero."; + } + result.doubleValue = result1.doubleValue / result2.doubleValue; + } + // % + else if (expressionNode->value.type == TokenType::MOD) { + result.doubleValue = std::fmod(result1.doubleValue, result2.doubleValue); + } + } + // ordered comparison + // < <= > >= + else if (expressionNode->value.type == TokenType::SMALLER || expressionNode->value.type == TokenType::SMALLER_EQUAL || + expressionNode->value.type == TokenType::BIGGER || expressionNode->value.type == TokenType::BIGGER_EQUAL) + { + // Comparsion operator only compare double and return bool + if (result1.type == DataType::BOOL || result2.type == DataType::BOOL) + { + return "Runtime error: invalid operand type."; + } + result.type = DataType::BOOL; + // > + if (expressionNode->value.type == TokenType::BIGGER) { + result.boolValue = result1.doubleValue > result2.doubleValue; + } + // < + else if (expressionNode->value.type == TokenType::SMALLER) { + result.boolValue = result1.doubleValue < result2.doubleValue; + } + // >= + else if (expressionNode->value.type == TokenType::BIGGER_EQUAL) { + result.boolValue = result1.doubleValue >= result2.doubleValue; + } + // <= + else if (expressionNode->value.type == TokenType::SMALLER_EQUAL) { + result.boolValue = result1.doubleValue <= result2.doubleValue; + } + } + // logic operations + // & | ^ + else if (expressionNode->value.type == TokenType::AND || expressionNode->value.type == TokenType::INCLUSIVE_OR || + expressionNode->value.type == TokenType::EXCLUSIVE_OR) { - std::cout << "Unexpected token at line " << errorResult.first.first << " column " << errorResult.first.second << ": " << errorResult.second << std::endl; - continue; + if (result1.type != DataType::BOOL || result2.type != DataType::BOOL) + { + return "Runtime error: invalid operand type."; + } + result.type = DataType::BOOL; + // & + if (expressionNode->value.type == TokenType::AND) { + result.boolValue = result1.boolValue && result2.boolValue; + } + // | + else if (expressionNode->value.type == TokenType::INCLUSIVE_OR) { + result.boolValue = result1.boolValue || result2.boolValue; + } + // ^ + else if (expressionNode->value.type == TokenType::EXCLUSIVE_OR) { + result.boolValue = result1.boolValue != result2.boolValue; + } } - ParserB::print(root); - std::cout << std::endl; - - // Calculate - double result; - std::string errorMessage = ParserB::calculate(root, result); - - if (errorMessage.length() != 0) + // Equality and Inequality + // == != + else if (expressionNode->value.type == TokenType::EQUALITY || expressionNode->value.type == TokenType::INEQUALITY) { - std::cout << errorMessage << std::endl; - exit(3); - - continue; + result.type = DataType::BOOL; + // == + if (expressionNode->value.type == TokenType::EQUALITY) { + + if (result1.type == DataType::NUL && result2.type == DataType::NUL) + { + result.boolValue = true; + } + else if (result1.type != result2.type) + { + result.boolValue = false; + } + else if (result1.type == DataType::ARRAY && result2.type == DataType::ARRAY) + { + if (result1.arrayValue->ArrayContent.size()==result2.arrayValue->ArrayContent.size()){ + for (size_t i = 0; i < result1.arrayValue->ArrayContent.size(); i++){ + // if (result1.arrayValue->ArrayContent.at(i)->value.type != result2.arrayValue->ArrayContent.at(i)->value.type + // || result1.arrayValue->ArrayContent.at(i)->value.value != result2.arrayValue->ArrayContent.at(i)->value.value) + // { + // result.boolValue = false; + // return ""; + // } + if (result1.arrayValue->ArrayContent.at(i)->value.type== TokenType::NUMBER) { + if (result1.arrayValue->ArrayContent.at(i)->value.value != result2.arrayValue->ArrayContent.at(i)->value.value){ + result.boolValue = false; + return ""; + } + } + if (result1.arrayValue->ArrayContent.at(i)->value.type== TokenType::TRUE || result1.arrayValue->ArrayContent.at(i)->value.type== TokenType::FALSE){ + if (result1.arrayValue->ArrayContent.at(i)->value.value != result2.arrayValue->ArrayContent.at(i)->value.value){ + result.boolValue = false; + return ""; + } + } + } + result.boolValue = true; + } + else {result.boolValue = false;} + } + else + { + if (result1.type == DataType::DOUBLE) + { result.boolValue = result1.doubleValue == result2.doubleValue; } + else if (result1.type == DataType::BOOL) + { result.boolValue = result1.boolValue == result2.boolValue; } + else + { std::cout << "Something's wrong == comparison"; } + } + } + // != + else if (expressionNode->value.type == TokenType::INEQUALITY) { + if (result1.type == DataType::NUL && result2.type == DataType::NUL) + { + result.boolValue = false; + } + else if (result1.type != result2.type) + { + result.boolValue = true; + } + else if (result1.type == DataType::ARRAY && result2.type == DataType::ARRAY) + { + if (result1.arrayValue->ArrayContent.size()==result2.arrayValue->ArrayContent.size()){ + for (size_t i = 0; i < result1.arrayValue->ArrayContent.size(); i++){ + if (result1.arrayValue->ArrayContent.at(i)->value.type == result2.arrayValue->ArrayContent.at(i)->value.type + && result1.arrayValue->ArrayContent.at(i)->value.value == result2.arrayValue->ArrayContent.at(i)->value.value) + { + result.boolValue = false; + return ""; + } + } + result.boolValue = true; + } + else {result.boolValue = true;} + } + else + { + if (result1.type == DataType::DOUBLE) + { result.boolValue = result1.doubleValue != result2.doubleValue; } + else if (result1.type == DataType::BOOL) + { result.boolValue = result1.boolValue != result2.boolValue; } + else + { std::cout << "Something's wrong == comparison"; } + } + } } - currentLine += 1; + return ""; } } - + return ""; } -std::string ParserB::calculate(Node root, double& result) +void ParserB::print(Node* root, int indent, bool semicolon) { - // number - if (root.value.type == TokenType::number) + for (int i=0; ivalue.type == TokenType::DEF) { - result = root.value.value; - return ""; - } + FunctionDefineNode* functionDefineRoot = dynamic_cast(root); - // variable - else if (root.value.type == TokenType::variable) - { - if (variableInitializedMap.find(root.value.content) == variableInitializedMap.end()) + std::cout << "def "; + std::cout << functionDefineRoot->functionName; + std::cout << "("; + for (int i = 0; i < (int)functionDefineRoot->parameterNames.size(); i++) + { + std::cout << functionDefineRoot->parameterNames[i]; + if (i != (int)functionDefineRoot->parameterNames.size()-1) + { + std::cout << ", "; + } + } + std::cout << ") "; + std::cout << "{" << std::endl; + for (int i=0; i < (int)functionDefineRoot->flows.size(); i++) { - return "Runtime error: unknown identifier " + root.value.content; + print(functionDefineRoot->flows[i].get(), indent + 1); + std::cout << std::endl; } - result = variableMap.at(root.value.content); - return ""; + + for (int i=0; i < indent; i++) { std::cout << " "; } + std::cout << "}"; } + // While + else if (root->value.type == TokenType::WHILE) + { + WhileNode* whileRoot = dynamic_cast(root); - // = - else if (root.value.type == TokenType::equals) + std::cout << "while "; + print(whileRoot->condition.get(), 0, false); + std::cout << " {" << std::endl; + for (int i=0;i < (int)whileRoot->flows.size(); i++) + { + print(whileRoot->flows[i].get(), indent + 1); + std::cout << std::endl; + } + for (int i=0; ivalue.type == TokenType::IF) { - // the last child must be a number or an initialized variable - Node last = root.children[root.children.size()-1]; - if (last.value.type == TokenType::variable && variableInitializedMap.find(last.value.content) == variableInitializedMap.end()) + IfNode* ifRoot = dynamic_cast(root); + + // if + std::cout << "if "; + print(ifRoot->conditions[0].get(), 0, false); + std::cout << " {" << std::endl; + for (int i=0 ; i < (int)ifRoot->flowGroups[0].size(); i++) { - return "Runtime error: unknown identifier " + last.value.content; + print(ifRoot->flowGroups[0][i].get(), indent + 1); + std::cout << std::endl; } + for (int i=0; iconditions.size(); conditionIndex++) + { + std::cout << std::endl; + for (int i=0; iconditions[conditionIndex].get(), 0, false); + std::cout << " {" << std::endl; + for (int i=0; i < (int)ifRoot->flowGroups[conditionIndex].size(); i++) + { + print(ifRoot->flowGroups[conditionIndex][i].get(), indent + 1); + std::cout << std::endl; + } + for (int a=0; aconditions.size() != ifRoot->flowGroups.size()) { - variableMap.at(root.children[i].value.content) = result; - variableInitializedMap.at(root.children[i].value.content) = true; + std::cout << std::endl; + for (int i=0; iflowGroups[ifRoot->flowGroups.size()-1].size(); i++) + { + print(ifRoot->flowGroups[ifRoot->flowGroups.size()-1][i].get(), indent + 1); + std::cout << std::endl; + } + for (int i=0; ivalue.type == TokenType::PRINT) + { + PrintNode* printRoot = dynamic_cast(root); - return ""; + std::cout << "print "; + if (printRoot->content2 != nullptr) { + print(printRoot->content2.get(), 0, false); + } + else { + print(printRoot->content.get(), 0, false); + } + std::cout << ";"; } + // Return + else if (root->value.type == TokenType::RETURN) + { + ReturnNode* returnRoot = dynamic_cast(root); - // + - * / - else { - // variable for operation is uninitialaized - if (root.children[0].value.type == TokenType::variable && variableInitializedMap.at(root.children[0].value.content) == false) + std::cout << "return"; + if (returnRoot->content != nullptr) { + std::cout << " "; + print(returnRoot->content.get(), 0, false); + std::cout << ";"; + } + else { + std::cout << ";"; + } + } + // Array + else if (root->value.type == TokenType::ARRAY) + { + ArrayNode * ArrayRoot = dynamic_cast(root); + if ( ArrayRoot->value.content != "") { + std::cout << "(" << ArrayRoot->value.content << " = "; + } + std::cout << "["; + for(size_t i = 0; i < ArrayRoot->ArrayContent.size(); i++) { + print(ArrayRoot->ArrayContent[i].get(), 0, false); + if (i+1 < ArrayRoot->ArrayContent.size()) { + std::cout << ", "; + } + } + std::cout << "]"; + if ( ArrayRoot->value.content != "") { + std::cout << ");"; + } + } + // only Array without assignment + else if (root->value.type == TokenType::LEFT_BRACKET && root->EqualityIndex == -1 ){ + // std::cout << "r" << std::endl; + ArrayNode * ArrayRoot = dynamic_cast(root); + std::cout << "["; + for(size_t i = 0; i < ArrayRoot->ArrayContent.size(); i++) { + print(ArrayRoot->ArrayContent[i].get(), 0, false); + if (i+1 < ArrayRoot->ArrayContent.size()) { + std::cout << ", "; + } + } + // check if there is lookup + if (ArrayRoot->lookUp == true) { - return "Runtime error: unknown identifier " + root.children[0].value.content; + if (ArrayRoot->LookUpNode.size()!=0) { + // std::cout << "RUN" <LookUpNode.at(0).get(), 0 , false); + } + else if (ArrayRoot->lookUpIndex != -1) { + std::cout << "][" << ArrayRoot->lookUpIndex; + } + else { + std::cout << "][" << ArrayRoot->lookUpStr; + } } + if (semicolon == false) { std::cout << "]"; } + else { std::cout << "];"; } + } + // array equality + else if (root->EqualityIndex != -1) + { + ArrayNode * ArrayRoot = dynamic_cast(root); + std::cout << "("; + if (ArrayRoot->ArrayContent[0]->ArrayContent.size()==0) { + std::cout << ArrayRoot->ArrayContent[0]->value.content; + } + else + { + print(ArrayRoot->ArrayContent[0].get()); + } + std::cout <<" " <value.content << " "; + if (ArrayRoot->ArrayContent[1]->ArrayContent.size()==0) { - std::string errorMessage = calculate(root.children[0], result); - if (errorMessage != "") { return errorMessage; } - + std::cout << ArrayRoot->ArrayContent[1]->value.content; + } + else + { + print(ArrayRoot->ArrayContent[1].get()); + } + std::cout << ")"; + // std::cout << "yes" << std::endl; + } + // ExpressionNode + else + { + ExpressionNode* expressionNode = dynamic_cast(root); + if (expressionNode->value.type == TokenType::NUMBER){ - for (int i = 1; i < (int)root.children.size(); i++) + } + if (expressionNode->value.type == TokenType::NUL) { - // variable for operation is uninitialaized - if (root.children[i].value.type == TokenType::variable && variableInitializedMap.at(root.children[i].value.content) == false) + std::cout << "null"; + } + else if (expressionNode->value.type == TokenType::NUMBER) + { + int v = floor(expressionNode->value.value); + // 1000.000 -> 1000 + if ((double)v == expressionNode->value.value) + { std::cout << v; } + else + { std::cout << expressionNode->value.content; } + } + else if (expressionNode->value.type == TokenType::VARIABLE) + { + // Function Call + if (expressionNode->children.size() != 0 && expressionNode->ArrayLookUp == false) { - return "Runtime error: unknown identifier " + root.children[i].value.content; + print(expressionNode->children[0].get(), 0, false); + std::cout << "("; + for (int i = 1; i < (int)expressionNode->children.size(); i++) + { + print(expressionNode->children[i].get(), 0, false); + if (i != (int)expressionNode->children.size() - 1) + { + std::cout << ", "; + } + } + std::cout << ")"; + if (semicolon) { std::cout << ";"; } } - else if (root.value.type == TokenType::plus) { - double r; - std::string errorMessage = calculate(root.children[i], r); - if (errorMessage != "") { return errorMessage; } - result += r; + // len() pop() push() + else if (expressionNode->IsFunction == true && expressionNode->ArrayLookUp == false) + { + // len() + if (expressionNode->value.content == "len") + { + std::cout << "len("; + if (expressionNode->children2.size()!=0) + { + if (expressionNode->children2[0]->value.type == TokenType::VARIABLE) + { + // std::cout << expressionNode->children2[0]->value.content << ", "; + // std::cout << expressionNode->children2[1]->value.content; + for (int i = 0; i < (int)expressionNode->children2.size(); i++) + { + std::cout << expressionNode->children2[i]->value.content; + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << ", "; + } + } + } + else + { + print(expressionNode->children2[0].get(), 0, false); + } + } + if (semicolon == true) {std::cout << ");";} + else {std::cout << ")";} + } + // pop() + else if (expressionNode->value.content == "pop") + { + std::cout << "pop("; + if (expressionNode->children2.size()!=0) + { + if (expressionNode->children2[0]->value.type == TokenType::VARIABLE) + { + // std::cout << expressionNode->children2[0]->value.content << ", "; + // std::cout << expressionNode->children2[1]->value.content; + for (int i = 0; i < (int)expressionNode->children2.size(); i++) + { + std::cout << expressionNode->children2[i]->value.content; + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << ", "; + } + } + } + else + { + print(expressionNode->children2[0].get(), 0, false); + } + } + if (semicolon == true) {std::cout << ");";} + else {std::cout << ")";} + } + // push() + else if (expressionNode->value.content == "push") + { + std::cout << "push("; + + for (int i = 0; i < (int)expressionNode->children2.size(); i++) + { + if (expressionNode->children2[i]->value.type == TokenType::VARIABLE) + { + std::cout << expressionNode->children2[i]->value.content; + } + else + { + print(expressionNode->children2[i].get(), 0, false); + } + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << ", "; + } + } + + if (semicolon == true) {std::cout << ");";} + else {std::cout << ")";} + } + } - else if (root.value.type == TokenType::minus) { - double r; - std::string errorMessage = calculate(root.children[i], r); - if (errorMessage != "") { return errorMessage; } - result -= r; + // Array + else if (expressionNode->ArrayLookUp == true) { + if (expressionNode->children.size()!= 0) { + std::cout << expressionNode->value.content << "["; + print(expressionNode->children[0].get(), 0, false); + std::cout << "]"; + } + else if (expressionNode->index!=-1) + { + std::cout << expressionNode->value.content << "[" << expressionNode->index << "]"; + } + else if (expressionNode->lookUpStr != "") + { + std::cout << expressionNode->value.content << "[" << expressionNode->lookUpStr << "]"; + } } - else if (root.value.type == TokenType::multiply) { - double r; - std::string errorMessage = calculate(root.children[i], r); - if (errorMessage != "") { return errorMessage; } - result *= r; + + // Normal Variable + else + { + std::cout << expressionNode->value.content; + } + } + else if (expressionNode->value.type == TokenType::TRUE) + { + std::cout << expressionNode->value.content; + } + else if (expressionNode->value.type == TokenType::FALSE) + { + std::cout << expressionNode->value.content; + } + else { + std::cout << "("; + for (int i = 0; i < (int)expressionNode->children.size(); i++) + { + print(expressionNode->children[i].get(), 0, false); + if (i != (int)expressionNode->children.size() - 1) + { + std::cout << " " << expressionNode->value.content << " "; + } } - else if (root.value.type == TokenType::divide) + for (int i = 0; i < (int)expressionNode->children2.size(); i++) { - double r; - std::string errorMessage = calculate(root.children[i], r); - if (errorMessage != "") { return errorMessage; } - if (r == 0) { - return "Runtime error: division by zero."; + print(expressionNode->children2[i].get(), 0, false); + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << " " << expressionNode->value.content << " "; } - result /= r; } + std::cout << ")"; + if (semicolon) { std::cout << ";"; } } - return ""; } } - -void ParserB::print(Node root) +void ParserB::printValue(Result& value) { - if (root.value.type == TokenType::number) + + // if (value.print == false) {return;} + // std::cout << (value.type == DataType::ARRAY) << std::endl; + if (value.type == DataType::NUL) { - int v = floor(root.value.value); - // 1000.000 -> 1000 - if ((double)v == root.value.value) - { - std::cout << v; - } - else - { - std::cout << root.value.content; - } + std::cout << "null"; } - else if (root.value.type == TokenType::variable) + + else if (value.type == DataType::BOOL) { - std::cout << root.value.content; + if (value.boolValue == 0) { std::cout << "false"; } + else { std::cout << "true"; } } - else { - std::cout << "("; - for (int i = 0; i < (int)root.children.size(); i++) - { - print(root.children[i]); - if (i != (int)root.children.size() - 1) + + else if (value.type == DataType::DOUBLE) + { + std::cout << value.doubleValue; + } + + else if (value.type == DataType::ARRAY) + { + // std::cout << value.arrayValue->ArrayContent.size() << std::endl; + std::cout << "["; + for (size_t i = 0; i < value.arrayValue->ArrayContent.size(); i++) + { + // std::cout << value.arrayValue->ArrayContent[i]->value.content <ArrayContent[i]->value.type == TokenType::NUMBER) { - std::cout << " " << root.value.content << " "; + std::cout << value.arrayValue->ArrayContent[i]->value.value; + } + else if (value.arrayValue->ArrayContent[i]->value.type == TokenType::ARRAY || value.arrayValue->ArrayContent[i]->value.type == TokenType::LEFT_BRACKET) + { + Result curr; + curr.type = DataType::ARRAY; + + curr.arrayValue = value.arrayValue->ArrayContent.at(i); + // curr.arrayValue->value.type = ; + printValue(curr); + // std::cout << "[5]"; + } + else if (value.arrayValue->ArrayContent[i]->value.type == TokenType::NUL) + { + std::cout <<"null"; + } + else{ + // std::cout << 3 << std::endl; + std::cout << value.arrayValue->ArrayContent[i]->value.content; + } + if (i+1< value.arrayValue->ArrayContent.size()) { + std::cout << ", "; } } - std::cout << ")"; + std::cout << "]"; + } + + else + { + std::cout << "There is something wrong PrintValue" << std::endl; + std::cout << (value.type == DataType::FUNCTION) << std::endl; + std::cout << (value.type == DataType::NUL) << std::endl; + std::cout << (value.type == DataType::UNINITIALIZED) << std::endl; + std::cout << "There is something wrong PrintValue" << std::endl; + // std::cout <<"null"; } } @@ -472,8 +2283,9 @@ int ParserB::findRightParenthesisNoError(std::vector expression, int left int balance = 1; int p = leftBound; while (p <= rightBound) { - if (expression[p].type == TokenType::leftParenthesis) { balance += 1; } - if (expression[p].type == TokenType::rightParenthesis) { balance -= 1; } + if (expression[p].type == TokenType::LEFT_PARENTHESIS || expression[p].type == TokenType::LEFT_BRACKET) { balance += 1; } + else if (expression[p].type == TokenType::RIGHT_PARENTHESIS || expression[p].type == TokenType::RIGHT_BRACKET) { balance -= 1; } + if (balance == 0) { break; } p += 1; } @@ -486,68 +2298,202 @@ int ParserB::findRightBracketNoError(std::vector expression, int leftBoun int balance = 1; int p = leftBound; while (p <= rightBound) { - if (expression[p].type == TokenType::leftParenthesis) { balance += 1; } - if (expression[p].type == TokenType::rightParenthesis) { balance -= 1; } + if (expression[p].type == TokenType::LEFT_BRACKET) { balance += 1; } + else if (expression[p].type == TokenType::RIGHT_BRACKET) { balance -= 1; } + if (balance == 0) { break; } p += 1; } return p; } - -// return vectors of lines in infix notation -// register variables in map -void ParserB::setupExpressionInfix(std::vector expression) +// exclude left brace +// it also can find bracket no error +int ParserB::findRightBraceNoError(std::vector expression, int leftBound, int rightBound) { - if (expression.size() == 1) - { -#if DEBUG - std::cout << "-1 empty expression" << std::endl; -#endif + int balance = 1; + int p = leftBound; + while (p <= rightBound) { + if (expression[p].type == TokenType::LEFT_BRACE || expression[p].type == TokenType::LEFT_BRACKET) { balance += 1; } + else if (expression[p].type == TokenType::RIGHT_BRACE || expression[p].type == TokenType::RIGHT_BRACKET) { balance -= 1; } - std::cout << "Unexpected token at line " << 1 << " column " << 1 << ": " << "END" << std::endl; - exit(2); + if (balance == 0) { break; } + p += 1; } + return p; +} + +// void ParserB::setupExpression(std::vector& expression, int leftBound, int rightBound, ) +void ParserB::setupExpression(std::vector& expression) +{ + auto& variableTypeMap = ScopeStack.top()->variableTypeMap; + for (int i = 0; i < (int)expression.size()-1; i++) { Token token = expression[i]; // handle new variable - if (token.type == TokenType::variable) + if (variableTypeMap.find(token.content) == variableTypeMap.end() && token.type == TokenType::VARIABLE) { - if (variableMap.find(token.content) == variableMap.end()) - { - variableMap.insert({ token.content, -1 }); - variableInitializedMap.insert({ token.content, false }); + variableTypeMap[token.content] = DataType::UNINITIALIZED; + } + } +} + +void ParserB::getVariable(std::string& variableName, Result& result, int index) { + auto& variableTypeMap = ScopeStack.top()->variableTypeMap; + auto& variableDoubleMap = ScopeStack.top()->variableDoubleMap; + auto& variableBoolMap = ScopeStack.top()->variableBoolMap; + auto& variableFunctionMap = ScopeStack.top()->variableFunctionMap; + auto& variableArrayMap = ScopeStack.top()->variableArrayMap; + result.type = variableTypeMap[variableName]; + + if (index != -1) + { + if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::NUMBER) + { + result.type = DataType::DOUBLE; + result.doubleValue = variableArrayMap[variableName]->ArrayContent.at(index)->value.value; + } + else if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::TRUE || + variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::FALSE) + { + result.type = DataType::BOOL; + result.boolValue = variableArrayMap[variableName]->ArrayContent.at(index)->value.value; + } + else if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::ARRAY || + variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::LEFT_BRACKET) + { + result.type = DataType::ARRAY; + + result.arrayValue = std::make_unique(variableArrayMap[variableName]->ArrayContent.at(index)->value); + result.arrayValue->lookUp = variableArrayMap[variableName]->ArrayContent.at(index)->lookUp; + result.arrayValue->lookUpStr = variableArrayMap[variableName]->ArrayContent.at(index)->lookUpStr; + result.arrayValue->lookUpIndex = variableArrayMap[variableName]->ArrayContent.at(index)->lookUpIndex; + for (auto element : variableArrayMap[variableName]->ArrayContent.at(index)->ArrayContent){ + result.arrayValue->ArrayContent.push_back(element); } } + else if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::NUL) + { + result.type = DataType::NUL; + } + return; + } + + if (variableTypeMap.at(variableName) == DataType::ARRAY) + { + result.arrayValue = variableArrayMap[variableName]; + return; + } + + if (result.type == DataType::NUL) + { + + } + else if (result.type == DataType::DOUBLE) + { + result.doubleValue = variableDoubleMap[variableName]; + } + else if (result.type == DataType::BOOL) + { + result.boolValue = variableBoolMap[variableName]; + } + else if (result.type == DataType::FUNCTION) + { + result.function = variableFunctionMap[variableName]; + } + else if (result.type == DataType::ARRAY) + { + result.arrayValue = variableArrayMap[variableName]; + } + else + { + // std::cout << (result.type == DataType::NUL) << std::endl; + // std::cout << (result.type == DataType::UNINITIALIZED) << std::endl; + std::cout << "There is a problem getVariable" << std::endl; } } +void ParserB::setVariable(std::string& variableName, Result& result, int index) { + auto& variableTypeMap = ScopeStack.top()->variableTypeMap; + auto& variableDoubleMap = ScopeStack.top()->variableDoubleMap; + auto& variableBoolMap = ScopeStack.top()->variableBoolMap; + auto& variableFunctionMap = ScopeStack.top()->variableFunctionMap; + auto& variableArrayMap = ScopeStack.top()->variableArrayMap; + + if (index != -1) { + // if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::NUMBER) + if (result.type == DataType::DOUBLE) + { + variableArrayMap[variableName]->ArrayContent.at(index)->value.type = TokenType::NUMBER; + // result.type = DataType::DOUBLE; + variableArrayMap[variableName]->ArrayContent.at(index)->value.value = result.doubleValue; + } + // else if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::TRUE || + // variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::FALSE) + else if (result.type == DataType::BOOL) + { + // result.type = DataType::BOOL; + variableArrayMap[variableName]->ArrayContent.at(index)->value.type = TokenType::TRUE; + variableArrayMap[variableName]->ArrayContent.at(index)->value.value = result.boolValue; + } + // else if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::ARRAY || + // variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::LEFT_BRACKET) + else if (result.type == DataType::ARRAY) + { + // result.type = DataType::ARRAY; + + // result.arrayValue = std::make_unique(variableArrayMap[variableName]->ArrayContent.at(index)->value); + // result.arrayValue->lookUp = variableArrayMap[variableName]->ArrayContent.at(index)->lookUp; + // result.arrayValue->lookUpStr = variableArrayMap[variableName]->ArrayContent.at(index)->lookUpStr; + // result.arrayValue->lookUpIndex = variableArrayMap[variableName]->ArrayContent.at(index)->lookUpIndex; + // for (auto element : variableArrayMap[variableName]->ArrayContent.at(index)->ArrayContent){ + // result.arrayValue->ArrayContent.push_back(element); + // } + + variableArrayMap[variableName]->ArrayContent.at(index) = result.arrayValue; + + } + // else if (variableArrayMap[variableName]->ArrayContent.at(index)->value.type == TokenType::NUL) + else if (result.type == DataType::NUL) + { + // result.type = DataType::NUL; + variableArrayMap[variableName]->ArrayContent.at(index)->value.type = TokenType::NUL; + + variableArrayMap[variableName]->ArrayContent.at(index)->value.content = "null"; + } + return; + } + variableTypeMap[variableName] = result.type; + + if (result.type == DataType::NUL) + { -// std::string ParserB::Checkerror(Node root, bool &result){ // only check whether all variable have value or will it be assigned value in the expression -// for (size_t i =0; ivalue.content << std::endl; + variableArrayMap[variableName] = result.arrayValue; + // if (variableName == "arref") { + // variableArrayMap[variableName]->ArrayContent.at(1)->value.value = -1; + // } + } + else + { + std::cout << "There is a problem setVariable" << std::endl; + } +} \ No newline at end of file diff --git a/src/lib/ParserB.h b/src/lib/ParserB.h index 2f0bf31..45f95bf 100644 --- a/src/lib/ParserB.h +++ b/src/lib/ParserB.h @@ -6,37 +6,406 @@ #include #include #include +#include +#include +#include "DataType.h" #include "Lexer.h" -#include "Utils.h" +#include "Scope.h" +#include "Function.h" +#include "ASTNode.h" -class Node -{ +class Result { public: - Node() : value(Token(TokenType::none, "", -1, -1, -1)) {} - Node(Token token) : value(token) {} - - std::vector children; - Token value; + DataType type; + bool isreturn = false; + std::shared_ptr function; + std::shared_ptr arrayValue; + union { + double doubleValue; + bool boolValue; + }; }; class ParserB { public: - static std::pair, std::string> MakeTreeInfix(std::vector expression, int leftBound, int rightBound, Node& node); - static std::string calculate(Node root, double& result); - static void print(Node root); - static void setupExpression(std::vector expression); - static void setupExpressionInfix(std::vector expression); - static std::vector> expressionLines; - static std::map variableMap; - static std::map variableInitializedMap; + static std::pair, std::string> HandleTokenVector(std::vector tokenVector, int leftBound, int rightBound, std::vector>& nodes); + static std::pair, std::string> MakeExpressionTree(std::vector expression, int leftBound, int rightBound, std::unique_ptr& node); + static std::pair, std::string> HandleArray(std::vector tokenVector, int leftBound, int rightBound,std::unique_ptr& node , int index = -1); + static std::string calculate(Node* root, Result& result); + static void print(Node* root, int indent = 0, bool semicolon = true); + static void printValue(Result& result); + static void setupExpression(std::vector& expression); + static void getVariable(std::string& variableName, Result& result, int index = -1); + static void setVariable(std::string& variableName, Result& result, int index = -1); + static int findRightParenthesisNoError(std::vector expression, int leftBound, int rightBound); + static int findRightBracketNoError(std::vector expression, int leftBound, int rightBound); + static int findRightBraceNoError(std::vector expression, int leftBound, int rightBound); + static std::stack ScopeStack; static std::map hierarchyMap; + static std::vector> functionStorage; + + static void clean() + { + for (int i=0; i < (int)functionStorage.size(); i++) + { + delete functionStorage[i]->m_CaptureScope; + } + } + + + +static void print_no_semicolon(Node* root, int indent=0) +{ + for (int i=0; ivalue.type == TokenType::DEF) + { + FunctionDefineNode* functionDefineRoot = dynamic_cast(root); + + std::cout << "def "; + std::cout << functionDefineRoot->functionName; + std::cout << "("; + for (int i = 0; i < (int)functionDefineRoot->parameterNames.size(); i++) + { + std::cout << functionDefineRoot->parameterNames[i]; + if (i != (int)functionDefineRoot->parameterNames.size()-1) + { + std::cout << ", "; + } + } + std::cout << ") "; + std::cout << "{" << std::endl; + for (int i=0; i < (int)functionDefineRoot->flows.size(); i++) + { + print(functionDefineRoot->flows[i].get(), indent + 1); + std::cout << std::endl; + } + + for (int i=0; i < indent; i++) { std::cout << " "; } + std::cout << "}"; + } + // While + else if (root->value.type == TokenType::WHILE) + { + WhileNode* whileRoot = dynamic_cast(root); + + std::cout << "while "; + print(whileRoot->condition.get(), 0, false); + std::cout << " {" << std::endl; + for (int i=0;i < (int)whileRoot->flows.size(); i++) + { + print(whileRoot->flows[i].get(), indent + 1); + std::cout << std::endl; + } + for (int i=0; ivalue.type == TokenType::IF) + { + IfNode* ifRoot = dynamic_cast(root); + + // if + std::cout << "if "; + print(ifRoot->conditions[0].get(), 0, false); + std::cout << " {" << std::endl; + for (int i=0 ; i < (int)ifRoot->flowGroups[0].size(); i++) + { + print(ifRoot->flowGroups[0][i].get(), indent + 1); + std::cout << std::endl; + } + for (int i=0; iconditions.size(); conditionIndex++) + { + std::cout << std::endl; + for (int i=0; iconditions[conditionIndex].get(), 0, false); + std::cout << " {" << std::endl; + for (int i=0; i < (int)ifRoot->flowGroups[conditionIndex].size(); i++) + { + print(ifRoot->flowGroups[conditionIndex][i].get(), indent + 1); + std::cout << std::endl; + } + for (int a=0; aconditions.size() != ifRoot->flowGroups.size()) + { + std::cout << std::endl; + for (int i=0; iflowGroups[ifRoot->flowGroups.size()-1].size(); i++) + { + print(ifRoot->flowGroups[ifRoot->flowGroups.size()-1][i].get(), indent + 1); + std::cout << std::endl; + } + for (int i=0; ivalue.type == TokenType::PRINT) + { + PrintNode* printRoot = dynamic_cast(root); + + std::cout << "print "; + print(printRoot->content.get(), 0, false); + } + // Return + else if (root->value.type == TokenType::RETURN) + { + ReturnNode* returnRoot = dynamic_cast(root); + + std::cout << "return "; + print(returnRoot->content.get()); + } + // Array + else if (root->value.type == TokenType::ARRAY) + { + ArrayNode * ArrayRoot = dynamic_cast(root); + if ( ArrayRoot->value.content != "") { + std::cout << "(" << ArrayRoot->value.content << " = "; + } + std::cout << "["; + for(size_t i = 0; i < ArrayRoot->ArrayContent.size(); i++) { + print(ArrayRoot->ArrayContent[i].get(), 0, false); + if (i+1 < ArrayRoot->ArrayContent.size()) { + std::cout << ", "; + } + } + std::cout << "]"; + if ( ArrayRoot->value.content != "") { + std::cout << ")"; + } + } + // only Array without assignment + else if (root->value.type == TokenType::LEFT_BRACKET && root->EqualityIndex == -1){ + ArrayNode * ArrayRoot = dynamic_cast(root); + std::cout << "["; + for(size_t i = 0; i < ArrayRoot->ArrayContent.size(); i++) { + print(ArrayRoot->ArrayContent[i].get(), 0, false); + if (i+1 < ArrayRoot->ArrayContent.size()) { + std::cout << ", "; + } + } + // check if there is lookup + if (ArrayRoot->lookUp == true) + { + if (ArrayRoot->LookUpNode.size()!=0) { + // std::cout << "RUN" <LookUpNode.at(0).get(), 0 , false); + } + else if (ArrayRoot->lookUpIndex != -1) { + std::cout << "][" << ArrayRoot->lookUpIndex; + } + else { + std::cout << "][" << ArrayRoot->lookUpStr; + } + } + std::cout << "]"; + } + + else if (root->EqualityIndex != -1) + { + ArrayNode * ArrayRoot = dynamic_cast(root); + std::cout << "("; + if (ArrayRoot->ArrayContent[0]->ArrayContent.size()==0) { + std::cout << ArrayRoot->ArrayContent[0]->value.content; + } + else + { + print(ArrayRoot->ArrayContent[0].get()); + } + std::cout <<" " <value.content << " "; + if (ArrayRoot->ArrayContent[1]->ArrayContent.size()==0) { + + std::cout << ArrayRoot->ArrayContent[1]->value.content; + } + else + { + print(ArrayRoot->ArrayContent[1].get()); + } + std::cout << ")"; + // std::cout << "yes" << std::endl; + } + // ExpressionNode + else + { + ExpressionNode* expressionNode = dynamic_cast(root); + if (expressionNode->value.type == TokenType::NUL) + { + std::cout << "null"; + } + else if (expressionNode->value.type == TokenType::NUMBER) + { + int v = floor(expressionNode->value.value); + // 1000.000 -> 1000 + if ((double)v == expressionNode->value.value) + { std::cout << v; } + else + { std::cout << expressionNode->value.content; } + } + else if (expressionNode->value.type == TokenType::VARIABLE) + { + // Function Call + if (expressionNode->children.size() != 0 && expressionNode->ArrayLookUp == false) + { + print(expressionNode->children[0].get(), 0, false); + std::cout << "("; + for (int i = 1; i < (int)expressionNode->children.size(); i++) + { + print(expressionNode->children[i].get(), 0, false); + if (i != (int)expressionNode->children.size() - 1) + { + std::cout << ", "; + } + } + std::cout << ")"; + } + // len() pop() push() + else if (expressionNode->IsFunction == true && expressionNode->ArrayLookUp == false) + { + // len() + if (expressionNode->value.content == "len") + { + std::cout << "len("; + if (expressionNode->children2.size()!=0) + { + if (expressionNode->children2[0]->value.type == TokenType::VARIABLE) + { + // std::cout << expressionNode->children2[0]->value.content; + for (int i = 0; i < (int)expressionNode->children2.size(); i++) + { + std::cout << expressionNode->children2[i]->value.content; + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << ", "; + } + } + } + else + { + print_no_semicolon(expressionNode->children2[0].get(), 0); + } + } + std::cout << ")"; + } + // pop() + else if (expressionNode->value.content == "pop") + { + std::cout << "pop("; + if (expressionNode->children2.size()!=0) + { + if (expressionNode->children2[0]->value.type == TokenType::VARIABLE) + { + // std::cout << expressionNode->children2[0]->value.content; + for (int i = 0; i < (int)expressionNode->children2.size(); i++) + { + std::cout << expressionNode->children2[i]->value.content; + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << ", "; + } + } + } + else + { + print_no_semicolon(expressionNode->children2[0].get(), 0); + } + } + std::cout << ")"; + } + // push() + else if (expressionNode->value.content == "push") + { + std::cout << "push("; + + for (int i = 0; i < (int)expressionNode->children2.size(); i++) + { + if (expressionNode->children2[i]->value.type == TokenType::VARIABLE) + { + std::cout << expressionNode->children2[i]->value.content; + } + else + { + print(expressionNode->children2[i].get(), 0, false); + } + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << ", "; + } + } + + + std::cout << ")"; + } + + } + else if (expressionNode->ArrayLookUp == true) { + if (expressionNode->children.size()!= 0) { + std::cout << expressionNode->value.content << "["; + print(expressionNode->children[0].get(), 0, false); + std::cout << "]"; + } + else if (expressionNode->index!=-1) + { + std::cout << expressionNode->value.content << "[" << expressionNode->index << "]"; + } + else if (expressionNode->lookUpStr != "") + { + std::cout << expressionNode->value.content << "[" << expressionNode->lookUpStr << "]"; + } + else { + std::cout << "ERROR" << std::endl; + } + } + // Normal Variable + else + { + std::cout << expressionNode->value.content; + } + } + else if (expressionNode->value.type == TokenType::TRUE) + { + std::cout << expressionNode->value.content; + } + else if (expressionNode->value.type == TokenType::FALSE) + { + std::cout << expressionNode->value.content; + } + else { + std::cout << "("; + for (int i = 0; i < (int)expressionNode->children.size(); i++) + { + print(expressionNode->children[i].get(), 0, false); + if (i != (int)expressionNode->children.size() - 1) + { + std::cout << " " << expressionNode->value.content << " "; + } + } + for (int i = 0; i < (int)expressionNode->children2.size(); i++) + { + print(expressionNode->children2[i].get(), 0, false); + if (i != (int)expressionNode->children2.size() - 1) + { + std::cout << " " << expressionNode->value.content << " "; + } + } + std::cout << ")"; + } + } +} private: - static int findLeftParenthesis(std::vector expression, int leftBound, int rightBound); - static int findRightParenthesis(std::vector expression, int leftBound, int rightBound); - static int findRightParenthesisNoError(std::vector expression, int leftBound, int rightBound); }; diff --git a/src/lib/Scope.h b/src/lib/Scope.h new file mode 100644 index 0000000..b788201 --- /dev/null +++ b/src/lib/Scope.h @@ -0,0 +1,121 @@ +#pragma once + +#include +#include +#include "DataType.h" +#include "ASTNode.h" + +class Function; + +class Scope +{ +public: + Scope() + : variableTypeMap(), variableDoubleMap(), variableBoolMap() + , variableFunctionMap(), variableArrayMap() + {} + + // Copy constructor + Scope(const Scope& other) + : variableTypeMap(other.variableTypeMap), variableDoubleMap(other.variableDoubleMap), + variableBoolMap(other.variableBoolMap), variableFunctionMap(other.variableFunctionMap), variableArrayMap(other.variableArrayMap) + {} + + ~Scope() + { + for (auto& pair : variableFunctionMap) { + pair.second.reset(); + } + // std::cout << "Scope is deleted" << std::endl; + } + + // Copy assignment operator + Scope& operator=(const Scope& other) { + if (this != &other) { + // Implement the assignment logic here + // Be sure to handle any dynamic resources properly + variableTypeMap = other.variableTypeMap; + variableDoubleMap = other.variableDoubleMap; + variableBoolMap = other.variableBoolMap; + variableFunctionMap = other.variableFunctionMap; + } + return *this; + } + + void OverwriteBy(Scope& other) + { + for (std::pair kv : other.variableTypeMap) + { + std::string variableName = kv.first; + variableTypeMap[variableName] = other.variableTypeMap[variableName]; + + if (other.variableTypeMap[variableName] == DataType::NUL) + { + + } + else if (other.variableTypeMap[variableName] == DataType::UNINITIALIZED) + { + + } + else if (other.variableTypeMap[variableName] == DataType::DOUBLE) + { + variableDoubleMap[variableName] = other.variableDoubleMap[variableName]; + } + else if (other.variableTypeMap[variableName] == DataType::BOOL) + { + variableBoolMap[variableName] = other.variableBoolMap[variableName]; + } + else if (other.variableTypeMap[variableName] == DataType::FUNCTION) + { + variableFunctionMap[variableName] = other.variableFunctionMap[variableName]; + } + else + { + // std::cout << variableName << std::endl; + // std::cout << "There is a problem overwrite scope" << std::endl; + } + } + } + + void print() + { + std::cout << "======================" << std::endl; + for (std::pair kv : variableTypeMap) + { + std::string variableName = kv.first; + + if (variableTypeMap[variableName] == DataType::NUL) + { + std::cout << variableName << " null" << std::endl; + } + else if (variableTypeMap[variableName] == DataType::UNINITIALIZED) + { + std::cout << variableName << " uninitialized" << std::endl; + } + else if (variableTypeMap[variableName] == DataType::DOUBLE) + { + std::cout << variableName << " double " << variableDoubleMap[variableName] << std::endl; + } + else if (variableTypeMap[variableName] == DataType::BOOL) + { + std::cout << variableName << " bool " << variableBoolMap[variableName] << std::endl; + } + else if (variableTypeMap[variableName] == DataType::FUNCTION) + { + std::cout << variableName << " function " << std::endl; + } + else + { + // std::cout << variableName << std::endl; + // std::cout << "There is a problem overwrite scope" << std::endl; + } + } + std::cout << "--------------------" << std::endl; + } + + std::map variableTypeMap; + std::map variableDoubleMap; + std::map variableBoolMap; + std::map> variableFunctionMap; + std::map> variableArrayMap; +}; \ No newline at end of file diff --git a/src/lib/Utils.cpp b/src/lib/Utils.cpp deleted file mode 100644 index 89df160..0000000 --- a/src/lib/Utils.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "Utils.h" - - -void hint(std::vector expression, std::vector> expressionLines, int checkIndex, - int line, int index, std::string content) -{ - if (expression[checkIndex].line == line && expression[checkIndex].index == index && expression[checkIndex].content == content) - { - for (std::vector v : expressionLines) - { - for (Token token : v) - { - std::cout << token.content << " "; - } - std::cout << std::endl; - } - } -} diff --git a/src/lib/Utils.h b/src/lib/Utils.h deleted file mode 100644 index 12f0180..0000000 --- a/src/lib/Utils.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "Lexer.h" - -#define DEBUG 1 -#define HINT 0 - -void hint(std::vector expression, std::vector> expressionLines, int checkIndex, - int line=1, int index=7, std::string content="89"); - -// git add * -// git commit -m "Checkpoint2 partA finished" -// git push origin Michael - -// g++ -Wall -Wextra -Werror -std=c++17 parse.cpp -o main lib/Parser.cpp lib/Lexer.cpp \ No newline at end of file diff --git a/src/lib/main b/src/lib/main new file mode 100644 index 0000000..9c01bdc Binary files /dev/null and b/src/lib/main differ diff --git a/src/scrypt.cpp b/src/scrypt.cpp index e69de29..20cbc1a 100644 --- a/src/scrypt.cpp +++ b/src/scrypt.cpp @@ -0,0 +1,125 @@ +#include "lib/ParserB.h" + + +int main() { +#if DEBUG == 0 + std::string input = ""; + std::string line; + + while(!std::cin.eof()) { + char c; + std::cin.get(c); + line = std::string(1, c); + input += line; + } + input = input.substr(0, input.size()-1); +#endif +#if DEBUG == 1 + +// std::string input = R"(x = 42 +// steps = 0 + +// while x > 1 { +// steps = steps + 1 +// if x % 2 == 0 { +// x = x / 2 +// } +// else { +// x = 3 * x + 1 +// } +// } + +// print steps)"; + + +// std::string input = R"( +// def foo(x, y) { +// })" +// ; + + + std::string input = R"( +(z = 42); +def foo(x, y) { + def square(value) { + return (value * value); + } + print square(((x + y) + z)); +} +(z = 108); +(f = foo); +(result = f(1, 2)); +if (result != null) { + print result; +} + +def p() { + print 114514; + return; +} +print p(); + + +def add(a) { + if (a <= 1) { + return a; + } + return a * add(a-1); +} + +print add(5); + )"; + + + + +#endif + + // Lexer + std::vector TokenVector; + std::pair errorPair = Token::GenTokenVector(input, TokenVector); + if (errorPair.first != -1) + { + std::cout << "Syntax error on line " << errorPair.first << " column " << errorPair.second << "." << std::endl; + exit(1); + } + // Token::printLexer(TokenVector); + + // Parser + // Add the global Scope + Scope* globalScope = new Scope(); + ParserB::ScopeStack.push(globalScope); + ParserB::setupExpression(TokenVector); + std::vector> flows; + std::pair, std::string> errorResult = ParserB::HandleTokenVector(TokenVector, 0, TokenVector.size()-2, flows); + if (errorResult.first.first != -1) + { + std::cout << "Unexpected token at line " << errorResult.first.first << " column " << errorResult.first.second << ": " << errorResult.second << std::endl; + exit(2); + } + + // for (int i=0; i < (int)flows.size(); i++) + // { + // ParserB::print(flows[i].get()); + // std::cout << std::endl; + // } + + // Calculate + // std::cout << "start calculating" << std::endl; + for (int i=0; i < (int)flows.size(); i++) + { + Result result; + std::string errorMessage = ParserB::calculate(flows[i].get(), result); + + if (errorMessage.length() != 0) + { + std::cout << errorMessage << std::endl; + exit(3); + } + } + + // std::cout << ParserB::functionStorage.size() << std::endl; + ParserB::clean(); + delete globalScope; + return 0; +} diff --git a/src/test.cpp b/src/test.cpp new file mode 100644 index 0000000..b5c4a18 --- /dev/null +++ b/src/test.cpp @@ -0,0 +1,92 @@ +#include "lib/Lexer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +class Function; + +class Scope +{ +public: + Scope() + : variableFunctionMap() + { + std::cout << "scope is created" << std::endl; + } + + ~Scope() + { + for (auto& pair : variableFunctionMap) { + pair.second.reset(); + } + std::cout << "Scope is deleted" << std::endl; + } + + Scope(const Scope& other) + : variableFunctionMap(other.variableFunctionMap) + { + std::cout << "scope copied" << std::endl; + } + + Scope& operator=(const Scope& other) { + if (this != &other) { + variableFunctionMap = other.variableFunctionMap; + } + return *this; + } + + std::map> variableFunctionMap; +}; + + +class Function +{ +public: + Function() + { + std::cout << "Function is created" << std::endl; + }; + + ~Function() + { + // for (auto& pair : m_CaptureScope.variableFunctionMap) { + // pair.second.reset(); + // } + // delete m_CaptureScope; + std::cout << "Function is deleted" << std::endl; + } + + Scope* m_CaptureScope; +}; + + +static std::stack ScopeStack; + +int main() { + // Add a Function inside globalScope + Scope* globalScope = new Scope(); + ScopeStack.push(globalScope); + + std::shared_ptr function = std::make_shared(); + globalScope->variableFunctionMap["add"] = function; + // map 里面有一个pointer指向function + + function->m_CaptureScope = new Scope(*globalScope); + // function 里面有一个pointer指向 scope, scope 里有个 map, map 里面有一个 pointer 指向 function + + delete function->m_CaptureScope; + std::cout << "1111" << std::endl; + delete globalScope; + std::cout << "2222" << std::endl; + + + + return 0; +} \ No newline at end of file