#include "parser.h"
#include "macros.h"
#include <ctype.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
#define JUSTDO(a) \
if (!(a)) { \
perror(#a); \
exit(1); \
}
array_t *STACK;
array_t *EVAL_STACK;
ht_t *WORD_TABLE;
char *INBUF;
parser_t *PARSER;
array_t *init_array(size_t size) {
array_t *a = calloc(1, sizeof(array_t));
a->size = 0;
a->capacity = size;
a->items = calloc(a->capacity, sizeof(value_t *));
return a;
}
void array_append(array_t *a, value_t *v) {
if (a->size >= a->capacity - 2) {
a->capacity = a->capacity * 2;
a->items = realloc(a->items, a->capacity * sizeof(value_t *));
}
a->items[a->size] = v;
a->size++;
}
value_t *array_pop(array_t *a) {
if (a->size > 0) {
value_t *v = a->items[a->size - 1];
a->size--;
return v;
}
return NULL;
}
void array_extend(array_t *a, array_t *b) {
for (int i = 0; i < b->size; i++) {
array_append(a, b->items[i]);
}
}
void array_free(array_t *a) {
for (int i = 0; i < a->size; i++) {
value_free(a->items[i]);
}
free(a->items);
free(a);
}
array_t *array_copy(array_t *a) {
array_t *b = calloc(1, sizeof(array_t));
b->size = a->size;
b->capacity = a->capacity;
b->items = calloc(b->capacity, sizeof(value_t *));
for (int i = 0; i < a->size; i++) {
b->items[i] = value_copy(a->items[i]);
}
return b;
}
value_t *init_value(int type) {
value_t *v = calloc(1, sizeof(value_t));
v->type = type;
v->escaped = false;
return v;
}
value_t *value_copy(value_t *v) {
value_t *a = init_value(VINT);
a->type = v->type;
if (v->type == VINT || v->type == VFLOAT) {
a->int_float = v->int_float;
} else if (v->type == VSTR || v->type == VWORD) {
a->str_word = string_copy(v->str_word);
a->escaped = v->escaped;
} else if (v->type == VQUOTE) {
a->quote = array_copy(v->quote);
}
return a;
}
void value_free(value_t *v) {
if (v->type == VSTR || v->type == VWORD) {
string_free(v->str_word);
}
if (v->type == VQUOTE) {
array_free(v->quote);
}
free(v);
}
parser_t *init_parser(char *source) {
parser_t *p = calloc(1, sizeof(parser_t));
p->i = 0;
p->source = source;
p->c = source[0];
return p;
}
void parser_reset(parser_t *p, char *source) {
p->source = source;
p->i = 0;
p->c = source[0];
}
void parser_move(parser_t *p) {
if (p->i < strlen(p->source) && p->c != '\0') {
p->i++;
p->c = p->source[p->i];
}
}
void parser_skip_whitespace(parser_t *p) {
while (isspace(p->c)) {
parser_move(p);
}
}
value_t *parse_string(parser_t *p) {
value_t *retv = init_value(VSTR);
parser_move(p);
string_t *s = init_string(NULL);
bool escaped = false;
while (escaped || p->c != '"' && p->c != '\0') {
if (p->c == '\\') {
escaped = true;
parser_move(p
|