From 0635aa8a257f195137f347fe6a4964c70ec96d59 Mon Sep 17 00:00:00 2001 From: Digit16 Date: Sat, 9 Nov 2024 14:14:08 +0100 Subject: [PATCH 1/3] Adjust to work with Godot --- interpreter/CodeInterpreter.cpp | 42 ++++++++++++--------------------- interpreter/CodeInterpreter.h | 5 +++- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/interpreter/CodeInterpreter.cpp b/interpreter/CodeInterpreter.cpp index 9347452..33bfa8e 100644 --- a/interpreter/CodeInterpreter.cpp +++ b/interpreter/CodeInterpreter.cpp @@ -2,26 +2,36 @@ #include #include "CodeInterpreter.h" -#include "src/GlobalScope.h" - void CodeInterpreter::_bind_methods() { ClassDB::bind_method(D_METHOD("interpret"), &CodeInterpreter::interpret); ClassDB::bind_method(D_METHOD("getVariable"), &CodeInterpreter::getVariable); - ClassDB::bind_method(D_METHOD("getGlobalScope"), &CodeInterpreter::getGlobalScope); } void CodeInterpreter::interpret(const String& str) { std::string text{str.utf8().get_data()}; - std::shared_ptr result = Interpreter::interpret(text); + //std::shared_ptr result = Interpreter::interpret(text); + + std::shared_ptr tree = interpreter.buildTree(text); + + st::SymbolTable& stRef = interpreter.symbolTable(); + SymbolTableBuilder stb; + stb.build(tree, stRef); + + std::shared_ptr result = interpreter.interpret(tree); } String CodeInterpreter::getVariable(const String& str) { std::string text{str.utf8().get_data()}; std::stringstream ssOut; + using namespace st; + try { - std::variant value = GLOBAL_SCOPE.at(text); // TODO: Handle exception + auto variable = interpreter.symbolTable().findWithType(text, SymbolType::VARIABLE_SYMBOL); // TODO: Handle exception + auto variableSymbol = std::dynamic_pointer_cast(variable); + + std::variant value = variableSymbol->getValue(); if (std::holds_alternative(value)) { int intValue = std::get(value); @@ -49,26 +59,4 @@ String CodeInterpreter::getVariable(const String& str) { return String("Error"); } -} - -Dictionary CodeInterpreter::getGlobalScope() { - - Dictionary dict{}; - - for (auto const& [key, value] : GLOBAL_SCOPE) { - String strKey = String(key.c_str()); - - if (std::holds_alternative(value)) { - dict[strKey] = std::get(value); - } else if (std::holds_alternative(value)) { - dict[strKey] = std::get(value); - } else if (std::holds_alternative(value)) { - dict[strKey] = std::get(value); - } else { - std::cout << "Unknown variant" << std::endl; - } - } - - return dict; - } \ No newline at end of file diff --git a/interpreter/CodeInterpreter.h b/interpreter/CodeInterpreter.h index 14c69a7..d90f313 100644 --- a/interpreter/CodeInterpreter.h +++ b/interpreter/CodeInterpreter.h @@ -10,8 +10,11 @@ class CodeInterpreter : public RefCounted, public Interpreter { protected: static void _bind_methods(); public: + void interpret(const String& str); String getVariable(const String& str); - Dictionary getGlobalScope(); + +private: + Interpreter interpreter; }; From 757f4133d8606acc55c0f797e4c08e9c2e164410 Mon Sep 17 00:00:00 2001 From: Wiktor Kubski Date: Fri, 15 Nov 2024 15:04:46 +0000 Subject: [PATCH 2/3] Add seq --- interpreter/CodeInterpreter.cpp | 136 ++++++++++++++++++++------------ interpreter/CodeInterpreter.h | 18 +++-- interpreter/grammar.cfg | 6 +- interpreter/main.cpp | 12 +++ interpreter/src/Ast.cpp | 10 +++ interpreter/src/Ast.h | 21 ++++- interpreter/src/Interpreter.cpp | 83 ++++++++++++++----- interpreter/src/Interpreter.h | 117 +++++++++++---------------- interpreter/src/Lexer.cpp | 38 +++++++-- interpreter/src/Lexer.h | 7 ++ interpreter/src/Parser.cpp | 25 +++++- interpreter/src/Parser.h | 17 +--- interpreter/src/Token.cpp | 2 + interpreter/src/Token.h | 9 ++- 14 files changed, 326 insertions(+), 175 deletions(-) diff --git a/interpreter/CodeInterpreter.cpp b/interpreter/CodeInterpreter.cpp index 33bfa8e..2186bf9 100644 --- a/interpreter/CodeInterpreter.cpp +++ b/interpreter/CodeInterpreter.cpp @@ -1,62 +1,94 @@ +#include "CodeInterpreter.h" + #include #include -#include "CodeInterpreter.h" +void CodeInterpreter::_bind_methods() +{ + ClassDB::bind_method(D_METHOD("registerBuiltInMethod"), &CodeInterpreter::registerBuiltInMethod); + ClassDB::bind_method(D_METHOD("interpret"), &CodeInterpreter::interpret); + ClassDB::bind_method(D_METHOD("getVariable"), &CodeInterpreter::getVariable); + ClassDB::bind_method(D_METHOD("getSequence"), &CodeInterpreter::getSequence); +} + +void CodeInterpreter::registerBuiltInMethod(const String& str); +{ + const std::string text{str.utf8().get_data()}; -void CodeInterpreter::_bind_methods() { - ClassDB::bind_method(D_METHOD("interpret"), &CodeInterpreter::interpret); - ClassDB::bind_method(D_METHOD("getVariable"), &CodeInterpreter::getVariable); + interpreter.registerBuiltInMethod(text); } -void CodeInterpreter::interpret(const String& str) { - std::string text{str.utf8().get_data()}; - //std::shared_ptr result = Interpreter::interpret(text); - - std::shared_ptr tree = interpreter.buildTree(text); +String CodeInterpreter::interpret(const String& str) +{ + try { + const std::string text{str.utf8().get_data()}; + + interpreter.symbolTable().init(); + interpreter.initParser(input); + + interpreter.registerBuiltInMethod("moveNorth()"); + interpreter.registerBuiltInMethod("moveSouth()"); + interpreter.registerBuiltInMethod("moveEast()"); + interpreter.registerBuiltInMethod("moveWest()"); + interpreter.registerBuiltInMethod("rotateLeft()"); + interpreter.registerBuiltInMethod("rotateRight()"); + interpreter.registerBuiltInMethod("push()"); + + std::shared_ptr tree = interpreter.buildTree(text); + + st::SymbolTable& stRef = interpreter.symbolTable(); + SymbolTableBuilder stb; + stb.build(tree, stRef); - st::SymbolTable& stRef = interpreter.symbolTable(); - SymbolTableBuilder stb; - stb.build(tree, stRef); + std::shared_ptr result = interpreter.interpret(tree); - std::shared_ptr result = interpreter.interpret(tree); + return String(); + } catch (const std::exception& e) { + return String(e.what()); + } } -String CodeInterpreter::getVariable(const String& str) { - std::string text{str.utf8().get_data()}; - std::stringstream ssOut; - - using namespace st; - - try { - auto variable = interpreter.symbolTable().findWithType(text, SymbolType::VARIABLE_SYMBOL); // TODO: Handle exception - auto variableSymbol = std::dynamic_pointer_cast(variable); - - std::variant value = variableSymbol->getValue(); - - if (std::holds_alternative(value)) { - int intValue = std::get(value); - std::cout << "Int value" << intValue << std::endl; - ssOut << intValue; - } else if (std::holds_alternative(value)) { - float floatValue = std::get(value); - std::cout << "Float value" << floatValue << std::endl; - ssOut << floatValue; - } else if (std::holds_alternative(value)) { - bool boolValue = std::get(value); - std::cout << "Bool value" << boolValue << std::endl; - ssOut << boolValue; - } else { - std::cout << "Unknown variant" << std::endl; - ssOut << "Unknown variant"; - } - - std::string sOut = ssOut.str(); - return String(sOut.c_str()); - - - } catch (const std::exception& e) { - std::cout << e.what() << std::endl; - return String("Error"); - } - -} \ No newline at end of file +String CodeInterpreter::getVariable(const String& str) +{ + const std::string variableName{str.utf8().get_data()}; + std::stringstream ssOut; + + try { + std::variant value = interpreter.getVariableVariant(variableName); + + if (std::holds_alternative(value)) { + int intValue = std::get(value); + std::cout << "Int value" << intValue << std::endl; + ssOut << intValue; + } else if (std::holds_alternative(value)) { + float floatValue = std::get(value); + std::cout << "Float value" << floatValue << std::endl; + ssOut << floatValue; + } else if (std::holds_alternative(value)) { + bool boolValue = std::get(value); + std::cout << "Bool value" << boolValue << std::endl; + ssOut << boolValue; + } else { + std::cout << "Unknown variant" << std::endl; + ssOut << "Unknown variant"; + } + + std::string sOut = ssOut.str(); + return String(sOut.c_str()); + + } catch (const std::exception& e) { + std::cout << e.what() << std::endl; + return String("Error"); + } +} + +Array CodeInterpreter::getSequence() +{ + Array array; + std::vector seq = interpreter.getSequence(); + for (const auto& instruction : seq) { + array.append(String(instruction.c_str())); + } + + return array; +} diff --git a/interpreter/CodeInterpreter.h b/interpreter/CodeInterpreter.h index d90f313..ed9becb 100644 --- a/interpreter/CodeInterpreter.h +++ b/interpreter/CodeInterpreter.h @@ -1,20 +1,22 @@ #pragma once -#include "src/Interpreter.h" #include "core/object/ref_counted.h" #include "core/variant/dictionary.h" +#include "src/Interpreter.h" -class CodeInterpreter : public RefCounted, public Interpreter { +class CodeInterpreter : public RefCounted, public Interpreter +{ GDCLASS(CodeInterpreter, RefCounted); protected: static void _bind_methods(); + public: - - void interpret(const String& str); - String getVariable(const String& str); - + void registerBuiltInMethod(const String& str); + String interpret(const String& str); + String getVariable(const String& str); + Array getSequence(); + private: - Interpreter interpreter; - + Interpreter interpreter; }; diff --git a/interpreter/grammar.cfg b/interpreter/grammar.cfg index ba4a3bf..6bf5683 100644 --- a/interpreter/grammar.cfg +++ b/interpreter/grammar.cfg @@ -10,8 +10,8 @@ section : START statementList END statement : section | assignmentStatement | ifStatement - | variableDeclaration | functionDeclaration | functionCall - | whileLoop | forLoop | empty + | variableDeclaration | functionDeclaration | builtInFunction + | functionCall | whileLoop | forLoop | empty statementList : statement | statement SEMI statementList @@ -20,6 +20,8 @@ variableDeclaration : (TYPE | auto) ID (ASSIGN expression)? variable : ID + + builtInFunction : builtInFunction functionDeclaration : FUN ID LPAREN RPAREN COLON section diff --git a/interpreter/main.cpp b/interpreter/main.cpp index 0f9cc27..eaabb75 100644 --- a/interpreter/main.cpp +++ b/interpreter/main.cpp @@ -50,6 +50,18 @@ int main(int argc, char* argv[]) } Interpreter interpreter; + + interpreter.symbolTable().init(); + interpreter.initParser(input); + + interpreter.registerBuiltInMethod("moveNorth()"); + interpreter.registerBuiltInMethod("moveSouth()"); + interpreter.registerBuiltInMethod("moveEast()"); + interpreter.registerBuiltInMethod("moveWest()"); + interpreter.registerBuiltInMethod("rotateLeft()"); + interpreter.registerBuiltInMethod("rotateRight()"); + interpreter.registerBuiltInMethod("push()"); + std::shared_ptr tree = interpreter.buildTree(input); st::SymbolTable& stRef = interpreter.symbolTable(); diff --git a/interpreter/src/Ast.cpp b/interpreter/src/Ast.cpp index 2759487..625fd38 100644 --- a/interpreter/src/Ast.cpp +++ b/interpreter/src/Ast.cpp @@ -107,6 +107,14 @@ NodeVariant getVariant(const std::shared_ptr& node) return NodeVariant(ForLoop(*forAst)); } + case NodeType::BUILT_IN_FUNCTION: { + auto builtInFunction = std::dynamic_pointer_cast(node); + if (!builtInFunction) { + throw std::runtime_error("Casting to BuiltInFunction failed"); + } + + return NodeVariant(BuiltInFunction(*builtInFunction)); + } } throw std::runtime_error("Unknown NodeType"); @@ -141,6 +149,8 @@ std::string getTypeString(NodeType nt) return "WHILE"; case NodeType::FOR: return "FOR"; + case NodeType::BUILT_IN_FUNCTION: + return "BUILT_IN_FUNCTION"; } throw std::runtime_error("Unknown NodeType"); diff --git a/interpreter/src/Ast.h b/interpreter/src/Ast.h index 1853a7c..798eb8f 100644 --- a/interpreter/src/Ast.h +++ b/interpreter/src/Ast.h @@ -16,6 +16,7 @@ class VariableDeclaration; class Variable; class EmptyNode; class FunDeclaration; +class BuiltInFunction; class FunCall; class IfStatement; class WhileLoop; @@ -30,6 +31,7 @@ using NodeVariant = std::variant _body; }; +class BuiltInFunction : public AstNode +{ +public: + BuiltInFunction(const std::string& name) : + _name(name) + { + } + + NodeType nodeType() const override { return NodeType::BUILT_IN_FUNCTION; } + + const std::string& name() const { return _name; } + +private: + std::string _name; +}; + NodeVariant getVariant(const std::shared_ptr& node); std::string getTypeString(NodeType nt); diff --git a/interpreter/src/Interpreter.cpp b/interpreter/src/Interpreter.cpp index 635c538..440c5b0 100644 --- a/interpreter/src/Interpreter.cpp +++ b/interpreter/src/Interpreter.cpp @@ -2,7 +2,6 @@ #include -// using NodeVisitor = InterpreterNodeVisitor::VisitNode; using NodeVisitor = Interpreter::VisitNode; using stNodeVisitor = SymbolTableVisitNode; @@ -46,8 +45,29 @@ void st::SymbolTable::init() create(std::make_shared("BOOL_VALUE", SymbolVariableType::BOOL_VALUE)); } +void st::SymbolTable::registerBuiltInMethod(const std::string& functionName) +{ + create(std::make_shared(functionName)); +} + +void st::SymbolTable::addToSequence(const std::string& functionName) +{ + _sequence.push_back(functionName); +} + +std::vector st::SymbolTable::sequence() +{ + return _sequence; +} + void st::SymbolTable::debugPrint() { + std::cout << "Sequence:" << std::endl; + for (size_t i = 0; i < _sequence.size(); ++i) { + std::cout << i << ": " << _sequence[i] << std::endl; + } + std::cout << "End of sequence" << std::endl; + for (const auto& [symbolName, symbolPtr] : _symbols) { if (!symbolPtr) continue; @@ -198,6 +218,16 @@ void stNodeVisitor::operator()(FunDeclaration& node) st.create(std::make_shared(functionName, node.body())); } +void stNodeVisitor::operator()(BuiltInFunction& node) +{ + const std::string functionName = node.name(); + + if (!st.find(functionName)) { + const std::string errorMessage = "Function '" + functionName + "' does not exists"; + throw std::runtime_error(errorMessage); + } +} + void stNodeVisitor::operator()(FunCall& node) { const std::string functionName = node.name(); @@ -422,8 +452,6 @@ std::shared_ptr NodeVisitor::operator()(Assign& node) throw std::runtime_error("Casting to variableSymbolType in VisitAssign failed!"); } - std::cout << "right() node type in visit Assign: " << static_cast(node.right()->nodeType()) << std::endl; - std::string valueTypeName; auto flexValue = value->value(); @@ -444,7 +472,7 @@ std::shared_ptr NodeVisitor::operator()(Assign& node) return std::make_shared(); } -std::shared_ptr NodeVisitor::operator()(VariableDeclaration& /*node*/) +std::shared_ptr NodeVisitor::operator()(VariableDeclaration&) { return std::make_shared(); } @@ -496,15 +524,14 @@ std::shared_ptr NodeVisitor::operator()(IfStatement& node) } } -std::shared_ptr NodeVisitor::operator()(FunDeclaration& /*node*/) +std::shared_ptr NodeVisitor::operator()(FunDeclaration&) { - // const std::string& functionName = node.name(); - // auto symbol = symbolTable().findWithType(functionName, st::SymbolType::FUNCTION_SYMBOL); - // auto functionSymbol = std::dynamic_pointer_cast(symbol); - - // std::variant& value = functionSymbol->getValue(); + return std::make_shared(); +} - // GLOBAL_FUNCTIONS[node.name()] = node.body(); +std::shared_ptr NodeVisitor::operator()(BuiltInFunction& node) +{ + symbolTable().addToSequence(node.name()); return std::make_shared(); } @@ -559,7 +586,8 @@ std::shared_ptr NodeVisitor::operator()(ForLoop& node) } bool conditionIsTrue = (std::holds_alternative(conditionValue->value()) && std::get(conditionValue->value()) != 0) - || (std::holds_alternative(conditionValue->value()) && std::get(conditionValue->value()) != 0.0f); + || (std::holds_alternative(conditionValue->value()) && std::get(conditionValue->value()) != 0.0f) + || (std::holds_alternative(conditionValue->value()) && std::get(conditionValue->value()) == true); if (!conditionIsTrue) { break; @@ -579,14 +607,19 @@ std::shared_ptr Interpreter::visitInterpret(NodeVariant astNode, st::Sy return std::visit(VisitNode(st), astNode); } -std::shared_ptr Interpreter::buildTree(const std::string& text) +void Interpreter::registerBuiltInMethod(const std::string& functionName) { - reset(); - - _symbolTable.init(); + symbolTable().registerBuiltInMethod(functionName); + _parser.registerBuiltInMethod(functionName); +} - _parser = Parser(Lexer(text)); +std::vector Interpreter::getSequence() +{ + return symbolTable().sequence(); +} +std::shared_ptr Interpreter::buildTree(const std::string& text) +{ return _parser.parse(); } @@ -595,17 +628,27 @@ std::shared_ptr Interpreter::interpret(std::shared_ptr tree) return Interpreter::visitInterpret(getVariant(tree), symbolTable()); } -void Interpreter::reset() +void Interpreter::initParser(const std::string& input) { - GLOBAL_SCOPE.clear(); - GLOBAL_FUNCTIONS.clear(); + _parser = Parser(Lexer(input)); +} +void Interpreter::reset() +{ _executionLine = -1; _executionPosition = -1; _parser = Parser(); } +std::variant Interpreter::getVariableVariant(const std::string& variableName) +{ + auto variable = this->symbolTable().findWithType(variableName, st::SymbolType::VARIABLE_SYMBOL); // TODO: Handle exception + auto variableSymbol = std::dynamic_pointer_cast(variable); + + return variableSymbol->getValue(); +} + // static FlexNumber Interpreter::calculateBinaryResult(st::SymbolTable& st, const std::shared_ptr& left, diff --git a/interpreter/src/Interpreter.h b/interpreter/src/Interpreter.h index d9e64a0..e80df93 100644 --- a/interpreter/src/Interpreter.h +++ b/interpreter/src/Interpreter.h @@ -20,8 +20,9 @@ enum class SymbolType : uint8_t { SYMBOL = 0, BUILT_IN_TYPE_SYMBOL = 1, - VARIABLE_SYMBOL = 2, - FUNCTION_SYMBOL = 3 + BUILT_IN_FUNCTION_SYMBOL = 2, + VARIABLE_SYMBOL = 3, + FUNCTION_SYMBOL = 4 }; class Symbol @@ -36,7 +37,6 @@ class Symbol virtual SymbolType symbolType() { return SymbolType::SYMBOL; } - // protected: std::string _name; }; @@ -51,10 +51,20 @@ class BuiltInTypeSymbol : public Symbol SymbolType symbolType() override { return SymbolType::BUILT_IN_TYPE_SYMBOL; } - // protected: SymbolVariableType _type; }; +class BuiltInFunctionSymbol : public Symbol +{ +public: + BuiltInFunctionSymbol(const std::string& symbolName) : + Symbol(symbolName) + { + } + + SymbolType symbolType() override { return SymbolType::BUILT_IN_TYPE_SYMBOL; } +}; + class VariableSymbol : public Symbol { public: @@ -86,17 +96,9 @@ class FunctionSymbol : public Symbol std::vector>& body() { return _function; } - // protected: - // std::string _functionName; std::vector> _function; }; -// class FunctionCallSymbol : public Symbol -// { -// protected: -// std::shared_ptr _functionToCall; -// }; - class SymbolTable { public: @@ -108,59 +110,37 @@ class SymbolTable void init(); + void registerBuiltInMethod(const std::string& functionName); + + void addToSequence(const std::string& functionName); + + std::vector sequence(); + void debugPrint(); private: std::map> _symbols; + std::vector _sequence; }; } // namespace st -// class InterpreterNodeVisitor -// { -// public: -// struct VisitNode -// { -// VisitNode(st::SymbolTable& st) : -// _st(st) -// { -// } -// ~VisitNode() = default; - -// std::shared_ptr operator()(BinaryOperation& node); -// std::shared_ptr operator()(Number& node); -// std::shared_ptr operator()(UnaryOp& node); -// std::shared_ptr operator()(Section& node); -// std::shared_ptr operator()(Assign& node); -// std::shared_ptr operator()(VariableDeclaration& node); -// std::shared_ptr operator()(Variable& node); -// std::shared_ptr operator()(EmptyNode& node); -// std::shared_ptr operator()(FunDeclaration& node); -// std::shared_ptr operator()(FunCall& node); -// std::shared_ptr operator()(IfStatement& node); -// std::shared_ptr operator()(WhileLoop& node); -// std::shared_ptr operator()(ForLoop& node); - -// st::SymbolTable& _st; -// }; - -// static std::shared_ptr visitInterpret(NodeVariant astNode); - -// static int calculateUnaryResult(const std::shared_ptr& node, TokenType op); -// static FlexNumber calculateBinaryResult(const std::shared_ptr& left, const std::shared_ptr& right, TokenType type); -// }; - -class Interpreter /* : public InterpreterNodeVisitor*/ +class Interpreter { public: + void registerBuiltInMethod(const std::string& functionName); + + std::vector getSequence(); + std::shared_ptr buildTree(const std::string& text); std::shared_ptr interpret(std::shared_ptr tree); + void initParser(const std::string& input); + void reset(); - std::map>& getGlobalScope() { return GLOBAL_SCOPE; } - std::unordered_map>>& getGlobalFunctions() { return GLOBAL_FUNCTIONS; } + std::variant getVariableVariant(const std::string& varialeName); void raiseExecutionError(uint16_t currentLine, int16_t currentPositon = -1) const; @@ -183,6 +163,7 @@ class Interpreter /* : public InterpreterNodeVisitor*/ std::shared_ptr operator()(Variable& node); std::shared_ptr operator()(EmptyNode& node); std::shared_ptr operator()(FunDeclaration& node); + std::shared_ptr operator()(BuiltInFunction& node); std::shared_ptr operator()(FunCall& node); std::shared_ptr operator()(IfStatement& node); std::shared_ptr operator()(WhileLoop& node); @@ -203,8 +184,6 @@ class Interpreter /* : public InterpreterNodeVisitor*/ private: st::SymbolTable _symbolTable; - std::map> GLOBAL_SCOPE; - std::unordered_map>> GLOBAL_FUNCTIONS; uint16_t _executionPosition; uint16_t _executionLine; @@ -216,11 +195,6 @@ class SymbolTableBuilder { public: void build(std::shared_ptr tree, st::SymbolTable& st); - - // st::SymbolTable& symbolTable() { return _symbolTable; } - - // protected: - // st::SymbolTable& _symbolTable; }; class SymbolTableVisitNode @@ -232,21 +206,22 @@ class SymbolTableVisitNode } ~SymbolTableVisitNode() = default; - void operator()(BinaryOperation& node /*, st::SymbolTable& st*/); - void operator()(Number& node /*, st::SymbolTable& st*/); - void operator()(UnaryOp& node /*, st::SymbolTable& st*/); - void operator()(Section& node /*, st::SymbolTable& st*/); - void operator()(Assign& node /*, st::SymbolTable& st*/); - void operator()(VariableDeclaration& node /*, st::SymbolTable& st*/); - void operator()(Variable& node /*, st::SymbolTable& st*/); - void operator()(EmptyNode& node /*, st::SymbolTable& st*/); - void operator()(FunDeclaration& node /*, st::SymbolTable& st*/); - void operator()(FunCall& node /*, st::SymbolTable& st*/); - void operator()(IfStatement& node /*, st::SymbolTable& st*/); - void operator()(WhileLoop& node /*, st::SymbolTable& st*/); - void operator()(ForLoop& node /*, st::SymbolTable& st*/); - - void visit(NodeVariant astNode /*, st::SymbolTable& st*/); + void operator()(BinaryOperation& node); + void operator()(Number& node); + void operator()(UnaryOp& node); + void operator()(Section& node); + void operator()(Assign& node); + void operator()(VariableDeclaration& node); + void operator()(Variable& node); + void operator()(EmptyNode& node); + void operator()(FunDeclaration& node); + void operator()(BuiltInFunction& node); + void operator()(FunCall& node); + void operator()(IfStatement& node); + void operator()(WhileLoop& node); + void operator()(ForLoop& node); + + void visit(NodeVariant astNode); std::variant evaluateExpression(const std::shared_ptr node); std::string getTokenTypeFromVariant(std::variant variant); diff --git a/interpreter/src/Lexer.cpp b/interpreter/src/Lexer.cpp index e1289c7..72b2ce2 100644 --- a/interpreter/src/Lexer.cpp +++ b/interpreter/src/Lexer.cpp @@ -2,6 +2,16 @@ #include +void Lexer::registerBuiltInMethod(const std::string& functionName) +{ + auto [it, res] = _builtInMethods.insert(functionName); + if (res) { + std::cout << "success" << std::endl; + } else { + std::cout << "lypton" << std::endl; + } +} + void Lexer::advance() { ++_pos; @@ -150,9 +160,15 @@ char Lexer::peekNextChar() return this->_text[this->_pos + 1]; } -Token Lexer::id() +std::map Lexer::getReservedKeywords() { - std::string result; + if (_builtInMethods.empty()) { + std::cout << "chuj bombki szczelyl" << std::endl; + } + for (const auto& fun : _builtInMethods) { + std::cout << fun << std::endl; + } + std::map RESERVED_KEYWORDS{ {"START", Token("START", TokenType::START) }, {"END", Token("END", TokenType::END) }, @@ -164,9 +180,21 @@ Token Lexer::id() {"while", Token("while", TokenType::WHILE) } }; - while (this->_currentChar != '\0' && isalnum(this->_currentChar)) { - result += this->_currentChar; - this->advance(); + for (const auto& fun : _builtInMethods) { + RESERVED_KEYWORDS[fun] = Token(fun, TokenType::BUILT_IN_FUNCTION); + } + + return RESERVED_KEYWORDS; +} + +Token Lexer::id() +{ + std::string result; + std::map RESERVED_KEYWORDS = getReservedKeywords(); + + while (_currentChar != '\0' && (isalnum(_currentChar) || _currentChar == '(' || _currentChar == ')')) { + result += _currentChar; + advance(); } if (RESERVED_KEYWORDS.count(result)) { diff --git a/interpreter/src/Lexer.h b/interpreter/src/Lexer.h index b5018bf..fba033f 100644 --- a/interpreter/src/Lexer.h +++ b/interpreter/src/Lexer.h @@ -3,6 +3,7 @@ #include "Token.h" #include +#include class Lexer { @@ -28,6 +29,8 @@ class Lexer { } + void registerBuiltInMethod(const std::string& functionName); + void raiseInvalidCharacterError() const { throw std::runtime_error("Invalid character"); } void advance(); @@ -48,11 +51,15 @@ class Lexer int16_t getParsingLine() { return _parsingLine; } int16_t getParsingPosition() { return _parsingPosition; } + std::map getReservedKeywords(); + private: std::string _text; int _pos; char _currentChar; + std::set _builtInMethods; + int16_t _parsingLine; int16_t _parsingPosition; }; diff --git a/interpreter/src/Parser.cpp b/interpreter/src/Parser.cpp index 1ab957f..5b4d2ee 100644 --- a/interpreter/src/Parser.cpp +++ b/interpreter/src/Parser.cpp @@ -2,6 +2,11 @@ #include +void Parser::registerBuiltInMethod(const std::string& functionName) +{ + _lexer.registerBuiltInMethod(functionName); +} + void Parser::raiseParsingError(const std::vector& expectedTokenType) { if (expectedTokenType.empty()) { @@ -76,9 +81,11 @@ std::shared_ptr Parser::factor() } else { raiseParsingError({TokenType::PLUS, TokenType::MINUS, TokenType::INTEGER, TokenType::FLOATING_NUMBER, TokenType::LPAREN, TokenType::ID}); } + + return std::make_shared(); } /* - term : factor ((MUL | DIV) factor)* +term : factor ((MUL | DIV) factor)* */ std::shared_ptr Parser::term() { @@ -164,6 +171,7 @@ statement : section | ifStatement | variableDeclaration | functionDeclaration + | builtInFunction | functionCall | whileLoop | forLoop @@ -189,6 +197,8 @@ std::shared_ptr Parser::statement() } } else if (_currentToken.getType() == TokenType::FUN_DECLARATION) { return functionDeclaration(); + } else if (_currentToken.getType() == TokenType::BUILT_IN_FUNCTION) { + return builtInFunction(); } else { return empty(); } @@ -272,7 +282,7 @@ std::shared_ptr Parser::ifStatement() auto condition = expr(); eat(TokenType::COLON); auto thenBranch = section(); - std::shared_ptr elseBranch = nullptr; + std::shared_ptr elseBranch = std::make_shared(); if (_currentToken.getType() == TokenType::ELSE) { eat(TokenType::ELSE); @@ -329,6 +339,17 @@ std::shared_ptr Parser::whileStatement() return std::make_shared(condition, body); } +/* +builtInFunction : builtInFunction +*/ +std::shared_ptr Parser::builtInFunction() +{ + auto ct = _currentToken; + eat(TokenType::BUILT_IN_FUNCTION); + + return std::make_shared(ct.getStringValue()); +} + /* forStatement : FOR LPAREN variableDeclaration SEMICOLON expr SEMICOLON assignmentStatement RPAREN section */ diff --git a/interpreter/src/Parser.h b/interpreter/src/Parser.h index 99e5970..3c6801e 100644 --- a/interpreter/src/Parser.h +++ b/interpreter/src/Parser.h @@ -21,6 +21,8 @@ class Parser { } + void registerBuiltInMethod(const std::string& functionName); + void raiseParsingError(const std::vector& expectedTokenType); void eat(TokenType tokenType); @@ -55,6 +57,8 @@ class Parser std::shared_ptr functionCall(); + std::shared_ptr builtInFunction(); + std::shared_ptr whileStatement(); std::shared_ptr forStatement(); @@ -62,19 +66,6 @@ class Parser Lexer lexer() { return _lexer; } private: - // class ParsingException : public std::exception - // { - // private: - // const char* message; - - // public: - // ParsingException(const char* msg) : - // message(msg) - // { - // } - // char* what() { return message; } - // }; - Lexer _lexer; Token _currentToken; }; diff --git a/interpreter/src/Token.cpp b/interpreter/src/Token.cpp index 1c77e02..5b62cfb 100644 --- a/interpreter/src/Token.cpp +++ b/interpreter/src/Token.cpp @@ -68,6 +68,8 @@ std::string Token::typeToString(TokenType type) return "VARIABLE_DECLARATION"; case TokenType::FUN_DECLARATION: return "FUN_DECLARATION"; + case TokenType::BUILT_IN_FUNCTION: + return "BUILT_IN_FUNCTION"; } throw std::runtime_error("TokenType not implemented, string conversion is not possible"); diff --git a/interpreter/src/Token.h b/interpreter/src/Token.h index e97ad53..6c15817 100644 --- a/interpreter/src/Token.h +++ b/interpreter/src/Token.h @@ -39,7 +39,8 @@ enum class TokenType : uint8_t LESS_EQUAL = 31, NEWLINE = 32, VARIABLE_DECLARATION = 33, - FUN_DECLARATION = 34 + FUN_DECLARATION = 34, + BUILT_IN_FUNCTION = 35 }; class Token @@ -49,6 +50,12 @@ class Token static constexpr std::array comparisonTokenTypes{ TokenType::COMPARISON, TokenType::NOT_EQUAL, TokenType::GREATER, TokenType::LESS, TokenType::GREATER_EQUAL, TokenType::LESS_EQUAL}; + Token() : + _value(std::nullptr_t()), + _type(TokenType::NONE) + { + } + Token(std::variant value, TokenType type) : _value(value), _type(type){}; From 55d24993bba20b5112bd32ac23e68cd8b4a971b3 Mon Sep 17 00:00:00 2001 From: Wiktor Kubski Date: Fri, 15 Nov 2024 15:22:16 +0000 Subject: [PATCH 3/3] Build fix --- interpreter/CodeInterpreter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interpreter/CodeInterpreter.cpp b/interpreter/CodeInterpreter.cpp index 2186bf9..1e7f143 100644 --- a/interpreter/CodeInterpreter.cpp +++ b/interpreter/CodeInterpreter.cpp @@ -11,7 +11,7 @@ void CodeInterpreter::_bind_methods() ClassDB::bind_method(D_METHOD("getSequence"), &CodeInterpreter::getSequence); } -void CodeInterpreter::registerBuiltInMethod(const String& str); +void CodeInterpreter::registerBuiltInMethod(const String& str) { const std::string text{str.utf8().get_data()}; @@ -24,7 +24,7 @@ String CodeInterpreter::interpret(const String& str) const std::string text{str.utf8().get_data()}; interpreter.symbolTable().init(); - interpreter.initParser(input); + interpreter.initParser(text); interpreter.registerBuiltInMethod("moveNorth()"); interpreter.registerBuiltInMethod("moveSouth()");