Skip to content

Commit c3591ce

Browse files
committed
Add line and position to parsing errors
1 parent 2251a99 commit c3591ce

File tree

12 files changed

+266
-75
lines changed

12 files changed

+266
-75
lines changed

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,10 @@ MigrationBackup/
369369
.ionide/
370370

371371
# Fody - auto-generated XML schema
372-
FodyWeavers.xsd
372+
FodyWeavers.xsd
373+
374+
.clang-format
375+
.devcontainer
376+
.vscode
377+
cpp.code-workspace
378+
formatted_code

interpreter/CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ set(CPACK_PROJECT_NAME ${PROJECT_NAME})
88
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
99
include(CPack)
1010

11-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -std=c++20")
11+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -std=c++17")
1212

1313
set(SOURCES main.cpp
1414
src/Ast.cpp
@@ -26,5 +26,3 @@ target_link_libraries(Interpreter
2626
spdlog::spdlog
2727
spdlog
2828
)
29-
30-
#add_subdirectory(test)

interpreter/main.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include "./src/Ast.h"
2+
#include "./src/GlobalScope.h"
3+
#include "./src/Interpreter.h"
4+
#include "./src/Lexer.h"
5+
#include "./src/Parser.h"
6+
#include "./src/Token.h"
7+
8+
#include <fstream>
9+
#include <iostream>
10+
#include <sstream>
11+
// #include <spdlog/spdlog.h>
12+
13+
// std::map<std::string, std::variant<int, float, bool>> GLOBAL_SCOPE;
14+
// std::unordered_map<std::string, std::vector<std::shared_ptr<AstNode>>> GLOBAL_FUNCTIONS;
15+
16+
int main(int argc, char* argv[])
17+
{
18+
19+
if (argc > 1) {
20+
std::string input;
21+
22+
std::string file_path;
23+
std::string other_arg;
24+
25+
std::string arg = argv[1];
26+
27+
if (arg.find("--file=") == 0) {
28+
file_path = arg.substr(7);
29+
} else {
30+
other_arg = arg;
31+
}
32+
33+
if (!file_path.empty()) {
34+
std::cout << "File path: " << file_path << std::endl;
35+
36+
std::ifstream file(file_path);
37+
38+
if (file.is_open()) {
39+
std::stringstream buffer;
40+
buffer << file.rdbuf();
41+
input = buffer.str();
42+
43+
std::cout << "File content:\n" << input << std::endl;
44+
} else {
45+
std::cerr << "Error: Could not open file " << file_path << std::endl;
46+
}
47+
48+
} else {
49+
std::cout << "No file path provided. Use --file=path_to_file" << std::endl;
50+
if (!arg.empty()) {
51+
std::cout << "Argument: " << std::endl;
52+
std::cout << " - " << arg << std::endl;
53+
input = arg;
54+
}
55+
}
56+
57+
Interpreter interpreter;
58+
std::shared_ptr<AstNode> result = interpreter.interpret(input);
59+
60+
std::cout << "Variables:" << std::endl;
61+
62+
for (const auto& [name, value] : GLOBAL_SCOPE) {
63+
if (std::holds_alternative<int>(value)) {
64+
std::cout << "[" << name << " = " << std::get<int>(value) << "]" << std::endl;
65+
} else {
66+
std::cout << "[" << name << " = " << std::get<float>(value) << "]" << std::endl;
67+
}
68+
}
69+
70+
std::cout << "Result node type: " << getTypeString(result->nodeType()) << std::endl;
71+
72+
return 0;
73+
}
74+
75+
return 1;
76+
}

interpreter/src/Ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "Token.h"
44

55
//#include <spdlog/spdlog.h>
6+
#include <memory>
67
#include <vector>
78

89
class AstNode;

interpreter/src/Interpreter.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#include "Interpreter.h"
2-
#include "GlobalScope.h"
32

3+
#include "GlobalScope.h"
44

55
using Visitor = NodeVisitor::VisitNode;
66

7-
87
std::map<std::string, std::variant<int, float, bool>> GLOBAL_SCOPE;
98
std::unordered_map<std::string, std::vector<std::shared_ptr<AstNode>>> GLOBAL_FUNCTIONS;
109

11-
1210
std::shared_ptr<AstNode> Visitor::operator()(BinaryOperation& node)
1311
{
1412

@@ -239,14 +237,26 @@ std::shared_ptr<AstNode> NodeVisitor::visit(NodeVariant astNode)
239237

240238
std::shared_ptr<AstNode> Interpreter::interpret(const std::string& text)
241239
{
242-
Lexer lexer(text);
243-
Parser parser(lexer);
240+
reset();
241+
242+
_parser = Parser(Lexer(text));
244243

245-
std::shared_ptr<AstNode> tree = parser.parse();
244+
std::shared_ptr<AstNode> tree = _parser.parse();
246245

247246
return NodeVisitor::visit(getVariant(tree));
248247
}
249248

249+
void Interpreter::reset()
250+
{
251+
GLOBAL_SCOPE.clear();
252+
GLOBAL_FUNCTIONS.clear();
253+
254+
_executionLine = -1;
255+
_executionPosition = -1;
256+
257+
_parser = Parser();
258+
}
259+
250260
// static
251261
FlexNumber NodeVisitor::calculateBinaryResult(const std::shared_ptr<AstNode>& left, const std::shared_ptr<AstNode>& right, TokenType type)
252262
{

interpreter/src/Interpreter.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#pragma once
22

3-
43
#include "Ast.h"
54
#include "Lexer.h"
65
#include "Parser.h"
76

7+
#include <unordered_map>
88
#include <variant>
99

1010
class NodeVisitor
1111
{
1212
public:
1313
struct VisitNode
1414
{
15-
//std::shared_ptr<AstNode> operator()(auto& node);
15+
// std::shared_ptr<AstNode> operator()(auto& node);
1616
std::shared_ptr<AstNode> operator()(BinaryOperation& node);
1717
std::shared_ptr<AstNode> operator()(Number& node);
1818
std::shared_ptr<AstNode> operator()(UnaryOp& node);
@@ -37,4 +37,23 @@ class Interpreter : public NodeVisitor
3737
{
3838
public:
3939
std::shared_ptr<AstNode> interpret(const std::string& text);
40+
41+
void reset();
42+
43+
std::map<std::string, std::variant<int, float, bool>>& getGlobalScope() { return GLOBAL_SCOPE; }
44+
std::unordered_map<std::string, std::vector<std::shared_ptr<AstNode>>>& getGlobalFunctions() { return GLOBAL_FUNCTIONS; }
45+
46+
void raiseExecutionError(uint16_t currentLine, int16_t currentPositon = -1) const;
47+
48+
// tutaj raise odpowiedni exception wraz z argumentami w postaci currentLine oraz currentPosition
49+
// rozwiazac jakos to z ast
50+
51+
private:
52+
std::map<std::string, std::variant<int, float, bool>> GLOBAL_SCOPE;
53+
std::unordered_map<std::string, std::vector<std::shared_ptr<AstNode>>> GLOBAL_FUNCTIONS;
54+
55+
uint16_t _executionPosition;
56+
uint16_t _executionLine;
57+
58+
Parser _parser;
4059
};

interpreter/src/Lexer.cpp

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ void Lexer::advance()
1010
} else {
1111
_currentChar = _text[_pos];
1212
}
13+
++_parsingPosition;
1314
}
1415

1516
void Lexer::skipWhitespace()
@@ -19,6 +20,19 @@ void Lexer::skipWhitespace()
1920
}
2021
}
2122

23+
void Lexer::skipNewLine()
24+
{
25+
++_pos;
26+
if (_pos > static_cast<int>(_text.length()) - 1) {
27+
_currentChar = '\0';
28+
} else {
29+
_currentChar = _text[_pos];
30+
}
31+
32+
++_parsingLine;
33+
_parsingPosition = 0;
34+
}
35+
2236
std::variant<int, float, bool> Lexer::number()
2337
{
2438
std::string result;
@@ -48,94 +62,79 @@ Token Lexer::getNextToken()
4862
if (_currentChar == ' ') {
4963
skipWhitespace();
5064
continue;
51-
}
52-
if (_currentChar == '+') {
65+
} else if (_currentChar == '\n') {
66+
skipNewLine();
67+
continue;
68+
} else if (_currentChar == '+') {
5369
advance();
5470
return Token('+', TokenType::PLUS);
55-
}
56-
if (_currentChar == '-') {
71+
} else if (_currentChar == '-') {
5772
advance();
5873
return Token('-', TokenType::MINUS);
59-
}
60-
if (_currentChar == '*') {
74+
} else if (_currentChar == '*') {
6175
advance();
6276
return Token('*', TokenType::MULTIPLICATION);
63-
}
64-
if (_currentChar == '/') {
77+
} else if (_currentChar == '/') {
6578
advance();
6679
return Token('/', TokenType::DIVISION);
67-
}
68-
if (_currentChar == '=' && peekNextChar() == '=') {
80+
} else if (_currentChar == '=' && peekNextChar() == '=') {
6981
advance();
7082
advance();
7183
return Token("==", TokenType::COMPARISON);
72-
}
73-
if (_currentChar == '!' && peekNextChar() == '=') {
84+
} else if (_currentChar == '!' && peekNextChar() == '=') {
7485
advance();
7586
advance();
7687
return Token("!=", TokenType::NOT_EQUAL);
77-
}
78-
if (_currentChar == '>' && peekNextChar() == '=') {
88+
} else if (_currentChar == '>' && peekNextChar() == '=') {
7989
advance();
8090
advance();
8191
return Token(">=", TokenType::GREATER_EQUAL);
82-
}
83-
if (_currentChar == '<' && peekNextChar() == '=') {
92+
} else if (_currentChar == '<' && peekNextChar() == '=') {
8493
advance();
8594
advance();
8695
return Token("<=", TokenType::LESS_EQUAL);
87-
}
88-
if (_currentChar == '>') {
96+
} else if (_currentChar == '>') {
8997
advance();
9098
advance();
9199
return Token(">", TokenType::GREATER);
92-
}
93-
if (_currentChar == '<') {
100+
} else if (_currentChar == '<') {
94101
advance();
95102
advance();
96103
return Token("<", TokenType::LESS);
97-
}
98-
if (_currentChar == '(') {
104+
} else if (_currentChar == '(') {
99105
advance();
100106
return Token('(', TokenType::LPAREN);
101-
}
102-
if (_currentChar == ')') {
107+
} else if (_currentChar == ')') {
103108
advance();
104109
return Token(')', TokenType::RPAREN);
105-
}
106-
if (_currentChar == '=') {
110+
} else if (_currentChar == '=') {
107111
advance();
108112
return Token('=', TokenType::ASSIGN);
109-
}
110-
if (_currentChar == ':') {
113+
} else if (_currentChar == ':') {
111114
advance();
112115
return Token(':', TokenType::COLON);
113-
}
114-
if (_currentChar == ';') {
116+
} else if (_currentChar == ';') {
115117
advance();
116118
return Token(';', TokenType::SEMICOLON);
117-
}
118-
if (_currentChar == '.') {
119+
} else if (_currentChar == '.') {
119120
advance();
120121
return Token('.', TokenType::DOT);
121-
}
122-
if (_currentChar == ',') {
122+
} else if (_currentChar == ',') {
123123
advance();
124124
return Token(',', TokenType::COMMA);
125-
}
126-
if (isdigit(_currentChar)) {
125+
} else if (isdigit(_currentChar)) {
127126
std::variant<int, float, bool> num = number();
128127
if (std::holds_alternative<int>(num)) {
129128
return Token(std::get<int>(num), TokenType::INTEGER);
130129
} else {
131130
return Token(std::get<float>(num), TokenType::FLOATING_NUMBER);
132131
}
133-
}
134-
if (isalpha(_currentChar)) {
132+
} else if (isalpha(_currentChar)) {
135133
return id();
136-
}
134+
} else {
137135

138-
raiseInvalidCharacterError();
136+
raiseInvalidCharacterError();
137+
}
139138
}
140139

141140
return Token(std::nullptr_t(), TokenType::END_OF_FILE);

0 commit comments

Comments
 (0)