Started handling tokens.
parent
707337ca6e
commit
048b26ca2b
|
@ -0,0 +1,18 @@
|
||||||
|
%include main
|
||||||
|
|
||||||
|
let person1 = Character("Person 1", "default_char.png")
|
||||||
|
let person2 = Character("Person 2", "default_char.png")
|
||||||
|
|
||||||
|
let location = Location("default_loc.png")
|
||||||
|
|
||||||
|
show location
|
||||||
|
enter person1 left
|
||||||
|
enter person2 right
|
||||||
|
|
||||||
|
person1 "Hello World"
|
||||||
|
person2 "Goodbye World"
|
||||||
|
|
||||||
|
exit person1
|
||||||
|
move person2 center
|
||||||
|
person2 "Goodbye"
|
||||||
|
exit person2
|
43
src/lang.cc
43
src/lang.cc
|
@ -14,9 +14,50 @@ int read_file(std::deque<std::string> args) {
|
||||||
}
|
}
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(file, line)) {
|
while (std::getline(file, line)) {
|
||||||
std::istringstream stream(line);
|
|
||||||
std::cout << line << std::endl;
|
std::cout << line << std::endl;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_line(std::string line) {
|
||||||
|
struct parsed_token parsed {
|
||||||
|
empty_token, empty_token
|
||||||
|
};
|
||||||
|
if (int sub = line.find("//"))
|
||||||
|
line = line.substr(sub);
|
||||||
|
std::deque<std::string> tokens;
|
||||||
|
int start = 0;
|
||||||
|
size_t end = line.find(" ");
|
||||||
|
while (end != std::string::npos) {
|
||||||
|
tokens.push_back(line.substr(start, end - start));
|
||||||
|
start = end + 1;
|
||||||
|
end = line.find(" ", start);
|
||||||
|
}
|
||||||
|
for (std::string &token : tokens) {
|
||||||
|
try {
|
||||||
|
Token curr_token = CV_Tokens.at(token);
|
||||||
|
parsed.lastToken = parsed.currentToken;
|
||||||
|
if (curr_token == parsed.lastToken && curr_token.type == TokenType::SPACE)
|
||||||
|
continue;
|
||||||
|
else {
|
||||||
|
// TODO: Line number handling for better errors
|
||||||
|
std::cerr << "Invalid token `" << token << "'." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
parsed.currentToken = curr_token;
|
||||||
|
} catch (std::out_of_range &oor) {
|
||||||
|
// this is most likely a variable or a string
|
||||||
|
if (parsed.lastToken.type == TokenType::INTRINSIC &&
|
||||||
|
parsed.lastToken.intrinsic == Intrinsic::LET) {
|
||||||
|
VariableToken var{TokenType::VARIABLE, Intrinsic::EMPTY,
|
||||||
|
Constant::EMPTY, "", token};
|
||||||
|
parsed.currentToken = var;
|
||||||
|
var_tokens.push_back(var);
|
||||||
|
}
|
||||||
|
// string parsing
|
||||||
|
std::cerr << "Not implemented. Found `" << token << "'." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
100
src/lang.h
100
src/lang.h
|
@ -7,54 +7,96 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
enum class TokenType {
|
enum class TokenType {
|
||||||
|
EMPTY,
|
||||||
|
SPACE,
|
||||||
LEFT_PAREN,
|
LEFT_PAREN,
|
||||||
RIGHT_PAREN,
|
RIGHT_PAREN,
|
||||||
COLONCOLON,
|
COLONCOLON,
|
||||||
|
EQ,
|
||||||
|
COMMA,
|
||||||
STRING,
|
STRING,
|
||||||
INTRINSIC,
|
INTRINSIC,
|
||||||
CONSTANT
|
CONSTANT,
|
||||||
|
VARIABLE
|
||||||
};
|
};
|
||||||
enum class Intrinsic { LET, UNLET, ENTER, EXIT, SHOW, HIDE };
|
|
||||||
enum class Constant { Character, Location, Image };
|
enum class Intrinsic { EMPTY, LET, UNLET, ENTER, EXIT, SHOW, HIDE };
|
||||||
|
|
||||||
|
enum class Constant { EMPTY, CHARACTER, LOCATION, IMAGE };
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
TokenType type;
|
TokenType type;
|
||||||
std::string value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IntrinsicToken : Token {
|
|
||||||
Intrinsic intrinsic;
|
Intrinsic intrinsic;
|
||||||
};
|
|
||||||
|
|
||||||
struct ConstantToken : Token {
|
|
||||||
Constant constant;
|
Constant constant;
|
||||||
};
|
|
||||||
|
|
||||||
struct StringToken : Token {
|
|
||||||
std::string string;
|
std::string string;
|
||||||
|
std::string name;
|
||||||
|
inline bool operator==(const Token &right) {
|
||||||
|
if (this->type == right.type && this->intrinsic == right.intrinsic &&
|
||||||
|
this->constant == right.constant && this->string == right.string &&
|
||||||
|
this->name == right.name)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool operator!=(const Token &right) { return !(*this == right); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<std::string, Token> tokens = {
|
struct VariableToken : Token {
|
||||||
{"(", Token{TokenType::LEFT_PAREN, "("}},
|
Token value;
|
||||||
{")", Token{TokenType::RIGHT_PAREN, ")"}},
|
inline bool operator==(const VariableToken &right) {
|
||||||
{"::", Token{TokenType::COLONCOLON, "::"}},
|
if ((Token) * this == (Token)right && this->value == right.value)
|
||||||
{"let", IntrinsicToken{TokenType::INTRINSIC, "let", Intrinsic::LET}},
|
return true;
|
||||||
{"unlet", IntrinsicToken{TokenType::INTRINSIC, "unlet", Intrinsic::UNLET}},
|
return false;
|
||||||
{"enter", IntrinsicToken{TokenType::INTRINSIC, "enter", Intrinsic::ENTER}},
|
}
|
||||||
{"exit", IntrinsicToken{TokenType::INTRINSIC, "exit", Intrinsic::EXIT}},
|
inline bool operator!=(const VariableToken &right) {
|
||||||
{"show", IntrinsicToken{TokenType::INTRINSIC, "show", Intrinsic::SHOW}},
|
return !(*this == right);
|
||||||
{"hide", IntrinsicToken{TokenType::INTRINSIC, "hide", Intrinsic::HIDE}},
|
}
|
||||||
{"Character",
|
|
||||||
ConstantToken{TokenType::CONSTANT, "Character", Constant::Character}},
|
|
||||||
{"Location",
|
|
||||||
ConstantToken{TokenType::CONSTANT, "Location", Constant::Location}},
|
|
||||||
{"Image", ConstantToken{TokenType::CONSTANT, "Image", Constant::Image}},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::map<std::string, Token> CV_Tokens{
|
||||||
|
{"", Token{TokenType::EMPTY, Intrinsic::EMPTY, Constant::EMPTY, "", ""}},
|
||||||
|
{" ", Token{TokenType::SPACE, Intrinsic::EMPTY, Constant::EMPTY, "", ""}},
|
||||||
|
{"(",
|
||||||
|
Token{TokenType::LEFT_PAREN, Intrinsic::EMPTY, Constant::EMPTY, "", ""}},
|
||||||
|
{")",
|
||||||
|
Token{TokenType::RIGHT_PAREN, Intrinsic::EMPTY, Constant::EMPTY, "", ""}},
|
||||||
|
{"::",
|
||||||
|
Token{TokenType::COLONCOLON, Intrinsic::EMPTY, Constant::EMPTY, "", ""}},
|
||||||
|
{"=", Token{TokenType::EQ, Intrinsic::EMPTY, Constant::EMPTY, "", ""}},
|
||||||
|
{",", Token{TokenType::COMMA, Intrinsic::EMPTY, Constant::EMPTY, "", ""}},
|
||||||
|
{"let",
|
||||||
|
Token{TokenType::INTRINSIC, Intrinsic::LET, Constant::EMPTY, "", ""}},
|
||||||
|
{"unlet",
|
||||||
|
Token{TokenType::INTRINSIC, Intrinsic::UNLET, Constant::EMPTY, "", ""}},
|
||||||
|
{"enter",
|
||||||
|
Token{TokenType::INTRINSIC, Intrinsic::ENTER, Constant::EMPTY, "", ""}},
|
||||||
|
{"exit",
|
||||||
|
Token{TokenType::INTRINSIC, Intrinsic::EXIT, Constant::EMPTY, "", ""}},
|
||||||
|
{"show",
|
||||||
|
Token{TokenType::INTRINSIC, Intrinsic::SHOW, Constant::EMPTY, "", ""}},
|
||||||
|
{"hide",
|
||||||
|
Token{TokenType::INTRINSIC, Intrinsic::HIDE, Constant::EMPTY, "", ""}},
|
||||||
|
{"Character",
|
||||||
|
Token{TokenType::CONSTANT, Intrinsic::EMPTY, Constant::CHARACTER, "", ""}},
|
||||||
|
{"Location",
|
||||||
|
Token{TokenType::CONSTANT, Intrinsic::EMPTY, Constant::LOCATION, "", ""}},
|
||||||
|
{"Image",
|
||||||
|
Token{TokenType::CONSTANT, Intrinsic::EMPTY, Constant::IMAGE, "", ""}}};
|
||||||
|
|
||||||
|
Token empty_token{TokenType::EMPTY, Intrinsic::EMPTY, Constant::EMPTY, "", ""};
|
||||||
|
|
||||||
|
struct parsed_token {
|
||||||
|
Token lastToken;
|
||||||
|
Token currentToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<VariableToken> var_tokens;
|
||||||
|
|
||||||
int read_file(std::deque<std::string> args);
|
int read_file(std::deque<std::string> args);
|
||||||
int parse_line(std::istream stream);
|
int parse_line(std::string line);
|
||||||
|
|
|
@ -3,10 +3,13 @@ if exists("b:current_syntax") | finish | endif
|
||||||
set iskeyword=a-z,A-Z,-,*,_,!,@
|
set iskeyword=a-z,A-Z,-,*,_,!,@
|
||||||
|
|
||||||
" Language keywords
|
" Language keywords
|
||||||
syntax keyword ceevKeywords let unlet enter exit show hide
|
syntax keyword ceevKeywords let unlet enter exit show hide left right center move
|
||||||
syntax keyword ceevTodos TODO
|
syntax keyword ceevTodos TODO
|
||||||
syntax keyword ceevConstant Character Location Image
|
syntax keyword ceevConstant Character Location Image
|
||||||
|
|
||||||
|
" Includes
|
||||||
|
syntax region ceevSpecials start="%include" end="$"
|
||||||
|
|
||||||
" Comments
|
" Comments
|
||||||
syntax region ceevCommentLine start="//" end="$" contains=ceevTodos
|
syntax region ceevCommentLine start="//" end="$" contains=ceevTodos
|
||||||
|
|
||||||
|
@ -30,6 +33,7 @@ highlight default link ceevConstant Constant
|
||||||
highlight default link ceevCommentLine Comment
|
highlight default link ceevCommentLine Comment
|
||||||
highlight default link ceevString String
|
highlight default link ceevString String
|
||||||
highlight default link ceevNumber Number
|
highlight default link ceevNumber Number
|
||||||
|
highlight default link ceevSpecials Include
|
||||||
highlight default link ceevTypeNames Type
|
highlight default link ceevTypeNames Type
|
||||||
highlight default link ceevChar Character
|
highlight default link ceevChar Character
|
||||||
highlight default link ceevEscapes SpecialChar
|
highlight default link ceevEscapes SpecialChar
|
||||||
|
|
Loading…
Reference in New Issue