more classes, less C
This commit is contained in:
parent
086315b6ab
commit
07cec15696
4 changed files with 56 additions and 53 deletions
|
|
@ -51,7 +51,10 @@ void run_prompt(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanResult run(std::string source) { return scan_tokens(source); }
|
ScanResult run(std::string source) {
|
||||||
|
Scanner *scanner = new Scanner(source);
|
||||||
|
return scanner->scan_tokens();
|
||||||
|
}
|
||||||
|
|
||||||
void print_tokens(std::list<Token> *list) {
|
void print_tokens(std::list<Token> *list) {
|
||||||
for (std::list<Token>::iterator token = list->begin(); token != list->end();
|
for (std::list<Token>::iterator token = list->begin(); token != list->end();
|
||||||
|
|
|
||||||
|
|
@ -5,33 +5,11 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
static void scan_token(void);
|
Scanner::Scanner(std::string s)
|
||||||
static void error(std::string message);
|
: had_error(false), current_pos(0), start(0), current_line(1), source(s),
|
||||||
static void report(std::string where, std::string message);
|
token_list(std::list<Token>()) {}
|
||||||
static bool is_at_end(void);
|
|
||||||
static bool match(char expected);
|
|
||||||
static char peek(void);
|
|
||||||
static char peek_next(void);
|
|
||||||
static void string(void);
|
|
||||||
static bool is_digit(char c);
|
|
||||||
static void number(void);
|
|
||||||
static bool is_alpha(char c);
|
|
||||||
static bool is_alphanumeric(char c);
|
|
||||||
static void identifier();
|
|
||||||
|
|
||||||
static bool had_error = false;
|
|
||||||
static size_t current_pos = -1;
|
|
||||||
static int start = -1;
|
|
||||||
static int current_line = -1;
|
|
||||||
static std::string source;
|
|
||||||
static std::list<Token> token_list;
|
|
||||||
|
|
||||||
ScanResult scan_tokens(std::string src) {
|
|
||||||
current_pos = 0;
|
|
||||||
start = 0;
|
|
||||||
current_line = 1;
|
|
||||||
source = src;
|
|
||||||
|
|
||||||
|
ScanResult Scanner::scan_tokens() {
|
||||||
while (current_pos < source.length()) {
|
while (current_pos < source.length()) {
|
||||||
start = current_pos;
|
start = current_pos;
|
||||||
scan_token();
|
scan_token();
|
||||||
|
|
@ -41,12 +19,10 @@ ScanResult scan_tokens(std::string src) {
|
||||||
scan_result.token_list = token_list;
|
scan_result.token_list = token_list;
|
||||||
scan_result.had_error = had_error;
|
scan_result.had_error = had_error;
|
||||||
|
|
||||||
// tokenlist_print(&scan_result.token_list);
|
|
||||||
|
|
||||||
return scan_result;
|
return scan_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_token(TokenType type) {
|
void Scanner::add_token(TokenType type) {
|
||||||
Token token;
|
Token token;
|
||||||
token.type = type;
|
token.type = type;
|
||||||
token.lexeme = source.substr(start, current_pos);
|
token.lexeme = source.substr(start, current_pos);
|
||||||
|
|
@ -56,7 +32,7 @@ static void add_token(TokenType type) {
|
||||||
token_list.push_front(token);
|
token_list.push_front(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_token_with_literal(TokenType type, std::string literal) {
|
void Scanner::add_token_with_literal(TokenType type, std::string literal) {
|
||||||
Token token;
|
Token token;
|
||||||
token.type = type;
|
token.type = type;
|
||||||
token.lexeme = source.substr(start, current_pos);
|
token.lexeme = source.substr(start, current_pos);
|
||||||
|
|
@ -66,12 +42,12 @@ static void add_token_with_literal(TokenType type, std::string literal) {
|
||||||
token_list.push_front(token);
|
token_list.push_front(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char advance(void) {
|
char Scanner::advance() {
|
||||||
char c = source.at(current_pos++);
|
char c = source.at(current_pos++);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scan_token(void) {
|
void Scanner::scan_token() {
|
||||||
char c = advance();
|
char c = advance();
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
@ -142,7 +118,7 @@ static void scan_token(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void identifier(void) {
|
void Scanner::identifier() {
|
||||||
while (is_alphanumeric(peek())) {
|
while (is_alphanumeric(peek())) {
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +133,7 @@ static void identifier(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void number(void) {
|
void Scanner::number() {
|
||||||
while (is_digit(peek()))
|
while (is_digit(peek()))
|
||||||
advance();
|
advance();
|
||||||
if (peek() == '.' && is_digit((peek_next())))
|
if (peek() == '.' && is_digit((peek_next())))
|
||||||
|
|
@ -167,9 +143,9 @@ static void number(void) {
|
||||||
add_token_with_literal(NUMBER, source.substr(start + 1, current_pos - start));
|
add_token_with_literal(NUMBER, source.substr(start + 1, current_pos - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_digit(char c) { return c >= '0' && c <= '9'; }
|
bool Scanner::is_digit(char c) { return c >= '0' && c <= '9'; }
|
||||||
|
|
||||||
void string(void) {
|
void Scanner::string() {
|
||||||
while (peek() != '"' && !is_at_end()) {
|
while (peek() != '"' && !is_at_end()) {
|
||||||
if (peek() == '\n')
|
if (peek() == '\n')
|
||||||
current_line += 1;
|
current_line += 1;
|
||||||
|
|
@ -187,7 +163,7 @@ void string(void) {
|
||||||
add_token_with_literal(STRING, string);
|
add_token_with_literal(STRING, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool match(char expected) {
|
bool Scanner::match(char expected) {
|
||||||
if (is_at_end()) {
|
if (is_at_end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -198,30 +174,31 @@ static bool match(char expected) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char peek_next(void) {
|
char Scanner::peek_next() {
|
||||||
if (current_pos + 1 >= source.length()) {
|
if (current_pos + 1 >= source.length()) {
|
||||||
return '\0';
|
return '\0';
|
||||||
}
|
}
|
||||||
return source[current_pos + 1];
|
return source[current_pos + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static char peek(void) {
|
char Scanner::peek() {
|
||||||
if (is_at_end()) {
|
if (is_at_end()) {
|
||||||
return '\0';
|
return '\0';
|
||||||
}
|
}
|
||||||
return source[current_pos];
|
return source[current_pos];
|
||||||
}
|
}
|
||||||
static bool is_alpha(char c) {
|
|
||||||
|
bool Scanner::is_alpha(char c) {
|
||||||
return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
|
return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_alphanumeric(char c) { return is_alpha(c) || is_digit(c); }
|
bool Scanner::is_alphanumeric(char c) { return is_alpha(c) || is_digit(c); }
|
||||||
|
|
||||||
static bool is_at_end(void) { return current_pos >= source.length(); }
|
bool Scanner::is_at_end(void) { return current_pos >= source.length(); }
|
||||||
|
|
||||||
static void error(std::string message) { report("", message); }
|
void Scanner::error(std::string message) { report("", message); }
|
||||||
|
|
||||||
static void report(std::string where, std::string message) {
|
void Scanner::report(std::string where, std::string message) {
|
||||||
std::cout << "*[Line " << current_line << "] Error " << where << " : "
|
std::cout << "*[Line " << current_line << "] Error " << where << " : "
|
||||||
<< message << "\n";
|
<< message << "\n";
|
||||||
had_error = true;
|
had_error = true;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef SCANNER_H
|
#pragma once
|
||||||
#define SCANNER_H
|
|
||||||
|
|
||||||
#include "tokens.hpp"
|
#include "tokens.hpp"
|
||||||
#include <cstdbool>
|
#include <cstdbool>
|
||||||
|
|
@ -11,7 +10,35 @@ typedef struct {
|
||||||
std::list<Token> token_list;
|
std::list<Token> token_list;
|
||||||
} ScanResult;
|
} ScanResult;
|
||||||
|
|
||||||
ScanResult scan_tokens(std::string source);
|
class Scanner {
|
||||||
|
private:
|
||||||
|
bool had_error;
|
||||||
|
size_t current_pos;
|
||||||
|
int start;
|
||||||
|
int current_line;
|
||||||
|
std::string source;
|
||||||
|
std::list<Token> token_list;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Scanner(std::string s);
|
||||||
|
ScanResult scan_tokens();
|
||||||
|
void add_token(TokenType type);
|
||||||
|
void add_token_with_literal(TokenType type, std::string literal);
|
||||||
|
char advance();
|
||||||
|
void scan_token();
|
||||||
|
void identifier();
|
||||||
|
void number();
|
||||||
|
bool is_digit(char c);
|
||||||
|
void string();
|
||||||
|
bool match(char expected);
|
||||||
|
char peek_next();
|
||||||
|
char peek();
|
||||||
|
bool is_alpha(char c);
|
||||||
|
bool is_alphanumeric(char c);
|
||||||
|
bool is_at_end(void);
|
||||||
|
void error(std::string message);
|
||||||
|
void report(std::string where, std::string message);
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const std::string key;
|
const std::string key;
|
||||||
|
|
@ -43,4 +70,3 @@ inline static const TokenType *get_keyword_token(std::string key) {
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#ifndef TOKENS_H
|
#pragma once
|
||||||
#define TOKENS_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
@ -65,5 +64,3 @@ typedef struct {
|
||||||
void *literal;
|
void *literal;
|
||||||
int line;
|
int line;
|
||||||
} Token;
|
} Token;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue