switching to c++
This commit is contained in:
parent
e079f63d27
commit
086315b6ab
12 changed files with 228 additions and 239 deletions
17
makefile
17
makefile
|
|
@ -1,26 +1,23 @@
|
||||||
TARGET := ./target
|
TARGET := ./target
|
||||||
SRC := ./src
|
SRC := ./src
|
||||||
CC := clang -c -std=c17 -Wall -Wextra -pedantic -Werror
|
CC := clang++ -c -std=c++17 -Wall -Wextra -pedantic -Werror
|
||||||
|
|
||||||
SRCS := $(shell find $(SRC) -name '*.c')
|
SRCS := $(shell find $(SRC) -name '*.c')
|
||||||
OBJS := $(SRCS:%=$(TARGET)/%.o)
|
OBJS := $(SRCS:%=$(TARGET)/%.o)
|
||||||
|
|
||||||
$(TARGET)/lox: $(TARGET)/lox.c.o $(TARGET)/parser.c.o $(TARGET)/scanner.c.o $(TARGET)/tokens.c.o $(TARGET)/utils.c.o
|
$(TARGET)/lox: $(TARGET)/lox.cpp.o $(TARGET)/parser.cpp.o $(TARGET)/scanner.cpp.o
|
||||||
clang $(TARGET)/lox.c.o -L$(TARGET) -lparser.c.o -ltokens.c.o -lscanner.c.o -lutils.c.o -o $(TARGET)/lox
|
clang++ $(TARGET)/lox.cpp.o -L$(TARGET) -lscanner.cpp.o -o $(TARGET)/lox
|
||||||
|
|
||||||
$(TARGET)/utils.c.o: $(SRC)/utils.c
|
$(TARGET)/utils.cpp.o: $(SRC)/utils.cpp
|
||||||
$(CC) $< -o $@
|
$(CC) $< -o $@
|
||||||
|
|
||||||
$(TARGET)/tokens.c.o: $(SRC)/tokens.c
|
$(TARGET)/scanner.cpp.o: $(SRC)/scanner.cpp
|
||||||
$(CC) $< -o $@
|
$(CC) $< -o $@
|
||||||
|
|
||||||
$(TARGET)/scanner.c.o: $(SRC)/scanner.c
|
$(TARGET)/parser.cpp.o: $(SRC)/parser.cpp
|
||||||
$(CC) $< -o $@
|
$(CC) $< -o $@
|
||||||
|
|
||||||
$(TARGET)/parser.c.o: $(SRC)/parser.c
|
$(TARGET)/lox.cpp.o: $(SRC)/lox.cpp $(TARGET)
|
||||||
$(CC) $< -o $@
|
|
||||||
|
|
||||||
$(TARGET)/lox.c.o: $(SRC)/lox.c $(TARGET)
|
|
||||||
$(CC) $< -o $@
|
$(CC) $< -o $@
|
||||||
|
|
||||||
$(TARGET):
|
$(TARGET):
|
||||||
|
|
|
||||||
83
src/lox.c
83
src/lox.c
|
|
@ -1,83 +0,0 @@
|
||||||
#include "scanner.h"
|
|
||||||
#include "tokens.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
int run_file(char *file);
|
|
||||||
void run_prompt(void);
|
|
||||||
ScanResult run(char *source);
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if (argc > 2) {
|
|
||||||
puts("Usage: lox [script]");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
} else if (argc == 2) {
|
|
||||||
return run_file(argv[1]);
|
|
||||||
} else {
|
|
||||||
run_prompt();
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int run_file(char *filename) {
|
|
||||||
|
|
||||||
FILE *file = fopen(filename, "r");
|
|
||||||
if (file == NULL) {
|
|
||||||
printf("unable to open file '%s'\n", filename);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
char line[255];
|
|
||||||
|
|
||||||
char *content = malloc(1);
|
|
||||||
if (content == NULL) {
|
|
||||||
puts("Out of memory");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
content[0] = '\0';
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), file)) {
|
|
||||||
content = realloc(content, strlen(content) + strlen(line) + 1);
|
|
||||||
if (content == NULL) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
strcat(content, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
ScanResult scan_result = run(content);
|
|
||||||
|
|
||||||
// FREE UP
|
|
||||||
free(content);
|
|
||||||
|
|
||||||
if (scan_result.had_error) {
|
|
||||||
return 65;
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenlist_print(&scan_result.token_list);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void run_prompt(void) {
|
|
||||||
char line[255];
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
printf(">");
|
|
||||||
char *r = fgets(line, 255, stdin);
|
|
||||||
|
|
||||||
if (r == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int len = (int)strlen(line);
|
|
||||||
ScanResult scan_result = run(substring(line, 1, len - 1));
|
|
||||||
|
|
||||||
tokenlist_print(&scan_result.token_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ScanResult run(char *source) { return scan_tokens(source); }
|
|
||||||
68
src/lox.cpp
Normal file
68
src/lox.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include "scanner.hpp"
|
||||||
|
#include "tokens.hpp"
|
||||||
|
#include <cstdbool>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void print_tokens(std::list<Token> *list);
|
||||||
|
int run_file(std::string file);
|
||||||
|
void run_prompt(void);
|
||||||
|
ScanResult run(std::string source);
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc > 2) {
|
||||||
|
puts("Usage: lox [script]");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else if (argc == 2) {
|
||||||
|
return run_file(argv[1]);
|
||||||
|
} else {
|
||||||
|
run_prompt();
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_file(std::string filename) {
|
||||||
|
std::string content;
|
||||||
|
std::ifstream file;
|
||||||
|
file.open(filename);
|
||||||
|
if (file.is_open()) {
|
||||||
|
file >> content;
|
||||||
|
} else {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanResult scan_result = run(content);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_prompt(void) {
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
std::cout << ">";
|
||||||
|
std::cin >> line;
|
||||||
|
|
||||||
|
ScanResult scan_result = run(line.substr(0, line.length()));
|
||||||
|
|
||||||
|
print_tokens(&scan_result.token_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanResult run(std::string source) { return scan_tokens(source); }
|
||||||
|
|
||||||
|
void print_tokens(std::list<Token> *list) {
|
||||||
|
for (std::list<Token>::iterator token = list->begin(); token != list->end();
|
||||||
|
++token) {
|
||||||
|
|
||||||
|
if (token->literal != NULL) {
|
||||||
|
std::cout << token_name(token->type) << "(" << token->literal << "), ";
|
||||||
|
} else {
|
||||||
|
std::cout << token_name(token->type) << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
21
src/parser.c
21
src/parser.c
|
|
@ -1,21 +0,0 @@
|
||||||
#include "parser.h"
|
|
||||||
#include "tokens.h"
|
|
||||||
|
|
||||||
enum ExprType {
|
|
||||||
Bin,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Binary {
|
|
||||||
Binary *left;
|
|
||||||
Token operator;
|
|
||||||
Binary *right;
|
|
||||||
};
|
|
||||||
|
|
||||||
union Expr {
|
|
||||||
Binary binary;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Expression {
|
|
||||||
enum ExprType type;
|
|
||||||
union Expr expr;
|
|
||||||
};
|
|
||||||
111
src/parser.cpp
Normal file
111
src/parser.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
// #include "tokens.hpp"
|
||||||
|
// #include <stdbool.h>
|
||||||
|
|
||||||
|
// static const TokenType eq[] = {BANG_EQUAL, EQUAL_EQUAL};
|
||||||
|
// static const TokenType comp[] = {GREATER, GREATER_EQUAL, LESS, LESS_EQUAL};
|
||||||
|
// static const TokenType unarytokens[] = {BANG, MINUS};
|
||||||
|
|
||||||
|
// // static int current = -1;
|
||||||
|
// // TokenList *tokens;
|
||||||
|
|
||||||
|
// class Expression;
|
||||||
|
|
||||||
|
// class Binary {
|
||||||
|
// public:
|
||||||
|
// Expression *left;
|
||||||
|
// Token *operator;
|
||||||
|
// Expression *right;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// typedef struct Grouping {
|
||||||
|
// Expression *expr;
|
||||||
|
// } Grouping;
|
||||||
|
|
||||||
|
// typedef struct Unary {
|
||||||
|
// Token *operator;
|
||||||
|
// Expression *expr;
|
||||||
|
// } Unary;
|
||||||
|
|
||||||
|
// class Expression {
|
||||||
|
// public:
|
||||||
|
// enum ExprType { Bin, Grp, Lit, Una } type;
|
||||||
|
// union Expr {
|
||||||
|
// Binary *binary;
|
||||||
|
// Grouping *grouping;
|
||||||
|
// Token *literal;
|
||||||
|
// Unary *unary;
|
||||||
|
// } expr;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// void parse(TokenList *tokenlist) {
|
||||||
|
// tokens = tokenlist;
|
||||||
|
// current = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static Token *peek(void) { return tokenlist_get(tokens, current); }
|
||||||
|
|
||||||
|
// static bool is_at_end(void) { return peek()->type == END_OF_FILE; }
|
||||||
|
|
||||||
|
// static bool check(TokenType type) {
|
||||||
|
// if (is_at_end()) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// return peek()->type == type;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static bool match(const TokenType tokens[], int n) {
|
||||||
|
// for (int i = 0; i < n; i++) {
|
||||||
|
// if (check(tokens[i])) {
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static Token previous(void) {
|
||||||
|
// Token t = {NUMBER, "", 0, 0};
|
||||||
|
// return t;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static Expression unary(void) {
|
||||||
|
// if (match(unarytokens, 2)) {
|
||||||
|
// Token operator= previous();
|
||||||
|
// Expression right = unary();
|
||||||
|
// Expression un;
|
||||||
|
// un.type = Una;
|
||||||
|
// Unary new_una = {&operator, & right };
|
||||||
|
// un.expr.unary = &new_una;
|
||||||
|
// return un;
|
||||||
|
// }
|
||||||
|
// return primary();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static Expression factor(void) {}
|
||||||
|
|
||||||
|
// static Expression term(void) { Expression expr = factor(); }
|
||||||
|
|
||||||
|
// static Expression comparison(void) {
|
||||||
|
// Expression expr = term();
|
||||||
|
// while (match(comp, 4)) {
|
||||||
|
// Token operator= previous();
|
||||||
|
// Expression right = term();
|
||||||
|
|
||||||
|
// Binary new_bin = {&expr, &operator, & right };
|
||||||
|
// expr.expr.binary = &new_bin;
|
||||||
|
// expr.type = Bin;
|
||||||
|
// }
|
||||||
|
// return expr;
|
||||||
|
// }
|
||||||
|
// static Expression equality(void) {
|
||||||
|
// Expression expr = comparison();
|
||||||
|
|
||||||
|
// while (match(eq, 2)) {
|
||||||
|
// Token operator= previous();
|
||||||
|
// Expression right = comparison();
|
||||||
|
// Binary new_bin = {&expr, &operator, & right };
|
||||||
|
// expr.expr.binary = &new_bin;
|
||||||
|
// expr.type = Bin;
|
||||||
|
// }
|
||||||
|
// return expr;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // static Expression expression(void) { return equality(); }
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
typedef struct Binary Binary;
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
#include "scanner.h"
|
#include "scanner.hpp"
|
||||||
#include "tokens.h"
|
#include "tokens.hpp"
|
||||||
#include "utils.h"
|
#include <cstdbool>
|
||||||
#include <stdbool.h>
|
#include <iostream>
|
||||||
#include <stdio.h>
|
#include <list>
|
||||||
#include <stdlib.h>
|
#include <string>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static void scan_token(void);
|
static void scan_token(void);
|
||||||
static void error(char *message);
|
static void error(std::string message);
|
||||||
static void report(char *where, char *message);
|
static void report(std::string where, std::string message);
|
||||||
static bool is_at_end(void);
|
static bool is_at_end(void);
|
||||||
static bool match(char expected);
|
static bool match(char expected);
|
||||||
static char peek(void);
|
static char peek(void);
|
||||||
|
|
@ -18,25 +17,22 @@ static bool is_digit(char c);
|
||||||
static void number(void);
|
static void number(void);
|
||||||
static bool is_alpha(char c);
|
static bool is_alpha(char c);
|
||||||
static bool is_alphanumeric(char c);
|
static bool is_alphanumeric(char c);
|
||||||
static void identifier(void);
|
static void identifier();
|
||||||
|
|
||||||
static bool had_error = false;
|
static bool had_error = false;
|
||||||
static int current_pos = -1;
|
static size_t current_pos = -1;
|
||||||
static int start = -1;
|
static int start = -1;
|
||||||
static int current_line = -1;
|
static int current_line = -1;
|
||||||
static char *source;
|
static std::string source;
|
||||||
static TokenList token_list;
|
static std::list<Token> token_list;
|
||||||
|
|
||||||
ScanResult scan_tokens(char *src) {
|
ScanResult scan_tokens(std::string src) {
|
||||||
current_pos = 0;
|
current_pos = 0;
|
||||||
start = 0;
|
start = 0;
|
||||||
current_line = 1;
|
current_line = 1;
|
||||||
source = src;
|
source = src;
|
||||||
|
|
||||||
tokenlist_init(&token_list);
|
while (current_pos < source.length()) {
|
||||||
int len = (int)strlen(source);
|
|
||||||
|
|
||||||
while (current_pos < len) {
|
|
||||||
start = current_pos;
|
start = current_pos;
|
||||||
scan_token();
|
scan_token();
|
||||||
}
|
}
|
||||||
|
|
@ -53,25 +49,25 @@ ScanResult scan_tokens(char *src) {
|
||||||
static void add_token(TokenType type) {
|
static void add_token(TokenType type) {
|
||||||
Token token;
|
Token token;
|
||||||
token.type = type;
|
token.type = type;
|
||||||
token.lexeme = substring(source, start, current_pos);
|
token.lexeme = source.substr(start, current_pos);
|
||||||
token.literal = NULL;
|
token.literal = NULL;
|
||||||
token.line = current_line;
|
token.line = current_line;
|
||||||
|
|
||||||
tokenlist_add(&token_list, token);
|
token_list.push_front(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_token_with_literal(TokenType type, char *literal) {
|
static void add_token_with_literal(TokenType type, std::string literal) {
|
||||||
Token token;
|
Token token;
|
||||||
token.type = type;
|
token.type = type;
|
||||||
token.lexeme = substring(source, start, current_pos);
|
token.lexeme = source.substr(start, current_pos);
|
||||||
token.literal = literal;
|
token.literal = static_cast<void *>(&literal);
|
||||||
token.line = current_line;
|
token.line = current_line;
|
||||||
|
|
||||||
tokenlist_add(&token_list, token);
|
token_list.push_front(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char advance(void) {
|
static char advance(void) {
|
||||||
char c = source[current_pos++];
|
char c = source.at(current_pos++);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +147,7 @@ static void identifier(void) {
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
char *text = substring(source, start + 1, current_pos - start);
|
std::string text = source.substr(start + 1, current_pos - start);
|
||||||
|
|
||||||
const TokenType *tokentype = get_keyword_token(text);
|
const TokenType *tokentype = get_keyword_token(text);
|
||||||
if (tokentype == NULL) {
|
if (tokentype == NULL) {
|
||||||
|
|
@ -168,8 +164,7 @@ static void number(void) {
|
||||||
advance();
|
advance();
|
||||||
while (is_digit(peek()))
|
while (is_digit(peek()))
|
||||||
advance();
|
advance();
|
||||||
add_token_with_literal(NUMBER,
|
add_token_with_literal(NUMBER, source.substr(start + 1, current_pos - start));
|
||||||
substring(source, start + 1, current_pos - start));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_digit(char c) { return c >= '0' && c <= '9'; }
|
bool is_digit(char c) { return c >= '0' && c <= '9'; }
|
||||||
|
|
@ -188,7 +183,7 @@ void string(void) {
|
||||||
|
|
||||||
advance();
|
advance();
|
||||||
|
|
||||||
char *string = substring(source, start + 2, current_pos - start - 2);
|
std::string string = source.substr(start + 2, current_pos - start - 2);
|
||||||
add_token_with_literal(STRING, string);
|
add_token_with_literal(STRING, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,7 +199,7 @@ static bool match(char expected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static char peek_next(void) {
|
static char peek_next(void) {
|
||||||
if (current_pos + 1 >= (int)strlen(source)) {
|
if (current_pos + 1 >= source.length()) {
|
||||||
return '\0';
|
return '\0';
|
||||||
}
|
}
|
||||||
return source[current_pos + 1];
|
return source[current_pos + 1];
|
||||||
|
|
@ -222,11 +217,12 @@ static bool is_alpha(char c) {
|
||||||
|
|
||||||
static bool is_alphanumeric(char c) { return is_alpha(c) || is_digit(c); }
|
static bool is_alphanumeric(char c) { return is_alpha(c) || is_digit(c); }
|
||||||
|
|
||||||
static bool is_at_end(void) { return current_pos >= (int)strlen(source); }
|
static bool is_at_end(void) { return current_pos >= source.length(); }
|
||||||
|
|
||||||
static void error(char *message) { report("", message); }
|
static void error(std::string message) { report("", message); }
|
||||||
|
|
||||||
static void report(char *where, char *message) {
|
static void report(std::string where, std::string message) {
|
||||||
printf("*[Line %i] Error %s : %s\n", current_line, where, message);
|
std::cout << "*[Line " << current_line << "] Error " << where << " : "
|
||||||
|
<< message << "\n";
|
||||||
had_error = true;
|
had_error = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
#ifndef SCANNER_H
|
#ifndef SCANNER_H
|
||||||
#define SCANNER_H
|
#define SCANNER_H
|
||||||
|
|
||||||
#include "tokens.h"
|
#include "tokens.hpp"
|
||||||
#include <stdbool.h>
|
#include <cstdbool>
|
||||||
#include <string.h>
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool had_error;
|
bool had_error;
|
||||||
TokenList token_list;
|
std::list<Token> token_list;
|
||||||
} ScanResult;
|
} ScanResult;
|
||||||
|
|
||||||
ScanResult scan_tokens(char *source);
|
ScanResult scan_tokens(std::string source);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *key;
|
const std::string key;
|
||||||
const TokenType value;
|
const TokenType value;
|
||||||
} Item;
|
} Item;
|
||||||
|
|
||||||
|
|
@ -23,14 +24,14 @@ static const Item keywords[] = {
|
||||||
{"or", OR}, {"print", PRINT}, {"return", RETURN}, {"super", SUPER},
|
{"or", OR}, {"print", PRINT}, {"return", RETURN}, {"super", SUPER},
|
||||||
{"this", THIS}, {"true", TRUE}, {"var", VAR}, {"while", WHILE}};
|
{"this", THIS}, {"true", TRUE}, {"var", VAR}, {"while", WHILE}};
|
||||||
|
|
||||||
inline static const TokenType *get_keyword_token(char *key) {
|
inline static const TokenType *get_keyword_token(std::string key) {
|
||||||
int low = 0;
|
int low = 0;
|
||||||
int high = sizeof(keywords) / sizeof(Item);
|
int high = sizeof(keywords) / sizeof(Item);
|
||||||
|
|
||||||
while (low < high) {
|
while (low < high) {
|
||||||
int mid = (low + high) / 2;
|
int mid = (low + high) / 2;
|
||||||
|
|
||||||
int c = strcmp(keywords[mid].key, key);
|
int c = keywords[mid].key.compare(key);
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
return &keywords[mid].value;
|
return &keywords[mid].value;
|
||||||
}
|
}
|
||||||
40
src/tokens.c
40
src/tokens.c
|
|
@ -1,40 +0,0 @@
|
||||||
#include "tokens.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
void tokenlist_init(TokenList *list) {
|
|
||||||
list->tokens = malloc(sizeof(Token) * 32);
|
|
||||||
list->size = 0;
|
|
||||||
list->capacity = 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tokenlist_add(TokenList *list, Token value) {
|
|
||||||
if (list->size >= list->capacity) {
|
|
||||||
list->capacity *= 2;
|
|
||||||
list->tokens = realloc(list->tokens, sizeof(Token) * list->capacity);
|
|
||||||
}
|
|
||||||
list->tokens[list->size] = value;
|
|
||||||
list->size += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token *tokenlist_get(TokenList *list, int index) {
|
|
||||||
if (index >= list->size || index < 0) {
|
|
||||||
printf("Index %d out of bounds for list of size %d\n", index, list->size);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return &list->tokens[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void tokenlist_print(TokenList *tokenlist) {
|
|
||||||
for (int i = 0; i < tokenlist->size; i++) {
|
|
||||||
Token *token = tokenlist_get(tokenlist, i);
|
|
||||||
if (token->literal != NULL) {
|
|
||||||
printf("%s(%s), ", token_name(token->type), (char *)token->literal);
|
|
||||||
} else {
|
|
||||||
printf("%s, ", token_name(token->type));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void tokenlist_free(TokenList *list) { free(list->tokens); }
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef TOKENS_H
|
#ifndef TOKENS_H
|
||||||
#define TOKENS_H
|
#define TOKENS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LEFT_PAREN,
|
LEFT_PAREN,
|
||||||
RIGHT_PAREN,
|
RIGHT_PAREN,
|
||||||
|
|
@ -59,25 +61,9 @@ static inline const char *token_name(TokenType type) {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TokenType type;
|
TokenType type;
|
||||||
char *lexeme;
|
std::string lexeme;
|
||||||
void *literal;
|
void *literal;
|
||||||
int line;
|
int line;
|
||||||
} Token;
|
} Token;
|
||||||
|
|
||||||
typedef struct TokenList {
|
|
||||||
Token *tokens;
|
|
||||||
int size;
|
|
||||||
int capacity;
|
|
||||||
} TokenList;
|
|
||||||
|
|
||||||
void tokenlist_init(TokenList *list);
|
|
||||||
|
|
||||||
void tokenlist_add(TokenList *list, Token value);
|
|
||||||
|
|
||||||
Token *tokenlist_get(TokenList *list, int index);
|
|
||||||
|
|
||||||
void tokenlist_print(TokenList *tokenlist);
|
|
||||||
|
|
||||||
void tokenlist_free(TokenList *list);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
19
src/utils.c
19
src/utils.c
|
|
@ -1,19 +0,0 @@
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
char* substring(char* string, int position, int length){
|
|
||||||
char* ptr = malloc(length+1);
|
|
||||||
if (ptr == NULL) {
|
|
||||||
printf("out of memory");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int c;
|
|
||||||
for (c=0; c < length; c+=1){
|
|
||||||
*(ptr+c) = *(string+position-1);
|
|
||||||
string += sizeof(char);
|
|
||||||
}
|
|
||||||
*(ptr+c) = '\0';
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef UTILS_H
|
|
||||||
#define UTILS_H
|
|
||||||
|
|
||||||
char* substring(char* string, int position, int length);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Loading…
Add table
Reference in a new issue