@@ -46,6 +46,59 @@ void st::SymbolTable::init()
4646 create (std::make_shared<BuiltInTypeSymbol>(" BOOL_VALUE" , SymbolVariableType::BOOL_VALUE));
4747}
4848
49+ void st::SymbolTable::debugPrint ()
50+ {
51+ for (const auto & [symbolName, symbolPtr] : _symbols) {
52+ if (!symbolPtr)
53+ continue ;
54+
55+ std::cout << " Symbol Name: " << symbolName << " \n " ;
56+ std::cout << " Symbol Type: " ;
57+
58+ switch (symbolPtr->symbolType ()) {
59+ case SymbolType::SYMBOL:
60+ std::cout << " General Symbol\n " ;
61+ break ;
62+
63+ case SymbolType::BUILT_IN_TYPE_SYMBOL: {
64+ std::cout << " Built-in Type Symbol\n " ;
65+ auto builtInTypeSymbol = std::dynamic_pointer_cast<BuiltInTypeSymbol>(symbolPtr);
66+ if (builtInTypeSymbol) {
67+ std::cout << " Type: " << static_cast <int >(builtInTypeSymbol->_type ) << " \n " ;
68+ }
69+ break ;
70+ }
71+
72+ case SymbolType::VARIABLE_SYMBOL: {
73+ std::cout << " Variable Symbol\n " ;
74+ auto variableSymbol = std::dynamic_pointer_cast<VariableSymbol>(symbolPtr);
75+ if (variableSymbol) {
76+ std::cout << " Type: " << variableSymbol->variableType ->name () << " \n " ;
77+ std::cout << " Value: " ;
78+ std::visit ([](const auto & val) { std::cout << val; }, variableSymbol->variableValue );
79+ std::cout << " \n " ;
80+ }
81+ break ;
82+ }
83+
84+ case SymbolType::FUNCTION_SYMBOL: {
85+ std::cout << " Function Symbol\n " ;
86+ auto functionSymbol = std::dynamic_pointer_cast<FunctionSymbol>(symbolPtr);
87+ if (functionSymbol) {
88+ std::cout << " Function Body Nodes: " << functionSymbol->body ().size () << " \n " ;
89+ }
90+ break ;
91+ }
92+
93+ default :
94+ std::cout << " Unknown Type\n " ;
95+ break ;
96+ }
97+
98+ std::cout << " --------------------------\n " ;
99+ }
100+ }
101+
49102void stNodeVisitor::operator ()(BinaryOperation& node)
50103{
51104 visit (getVariant (node.left ()));
@@ -82,19 +135,37 @@ void stNodeVisitor::operator()(Assign& node)
82135
83136void stNodeVisitor::operator ()(VariableDeclaration& node)
84137{
85- std::shared_ptr<Variable> variable = std::dynamic_pointer_cast<Variable>(node.variable ().value ());
138+ if (node.variable ().has_value ()) {
139+ std::shared_ptr<Variable> variable = std::dynamic_pointer_cast<Variable>(node.variable ().value ());
86140
87- const std::string variableName = variable->name ();
141+ const std::string variableName = variable->name ();
88142
89- if (st.find (variableName)) {
90- const std::string errorMessage = " Variable '" + variableName + " ' already exists" ;
91- throw std::runtime_error (errorMessage);
92- }
143+ if (st.find (variableName)) {
144+ const std::string errorMessage = " Variable '" + variableName + " ' already exists" ;
145+ throw std::runtime_error (errorMessage);
146+ }
147+
148+ const std::variant<int , float , bool > variableValue = variable->token ().getFlexNumber ();
149+ std::shared_ptr<st::Symbol> variableType = st.find (Token::typeToString (variable->token ().getType ()));
93150
94- const std::variant<int , float , bool > variableValue = variable->token ().getFlexNumber ();
95- std::shared_ptr<st::Symbol> variableType = st.find (Token::typeToString (variable->token ().getType ()));
151+ st.create (std::make_shared<st::VariableSymbol>(variableName, variableValue, variableType));
152+ } else {
153+ std::shared_ptr<Assign> assignment = std::dynamic_pointer_cast<Assign>(node.assignment ().value ());
154+ std::shared_ptr<Variable> variable = std::dynamic_pointer_cast<Variable>(assignment->left ());
96155
97- st.create (std::make_shared<st::VariableSymbol>(variableName, variableValue, variableType));
156+ const std::string variableName = variable->name ();
157+
158+ if (st.find (variableName)) {
159+ const std::string errorMessage = " Variable '" + variableName + " ' already exists" ;
160+ throw std::runtime_error (errorMessage);
161+ }
162+
163+ const std::variant<int , float , bool > variableValue = evaluateExpression (assignment->right ());
164+ const std::string tokenType = getTokenTypeFromVariant (variableValue);
165+ std::shared_ptr<st::Symbol> variableType = st.find (tokenType);
166+
167+ st.create (std::make_shared<st::VariableSymbol>(variableName, variableValue, variableType));
168+ }
98169}
99170
100171void stNodeVisitor::operator ()(Variable& variable)
@@ -170,6 +241,69 @@ void SymbolTableVisitNode::visit(NodeVariant astNode)
170241 return std::visit (SymbolTableVisitNode (st), astNode);
171242}
172243
244+ std::variant<int , float , bool > stNodeVisitor::evaluateExpression (const std::shared_ptr<AstNode> node)
245+ {
246+ switch (node->nodeType ()) {
247+ case NodeType::BINARY_OPERATION: {
248+ auto binaryOpNode = std::dynamic_pointer_cast<BinaryOperation>(node);
249+
250+ NodeVariant left = getVariant (binaryOpNode->left ());
251+ NodeVariant right = getVariant (binaryOpNode->right ());
252+
253+ TokenType tokenType = binaryOpNode->binaryOperator ().getType ();
254+
255+ return Interpreter::calculateBinaryResult (st, Interpreter::visitInterpret (left, st), Interpreter::visitInterpret (right, st), tokenType);
256+ }
257+ case NodeType::UNARY_OPERATOR: {
258+ auto unaryOpNode = std::dynamic_pointer_cast<UnaryOp>(node);
259+
260+ if (unaryOpNode->token ().getType () == TokenType::PLUS) {
261+ return evaluateExpression (unaryOpNode->expr ());
262+ } else if (unaryOpNode->token ().getType () == TokenType::MINUS) {
263+ const std::variant<int , float , bool > variant = evaluateExpression (unaryOpNode->expr ());
264+ if (std::holds_alternative<int >(variant)) {
265+ const int value = std::get<int >(variant);
266+ return -value;
267+ } else if (std::holds_alternative<float >(variant)) {
268+ const float value = std::get<float >(variant);
269+ return -value;
270+ } else if (std::holds_alternative<bool >(variant)) {
271+ throw std::runtime_error (" Cannot add '-' sign to bool value" );
272+ } else {
273+ throw std::runtime_error (" Variant does not hold integer, float or bool inside, cannot return value of it" );
274+ }
275+ } else {
276+ throw std::runtime_error (" Token type in UnaryOp is netiher PLUS or MINUS" );
277+ }
278+ }
279+ case NodeType::NUMBER: {
280+ auto numberNode = std::dynamic_pointer_cast<Number>(node);
281+ return numberNode->value ();
282+ }
283+ case NodeType::VARIABLE: {
284+ auto variableNode = std::dynamic_pointer_cast<Variable>(node);
285+ return variableNode->token ().getFlexNumber ();
286+ }
287+ default : {
288+ const std::string msg = " Evaluating expression for type '" + std::to_string (static_cast <uint8_t >(node->nodeType ())) + " ' is not implemented" ;
289+ throw std::runtime_error (msg);
290+ }
291+ }
292+ }
293+
294+ std::string stNodeVisitor::getTokenTypeFromVariant (std::variant<int , float , bool > variant)
295+ {
296+ if (std::holds_alternative<int >(variant)) {
297+ return " INTEGER" ;
298+ } else if (std::holds_alternative<float >(variant)) {
299+ return " FLOATING_NUMBER" ;
300+ } else if (std::holds_alternative<bool >(variant)) {
301+ return " BOOL_VALUE" ;
302+ } else {
303+ throw std::runtime_error (" Unknown variant in getTokenTypeFromVariant" );
304+ }
305+ }
306+
173307std::shared_ptr<AstNode> NodeVisitor::operator ()(BinaryOperation& node)
174308{
175309
@@ -449,6 +583,8 @@ std::shared_ptr<AstNode> Interpreter::buildTree(const std::string& text)
449583{
450584 reset ();
451585
586+ _symbolTable.init ();
587+
452588 _parser = Parser (Lexer (text));
453589
454590 return _parser.parse ();
0 commit comments