Restructure a bit

This commit is contained in:
2024-01-07 14:54:46 +01:00
parent 61ee6d10d9
commit 33d07bea37
2 changed files with 260 additions and 225 deletions

View File

@@ -33,6 +33,8 @@ expr
| INT OPERATOR FLOAT {conv($1); $$ = binary_op_float($1, $3, $2);} | INT OPERATOR FLOAT {conv($1); $$ = binary_op_float($1, $3, $2);}
| FLOAT OPERATOR INT {conv($2); $$ = binary_op_float($1, $3, $2);} | FLOAT OPERATOR INT {conv($2); $$ = binary_op_float($1, $3, $2);}
| FLOAT OPERATOR FLOAT {$$ = binary_op_float($1, $3, $2);}; | FLOAT OPERATOR FLOAT {$$ = binary_op_float($1, $3, $2);};
| INT
| FLOAT
============================= */ ============================= */
enum value_type { enum value_type {
@@ -48,34 +50,48 @@ static const char* value_type_str[VALUE_TYPE_COUNT] = {
[VALUE_FLOATING] = "VALUE_FLOATING", [VALUE_FLOATING] = "VALUE_FLOATING",
}; };
static const int operator_precedence[256] = {
['+'] = 0,
['-'] = 0,
['*'] = 10,
['/'] = 10,
};
typedef struct parser {
Token* cur;
Token* next;
Mfile* m;
} Parser;
bool parser_advance(Error* err, Parser* p)
{
p->cur = p->next;
mfile_skip(p->m, isspace);
p->next = token_read(err, p->m);
if (!error_empty(err)) {
error_push(err, "%s failed", __func__);
return false;
}
return true;
}
typedef struct value { typedef struct value {
const char* debug_name; const char* debug_name;
enum value_type type; enum value_type type;
union { union {
int64_t i64; int64_t i64;
char op[3];
double f64; double f64;
char op[3];
}; };
} Value; } Value;
typedef struct symbol_table_entry {
const char* debug_name;
int id;
Value* val;
struct symbol_table_entry* next;
} Symbol_table_entry;
typedef struct symbol_table {
Symbol_table_entry* syms;
} Symbol_table;
static Value* parse_operator(Error* err, Token* t) static Value* parse_operator(Error* err, Token* t)
{ {
if (t->type != TOKEN_OPERATOR) { if (t->type != TOKEN_OPERATOR) {
error_push(err, "%s: unexpected token type: %s", __func__, token_type_str[t->type]); error_push(err, "%s: unexpected token type: %s", __func__, token_type_str[t->type]);
return NULL; return NULL;
} }
Value* v = malloc(sizeof *v); Value* v = calloc(1, sizeof *v);
if (!v) { if (!v) {
error_push(err, "%s: failed to allocate value: %s", __func__, strerror(errno)); error_push(err, "%s: failed to allocate value: %s", __func__, strerror(errno));
return NULL; return NULL;
@@ -91,7 +107,7 @@ static Value* parse_int(Error* err, Token* t)
error_push(err, "%s: unexpected token type: %s", __func__, token_type_str[t->type]); error_push(err, "%s: unexpected token type: %s", __func__, token_type_str[t->type]);
return NULL; return NULL;
} }
Value* v = malloc(sizeof *v); Value* v = calloc(1, sizeof *v);
if (!v) { if (!v) {
error_push(err, "%s: failed to allocate value: %s", __func__, strerror(errno)); error_push(err, "%s: failed to allocate value: %s", __func__, strerror(errno));
return NULL; return NULL;
@@ -110,12 +126,12 @@ static Value* parse_int(Error* err, Token* t)
static Value* parse_floating(Error* err, Token* t) static Value* parse_floating(Error* err, Token* t)
{ {
if (t->type != TOKEN_FLOATING) { if (t->type != TOKEN_FLOATING) {
error_push(err, "%s: unexpected token type: %s", __func__, token_type_str[t->type]); error_push(err, "(%s) unexpected token type: %s", __func__, token_type_str[t->type]);
return NULL; return NULL;
} }
Value* v = malloc(sizeof *v); Value* v = calloc(1, sizeof *v);
if (!v) { if (!v) {
error_push(err, "%s: failed to allocate value: %s", __func__, strerror(errno)); error_push(err, "(%s) failed to allocate value: %s", __func__, strerror(errno));
return NULL; return NULL;
} }
v->type = VALUE_FLOATING; v->type = VALUE_FLOATING;
@@ -123,7 +139,7 @@ static Value* parse_floating(Error* err, Token* t)
errno = 0; errno = 0;
v->f64= strtod(t->start, NULL); v->f64= strtod(t->start, NULL);
if (errno != 0) { if (errno != 0) {
error_push(err, "%s: failed to parse float: %s", __func__, strerror(errno)); error_push(err, "(%s) failed to parse float: %s", __func__, strerror(errno));
return NULL; return NULL;
} }
return v; return v;
@@ -175,7 +191,7 @@ static Value* parse_binary_expr(Error* err, Value* lval, Value* rval, Value* op)
return NULL; return NULL;
} }
Value* result = malloc(sizeof *result); Value* result = calloc(1, sizeof *result);
if (!result) { if (!result) {
error_push(err, "%s: failed to allocate value: %s", __func__, strerror(errno)); error_push(err, "%s: failed to allocate value: %s", __func__, strerror(errno));
return NULL; return NULL;
@@ -222,32 +238,44 @@ static Value* parse_binary_expr(Error* err, Value* lval, Value* rval, Value* op)
return result; return result;
} }
static Value* parser_handle_binary_expr(Error* err, Token* peek, Mfile* m) static Value* parse_expr(Error* err, Parser* p)
{ {
Value* lval = parse_number(err, peek); Value* lval = parse_number(err, p->cur);
if (!error_empty(err) || !lval) { if (!error_empty(err) || !lval) {
goto generic_error; goto generic_error;
} }
Token* op_tok = token_read(err, m);
if (!error_empty(err)) { if (!error_empty(err)) {
goto generic_error; goto generic_error;
} else if (op_tok->type != TOKEN_OPERATOR) { } else if (p->next->type != TOKEN_OPERATOR) {
parser_advance(err, p);
if (!error_empty(err)) {
goto syntax_error; goto syntax_error;
} }
return lval;
}
Value* op = parse_operator(err, op_tok); Value* op = parse_operator(err, p->next);
if (!error_empty(err)) {
goto generic_error;
}
parser_advance(err, p);
if (!error_empty(err)) {
goto generic_error;
}
parser_advance(err, p);
if (!error_empty(err)) { if (!error_empty(err)) {
goto generic_error; goto generic_error;
} }
Token* rval_tok = token_read(err, m);
if (!error_empty(err)) { if (!error_empty(err)) {
goto generic_error; goto generic_error;
} else if (rval_tok->type != TOKEN_INTEGER && rval_tok->type != TOKEN_FLOATING) { } else if (p->cur->type != TOKEN_INTEGER
&& p->cur->type != TOKEN_FLOATING)
{
goto syntax_error; goto syntax_error;
} }
Value* rval = parse_number(err, rval_tok); Value* rval = parse_expr(err, p);
if (!error_empty(err)) { if (!error_empty(err)) {
goto generic_error; goto generic_error;
} }
@@ -264,28 +292,27 @@ generic_error:
return NULL; return NULL;
} }
static Value* parser_next(Error* err, Mfile* m) static Value* parser_next(Error* err, Parser* p)
{ {
mfile_skip(m, isspace); if (p->cur->type == EOF || !error_empty(err)) {
Token* t = token_read(err, m);
if (t->type == EOF) {
return NULL;
} else if (!error_empty(err)) {
return NULL; return NULL;
} }
Value* result; Value* result;
switch (t->type) { switch (p->cur->type) {
case TOKEN_INTEGER: case TOKEN_INTEGER:
case TOKEN_FLOATING: case TOKEN_FLOATING:
{ {
result = parser_handle_binary_expr(err, t, m); result = parse_expr(err, p);
if (!error_empty(err)) { if (!error_empty(err)) {
goto syntax_error; goto syntax_error;
} }
break; break;
} }
default: syntax_error: { default:
error_push(err, "(%s) syntax error: unexpected token %s", __func__, token_type_str[t->type]); syntax_error:
{
error_push(err, "(%s) syntax error: unexpected token %s", __func__, token_type_str[p->cur->type]);
return NULL; return NULL;
} }
} }
@@ -317,8 +344,16 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
Parser p = {
.cur = NULL,
.next = NULL,
.m = m,
};
parser_advance(&err, &p);
parser_advance(&err, &p);
while (!mfile_eof(m)) { while (!mfile_eof(m)) {
parser_next(&err, m); parser_next(&err, &p);
if (!error_empty(&err)) { if (!error_empty(&err)) {
error_print(&err); error_print(&err);
return EXIT_FAILURE; return EXIT_FAILURE;

View File

@@ -1,4 +1,4 @@
1+2 1+2
1 + 4 1 + 4 + 3
5 / 2 5 / 2
1.3 * 2 1.3 * 2