Simplify Object type
This commit is contained in:
		@@ -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);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user