Simplify Object type

This commit is contained in:
Abdelrahman Said 2025-06-08 15:08:45 +01:00
parent eea4aace61
commit cd7ce538b6
6 changed files with 232 additions and 35 deletions

View File

@ -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;
} }

View File

@ -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;
};
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; double number;
}; };
};
std::ostream &operator<<(std::ostream &os, const Object &obj); std::ostream &operator<<(std::ostream &os, const Object &obj);

View File

@ -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));
} }

View File

@ -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;
}; };

View File

@ -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;
} }

View File

@ -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);