Simplify Object type
This commit is contained in:
parent
eea4aace61
commit
cd7ce538b6
@ -1,18 +1,28 @@
|
|||||||
#include "object.hh"
|
#include "object.hh"
|
||||||
|
|
||||||
void Identifier::write(std::ostream &os) const {
|
Object::Object(StringObjectType string_type, const std::string &value) : str{value} {
|
||||||
os << identifier;
|
switch (string_type) {
|
||||||
};
|
case StringObjectType::IDENTIFIER:
|
||||||
|
type = ObjectType::IDENTIFIER;
|
||||||
void StringLit::write(std::ostream &os) const {
|
break;
|
||||||
os << literal;
|
case StringObjectType::LITERAL:
|
||||||
};
|
type = ObjectType::STRING_LIT;
|
||||||
|
break;
|
||||||
void Number::write(std::ostream &os) const {
|
}
|
||||||
os << number;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, const Object &obj) {
|
std::ostream &operator<<(std::ostream &os, const Object &obj) {
|
||||||
obj.write(os);
|
switch (obj.type) {
|
||||||
|
case ObjectType::NIL:
|
||||||
|
break;
|
||||||
|
case ObjectType::IDENTIFIER:
|
||||||
|
case ObjectType::STRING_LIT:
|
||||||
|
os << obj.str;
|
||||||
|
break;
|
||||||
|
case ObjectType::NUMBER:
|
||||||
|
os << obj.number;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,31 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
enum class StringObjectType : uint8_t {
|
||||||
|
IDENTIFIER,
|
||||||
|
LITERAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ObjectType : uint8_t {
|
||||||
|
NIL,
|
||||||
|
IDENTIFIER,
|
||||||
|
STRING_LIT,
|
||||||
|
NUMBER,
|
||||||
|
};
|
||||||
|
|
||||||
struct Object {
|
struct Object {
|
||||||
Object() = delete;
|
Object() : type{ObjectType::NIL} {};
|
||||||
virtual ~Object() = default;
|
Object(double number) : type{ObjectType::NUMBER}, number{number} {};
|
||||||
virtual void write(std::ostream &os) const = 0;
|
Object(StringObjectType string_type, const std::string &value);
|
||||||
};
|
|
||||||
|
|
||||||
struct Identifier : public Object {
|
ObjectType type;
|
||||||
virtual void write(std::ostream &os) const final;
|
union {
|
||||||
std::string identifier;
|
std::string_view str;
|
||||||
};
|
double number;
|
||||||
|
};
|
||||||
struct StringLit : public Object {
|
|
||||||
virtual void write(std::ostream &os) const final;
|
|
||||||
std::string literal;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Number : public Object {
|
|
||||||
virtual void write(std::ostream &os) const final;
|
|
||||||
double number;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, const Object &obj);
|
std::ostream &operator<<(std::ostream &os, const Object &obj);
|
||||||
|
@ -1,7 +1,53 @@
|
|||||||
#include "scanner.hh"
|
#include "scanner.hh"
|
||||||
#include "token.hh"
|
#include "token.hh"
|
||||||
|
#include "error_handler.hh"
|
||||||
|
#include "object.hh"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
extern ErrorHandler error_handler;
|
||||||
|
|
||||||
std::vector<Token> Scanner::scan_tokens() {
|
std::vector<Token> Scanner::scan_tokens() {
|
||||||
return std::vector<Token>{};
|
while (!is_at_end()) {
|
||||||
|
start = current;
|
||||||
|
scan_token();
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens.push_back(Token(TokenType::EOFILE, "", Object{}, line));
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scanner::is_at_end() {
|
||||||
|
return current >= code.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::scan_token() {
|
||||||
|
char c = advance();
|
||||||
|
switch (c) {
|
||||||
|
case '(': add_token(TokenType::LEFT_PAREN); break;
|
||||||
|
case ')': add_token(TokenType::RIGHT_PAREN); break;
|
||||||
|
case '{': add_token(TokenType::LEFT_BRACE); break;
|
||||||
|
case '}': add_token(TokenType::RIGHT_BRACE); break;
|
||||||
|
case ',': add_token(TokenType::COMMA); break;
|
||||||
|
case '.': add_token(TokenType::DOT); break;
|
||||||
|
case '-': add_token(TokenType::MINUS); break;
|
||||||
|
case '+': add_token(TokenType::PLUS); break;
|
||||||
|
case ';': add_token(TokenType::SEMICOLON); break;
|
||||||
|
case '*': add_token(TokenType::STAR); break;
|
||||||
|
default:
|
||||||
|
error_handler.error(line, "Unexpected character.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Scanner::advance() {
|
||||||
|
return code.at(current++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::add_token(TokenType type) {
|
||||||
|
add_token(type, Object{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scanner::add_token(TokenType type, Object literal) {
|
||||||
|
std::string text = code.substr(start, current - start);
|
||||||
|
tokens.push_back(Token(type, text, literal, line));
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "token.hh"
|
#include "token.hh"
|
||||||
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct Scanner {
|
struct Scanner {
|
||||||
Scanner(const std::string &code) : code{code} {};
|
Scanner(const std::string &code) : code{code}, tokens{}, start{0}, current{0}, line{1} {};
|
||||||
std::vector<Token> scan_tokens();
|
std::vector<Token> scan_tokens();
|
||||||
|
bool is_at_end();
|
||||||
|
void scan_token();
|
||||||
|
char advance();
|
||||||
|
void add_token(TokenType type);
|
||||||
|
void add_token(TokenType type, Object literal);
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
|
std::vector<Token> tokens;
|
||||||
|
std::size_t start, current, line;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,133 @@
|
|||||||
#include "token.hh"
|
#include "token.hh"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const TokenType &type) {
|
||||||
|
switch (type) {
|
||||||
|
case TokenType::LEFT_PAREN:
|
||||||
|
os << "TokenType::LEFT_PAREN";
|
||||||
|
break;
|
||||||
|
case TokenType::RIGHT_PAREN:
|
||||||
|
os << "TokenType::RIGHT_PAREN";
|
||||||
|
break;
|
||||||
|
case TokenType::LEFT_BRACE:
|
||||||
|
os << "TokenType::LEFT_BRACE";
|
||||||
|
break;
|
||||||
|
case TokenType::RIGHT_BRACE:
|
||||||
|
os << "TokenType::RIGHT_BRACE";
|
||||||
|
break;
|
||||||
|
case TokenType::COMMA:
|
||||||
|
os << "TokenType::COMMA";
|
||||||
|
break;
|
||||||
|
case TokenType::DOT:
|
||||||
|
os << "TokenType::DOT";
|
||||||
|
break;
|
||||||
|
case TokenType::MINUS:
|
||||||
|
os << "TokenType::MINUS";
|
||||||
|
break;
|
||||||
|
case TokenType::PLUS:
|
||||||
|
os << "TokenType::PLUS";
|
||||||
|
break;
|
||||||
|
case TokenType::SEMICOLON:
|
||||||
|
os << "TokenType::SEMICOLON";
|
||||||
|
break;
|
||||||
|
case TokenType::SLASH:
|
||||||
|
os << "TokenType::SLASH";
|
||||||
|
break;
|
||||||
|
case TokenType::STAR:
|
||||||
|
os << "TokenType::STAR";
|
||||||
|
break;
|
||||||
|
case TokenType::BANG:
|
||||||
|
os << "TokenType::BANG";
|
||||||
|
break;
|
||||||
|
case TokenType::BANG_EQUAL:
|
||||||
|
os << "TokenType::BANG_EQUAL";
|
||||||
|
break;
|
||||||
|
case TokenType::EQUAL:
|
||||||
|
os << "TokenType::EQUAL";
|
||||||
|
break;
|
||||||
|
case TokenType::EQUAL_EQUAL:
|
||||||
|
os << "TokenType::EQUAL_EQUAL";
|
||||||
|
break;
|
||||||
|
case TokenType::GREATER:
|
||||||
|
os << "TokenType::GREATER";
|
||||||
|
break;
|
||||||
|
case TokenType::GREATER_EQUAL:
|
||||||
|
os << "TokenType::GREATER_EQUAL";
|
||||||
|
break;
|
||||||
|
case TokenType::LESS:
|
||||||
|
os << "TokenType::LESS";
|
||||||
|
break;
|
||||||
|
case TokenType::LESS_EQUAL:
|
||||||
|
os << "TokenType::LESS_EQUAL";
|
||||||
|
break;
|
||||||
|
case TokenType::IDENTIFIER:
|
||||||
|
os << "TokenType::IDENTIFIER";
|
||||||
|
break;
|
||||||
|
case TokenType::STRING:
|
||||||
|
os << "TokenType::STRING";
|
||||||
|
break;
|
||||||
|
case TokenType::NUMBER:
|
||||||
|
os << "TokenType::NUMBER";
|
||||||
|
break;
|
||||||
|
case TokenType::AND:
|
||||||
|
os << "TokenType::AND";
|
||||||
|
break;
|
||||||
|
case TokenType::CLASS:
|
||||||
|
os << "TokenType::CLASS";
|
||||||
|
break;
|
||||||
|
case TokenType::ELSE:
|
||||||
|
os << "TokenType::ELSE";
|
||||||
|
break;
|
||||||
|
case TokenType::FALSE:
|
||||||
|
os << "TokenType::FALSE";
|
||||||
|
break;
|
||||||
|
case TokenType::FUN:
|
||||||
|
os << "TokenType::FUN";
|
||||||
|
break;
|
||||||
|
case TokenType::FOR:
|
||||||
|
os << "TokenType::FOR";
|
||||||
|
break;
|
||||||
|
case TokenType::IF:
|
||||||
|
os << "TokenType::IF";
|
||||||
|
break;
|
||||||
|
case TokenType::NIL:
|
||||||
|
os << "TokenType::NIL";
|
||||||
|
break;
|
||||||
|
case TokenType::OR:
|
||||||
|
os << "TokenType::OR";
|
||||||
|
break;
|
||||||
|
case TokenType::PRINT:
|
||||||
|
os << "TokenType::PRINT";
|
||||||
|
break;
|
||||||
|
case TokenType::RETURN:
|
||||||
|
os << "TokenType::RETURN";
|
||||||
|
break;
|
||||||
|
case TokenType::SUPER:
|
||||||
|
os << "TokenType::SUPER";
|
||||||
|
break;
|
||||||
|
case TokenType::THIS:
|
||||||
|
os << "TokenType::THIS";
|
||||||
|
break;
|
||||||
|
case TokenType::TRUE:
|
||||||
|
os << "TokenType::TRUE";
|
||||||
|
break;
|
||||||
|
case TokenType::VAR:
|
||||||
|
os << "TokenType::VAR";
|
||||||
|
break;
|
||||||
|
case TokenType::WHILE:
|
||||||
|
os << "TokenType::WHILE";
|
||||||
|
break;
|
||||||
|
case TokenType::EOFILE:
|
||||||
|
os << "TokenType::EOFILE";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, const Token &token) {
|
std::ostream &operator<<(std::ostream &os, const Token &token) {
|
||||||
return os << uint8_t(token.type) << ' ' << token.lexeme << ' ' << token.literal;
|
os << token.type << ' ';
|
||||||
|
os << token.lexeme << ' ';
|
||||||
|
os << token.literal;
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
@ -26,14 +26,15 @@ enum class TokenType : uint8_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
Token(TokenType type, const std::string &lexeme, Object &literal, int line)
|
Token(TokenType type, const std::string &lexeme, Object literal, int line)
|
||||||
: type{type}, lexeme{lexeme}, literal{literal}, line{line}
|
: type{type}, lexeme{lexeme}, literal{literal}, line{line}
|
||||||
{};
|
{};
|
||||||
|
|
||||||
TokenType type;
|
TokenType type;
|
||||||
std::string lexeme;
|
std::string lexeme;
|
||||||
Object &literal;
|
Object literal;
|
||||||
int line;
|
int line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const TokenType &type);
|
||||||
std::ostream &operator<<(std::ostream &os, const Token &token);
|
std::ostream &operator<<(std::ostream &os, const Token &token);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user