Add support for diagnostics

This commit is contained in:
2019-05-21 13:56:08 +02:00
parent 26f1ed27a3
commit 2b35da3a7b
11 changed files with 161 additions and 68 deletions

View File

@@ -3,15 +3,16 @@
#include "Lexer.hpp"
Lexer::Lexer(string script) {
Lexer::Script = std::move(script);
Lexer::Position = 0;
Lexer::Lexer(string scriptString, class Script* script) {
this -> ScriptString = std::move(scriptString);
this -> ScriptData = script;
this -> Position = 0;
}
vector<IToken*> Lexer::Lex() {
vector<IToken*> tokens;
while (true){
IToken* next = Lexer::LexNext(Lexer::Next());
IToken* next = this -> LexNext(this -> Next());
tokens.push_back(next);
if (next->GetKind() == TokenKind::EndOfFile)
break;
@@ -20,9 +21,9 @@ vector<IToken*> Lexer::Lex() {
}
char Lexer::Peek(){
if (Lexer::Position > Lexer::Script.length())
if (Lexer::Position > this -> ScriptString.length())
return '\0';
return Lexer::Script[Lexer::Position];
return this -> ScriptString[Lexer::Position];
}
char Lexer::Next(){
@@ -34,23 +35,23 @@ char Lexer::Next(){
IToken* Lexer::LexNext(char c){
switch (c) {
case '\0':
return new SimpleToken(TokenKind::EndOfFile, Lexer::Position - 1, 1);
return new SimpleToken(TokenKind::EndOfFile, this -> Position - 1, 1);
case ' ': case '\t': case '\n': case '\r': case '\v': case '\f':
return new SimpleToken(TokenKind::WhiteSpace, Lexer::Position - 1, 1);
return new SimpleToken(TokenKind::WhiteSpace, this -> Position - 1, 1);
case '+':
return new SimpleToken(TokenKind::PlusToken, Lexer::Position - 1, 1);
return new SimpleToken(TokenKind::PlusToken, this -> Position - 1, 1);
case '-':
return new SimpleToken(TokenKind::MinusToken, Lexer::Position - 1, 1);
return new SimpleToken(TokenKind::MinusToken, this -> Position - 1, 1);
case '/':
return new SimpleToken(TokenKind::SlashToken, Lexer::Position - 1, 1);
return new SimpleToken(TokenKind::SlashToken, this -> Position - 1, 1);
case '*':
return new SimpleToken(TokenKind::StarToken, Lexer::Position - 1, 1);
return new SimpleToken(TokenKind::StarToken, this -> Position - 1, 1);
case '=':
if (Lexer::Peek() == '='){
Lexer::Next();
return new SimpleToken(TokenKind::EqualityToken, Lexer::Position - 2, 2);
return new SimpleToken(TokenKind::EqualityToken, this -> Position - 2, 2);
}
return new SimpleToken(TokenKind::AssignmentToken, Lexer::Position - 1, 1);
return new SimpleToken(TokenKind::AssignmentToken, this -> Position - 1, 1);
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
return LexNumber(c);
case '_':
@@ -59,7 +60,8 @@ IToken* Lexer::LexNext(char c){
if (isalpha(c)){
return LexIdentifierOrKeyword(c);
}
throw;
this -> ScriptData->Diagnostics.LogError(DiagnosticCode::UnexpectedCharacter, this -> Position - 1, 1);
return new SimpleToken(TokenKind::BadToken, this -> Position - 1, 1);
}
}
@@ -85,19 +87,19 @@ IToken* Lexer::LexNumber(char c){
short decimal_index = 0;
bool has_point = false;
bool is_searching = true;
unsigned int start = Lexer::Position - 1;
unsigned int start = this -> Position - 1;
unsigned int length = 1;
while (is_searching){
char next = Lexer::Peek();
char next = this -> Peek();
int next_val = CharToInt(next);
if (next_val == -1){
switch (next){
case '_':
Lexer::Next();
this -> Next();
length++;
continue;
case '.':
Lexer::Next();
this -> Next();
has_point = true;
decimal_index = 0;
float_value = int_value;
@@ -109,7 +111,7 @@ IToken* Lexer::LexNumber(char c){
}
}
else{
Lexer::Next();
this -> Next();
length++;
if (has_point){
decimal_index++;
@@ -137,12 +139,12 @@ unsigned constexpr const_hash(char const *input) {
IToken* Lexer::LexIdentifierOrKeyword(char c){
vector<char> charVec(1, c);
auto start = Lexer::Position - 1;
auto start = this -> Position - 1;
while (true){
char next = Lexer::Peek();
char next = this -> Peek();
if (next == '\0') break;
if (isalpha(next) || next == '_'){
Lexer::Next();
this -> Next();
charVec.push_back(next);
}
else{