From 048b26ca2bc63728de46ac2bfd5f3ce907b98fb1 Mon Sep 17 00:00:00 2001 From: Ruben Dahl Date: Tue, 17 Jan 2023 21:37:12 +0100 Subject: [PATCH] Started handling tokens. --- examples/src/next.cv | 18 ++++++++ src/lang.cc | 43 ++++++++++++++++++- src/lang.h | 100 ++++++++++++++++++++++++++++++------------- syntax/ceev.vim | 6 ++- 4 files changed, 136 insertions(+), 31 deletions(-) create mode 100644 examples/src/next.cv diff --git a/examples/src/next.cv b/examples/src/next.cv new file mode 100644 index 0000000..61ed01a --- /dev/null +++ b/examples/src/next.cv @@ -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 diff --git a/src/lang.cc b/src/lang.cc index e6d45bb..3eb082d 100644 --- a/src/lang.cc +++ b/src/lang.cc @@ -14,9 +14,50 @@ int read_file(std::deque args) { } std::string line; while (std::getline(file, line)) { - std::istringstream stream(line); std::cout << line << std::endl; } 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 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; +} diff --git a/src/lang.h b/src/lang.h index 27d6752..2a9ce16 100644 --- a/src/lang.h +++ b/src/lang.h @@ -7,54 +7,96 @@ #include #include #include +#include #include +#include namespace fs = std::filesystem; enum class TokenType { + EMPTY, + SPACE, LEFT_PAREN, RIGHT_PAREN, COLONCOLON, + EQ, + COMMA, STRING, 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 { TokenType type; - std::string value; -}; - -struct IntrinsicToken : Token { Intrinsic intrinsic; -}; - -struct ConstantToken : Token { Constant constant; -}; - -struct StringToken : Token { 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 tokens = { - {"(", Token{TokenType::LEFT_PAREN, "("}}, - {")", Token{TokenType::RIGHT_PAREN, ")"}}, - {"::", Token{TokenType::COLONCOLON, "::"}}, - {"let", IntrinsicToken{TokenType::INTRINSIC, "let", Intrinsic::LET}}, - {"unlet", IntrinsicToken{TokenType::INTRINSIC, "unlet", Intrinsic::UNLET}}, - {"enter", IntrinsicToken{TokenType::INTRINSIC, "enter", Intrinsic::ENTER}}, - {"exit", IntrinsicToken{TokenType::INTRINSIC, "exit", Intrinsic::EXIT}}, - {"show", IntrinsicToken{TokenType::INTRINSIC, "show", Intrinsic::SHOW}}, - {"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}}, +struct VariableToken : Token { + Token value; + inline bool operator==(const VariableToken &right) { + if ((Token) * this == (Token)right && this->value == right.value) + return true; + return false; + } + inline bool operator!=(const VariableToken &right) { + return !(*this == right); + } }; +std::map 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 var_tokens; + int read_file(std::deque args); -int parse_line(std::istream stream); +int parse_line(std::string line); diff --git a/syntax/ceev.vim b/syntax/ceev.vim index e9b52b5..ad25572 100644 --- a/syntax/ceev.vim +++ b/syntax/ceev.vim @@ -3,10 +3,13 @@ if exists("b:current_syntax") | finish | endif set iskeyword=a-z,A-Z,-,*,_,!,@ " 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 ceevConstant Character Location Image +" Includes +syntax region ceevSpecials start="%include" end="$" + " Comments syntax region ceevCommentLine start="//" end="$" contains=ceevTodos @@ -30,6 +33,7 @@ highlight default link ceevConstant Constant highlight default link ceevCommentLine Comment highlight default link ceevString String highlight default link ceevNumber Number +highlight default link ceevSpecials Include highlight default link ceevTypeNames Type highlight default link ceevChar Character highlight default link ceevEscapes SpecialChar