restructuring, precomp
This commit is contained in:
parent
cef7b2bc82
commit
83a0cee3e3
|
@ -73,7 +73,9 @@ int _dynarray_pop(void* arr, void* dest) {
|
||||||
if (dynarray_length(arr) < 1) {
|
if (dynarray_length(arr) < 1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy(dest, arr + (dynarray_length(arr) - 1) * dynarray_stride(arr), dynarray_stride(arr));
|
if (dest) {
|
||||||
|
memcpy(dest, arr + (dynarray_length(arr) - 1) * dynarray_stride(arr), dynarray_stride(arr));
|
||||||
|
}
|
||||||
_dynarray_field_set(arr, LENGTH,
|
_dynarray_field_set(arr, LENGTH,
|
||||||
dynarray_length(arr) - 1); // Decrement length.
|
dynarray_length(arr) - 1); // Decrement length.
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef _H_MORPH_PARSER
|
|
||||||
#define _H_MORPH_PARSER
|
|
||||||
|
|
||||||
#include "ast.h"
|
|
||||||
#include "token.h"
|
|
||||||
program_t parse(const token_t* tokens);
|
|
||||||
|
|
||||||
#endif // _H_MORPH_PARSER
|
|
13
src/include/parser/parser.h
Normal file
13
src/include/parser/parser.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef _H_MORPH_PARSER
|
||||||
|
#define _H_MORPH_PARSER
|
||||||
|
|
||||||
|
#include <parser/ast.h>
|
||||||
|
#include <token.h>
|
||||||
|
program_t parse(const token_t* tokens);
|
||||||
|
|
||||||
|
typedef struct parser_state_s {
|
||||||
|
program_t prog;
|
||||||
|
token_t curr_tok;
|
||||||
|
token_t* tokens;
|
||||||
|
} parser_state_t;
|
||||||
|
#endif // _H_MORPH_PARSER
|
6
src/include/parser/precomp.h
Normal file
6
src/include/parser/precomp.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef _H_MORPH_PARSER_PRECOMP
|
||||||
|
#define _H_MORPH_PARSER_PRECOMP
|
||||||
|
|
||||||
|
#include <token.h>
|
||||||
|
int compile_value(token_t* tokens);
|
||||||
|
#endif // _H_MORPH_PARSER_PRECOMP
|
15
src/include/parser/tokcmp.h
Normal file
15
src/include/parser/tokcmp.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef _H_MORPH_PARSER_TOKCMP
|
||||||
|
#define _H_MORPH_PARSER_TOKCMP
|
||||||
|
|
||||||
|
#include <parser/parser.h>
|
||||||
|
#include <token.h>
|
||||||
|
token_t* expect_token_type(parser_state_t* state, token_type_t type);
|
||||||
|
token_t* expect_token_type_mul(parser_state_t* state, token_type_t types[], int type_count);
|
||||||
|
token_t* expect_token_type_ex(parser_state_t* state, token_type_t type, int inner_type);
|
||||||
|
|
||||||
|
// Tests token type, and inner type, so like, op type, kw type, etc.
|
||||||
|
// Does not edit state.curr_tok
|
||||||
|
token_t* test_token_type_ex(parser_state_t* state, token_type_t tok_type, int gen_type);
|
||||||
|
token_t* test_token_type(parser_state_t* state, token_type_t tok_type);
|
||||||
|
|
||||||
|
#endif // _H_MORPH_PARSER_TOKCMP
|
|
@ -15,6 +15,7 @@ typedef enum token_type_e {
|
||||||
TT_PUSH_CHAR,
|
TT_PUSH_CHAR,
|
||||||
TT_PUSH_INT,
|
TT_PUSH_INT,
|
||||||
TT_PUSH_FLOAT,
|
TT_PUSH_FLOAT,
|
||||||
|
TT_PUSH_BOOL,
|
||||||
TT_IDENT
|
TT_IDENT
|
||||||
} token_type_t;
|
} token_type_t;
|
||||||
|
|
||||||
|
@ -52,12 +53,14 @@ typedef enum op_type_e {
|
||||||
OP_GE,
|
OP_GE,
|
||||||
OP_LE,
|
OP_LE,
|
||||||
OP_NE,
|
OP_NE,
|
||||||
|
OP_AND,
|
||||||
|
OP_OR,
|
||||||
|
|
||||||
// Bit manipulation
|
// Bit manipulation
|
||||||
OP_SHR,
|
OP_SHR,
|
||||||
OP_SHL,
|
OP_SHL,
|
||||||
OP_OR,
|
OP_BOR,
|
||||||
OP_AND,
|
OP_BAND,
|
||||||
OP_NOT,
|
OP_NOT,
|
||||||
|
|
||||||
// stack ops
|
// stack ops
|
||||||
|
@ -114,6 +117,7 @@ typedef struct token_s {
|
||||||
// NOTE: For PUSH_MEM. It will push the offset of the memory,
|
// NOTE: For PUSH_MEM. It will push the offset of the memory,
|
||||||
// that is assigned for that specific memory, from the `memory` label.
|
// that is assigned for that specific memory, from the `memory` label.
|
||||||
size_t offset_v;
|
size_t offset_v;
|
||||||
|
bool bool_v;
|
||||||
double float_v;
|
double float_v;
|
||||||
};
|
};
|
||||||
} token_t;
|
} token_t;
|
||||||
|
|
|
@ -3,66 +3,13 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <token.h>
|
#include <token.h>
|
||||||
#include <ast.h>
|
|
||||||
#include <dynarray.h>
|
#include <dynarray.h>
|
||||||
#include <parser.h>
|
#include <parser/parser.h>
|
||||||
|
#include <parser/precomp.h>
|
||||||
typedef struct parser_state_s {
|
#include <parser/tokcmp.h>
|
||||||
program_t prog;
|
#include <parser/ast.h>
|
||||||
token_t curr_tok;
|
|
||||||
token_t* tokens;
|
|
||||||
} parser_state_t;
|
|
||||||
|
|
||||||
token_t* expect_token_type(parser_state_t* state, token_type_t type) {
|
|
||||||
const char* exoected_type_str = get_tok_type_str_dbg(state->curr_tok.type);
|
|
||||||
if (dynarray_pop(state->tokens, &state->curr_tok) != 0) {
|
|
||||||
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got nothing.", exoected_type_str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (state->curr_tok.type != type) {
|
|
||||||
const char* s1 = get_tok_str_dbg(&state->curr_tok);
|
|
||||||
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got %s.", exoected_type_str, s1);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return &state->curr_tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
token_t* expect_token_type_ex(parser_state_t* state, token_type_t type, int inner_type) {
|
|
||||||
const char* exoected_type_str = get_tok_type_str_dbg(state->curr_tok.type);
|
|
||||||
if (dynarray_pop(state->tokens, &state->curr_tok) != 0) {
|
|
||||||
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got nothing.", exoected_type_str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// NOTE: all inner types are in a union
|
|
||||||
if (state->curr_tok.type != type || state->curr_tok.kw_type != inner_type) {
|
|
||||||
const char* s1 = get_tok_str_dbg(&state->curr_tok);
|
|
||||||
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got %s.", exoected_type_str, s1);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return &state->curr_tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests token type, and inner type, so like, op type, kw type, etc.
|
|
||||||
// Does not edit state.curr_tok
|
|
||||||
token_t* test_token_type_ex(parser_state_t* state, token_type_t tok_type, int gen_type) {
|
|
||||||
const char* exoected_type_str = get_tok_type_str_dbg(state->curr_tok.type);
|
|
||||||
token_t* token = &state->tokens[dynarray_length(state->tokens - 1)];
|
|
||||||
// NOTE: tests inner type in a generic way
|
|
||||||
if (token->type != tok_type || ((int)token->kw_type) != gen_type) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
token_t* test_token_type(parser_state_t* state, token_type_t tok_type) {
|
|
||||||
const char* exoected_type_str = get_tok_type_str_dbg(state->curr_tok.type);
|
|
||||||
token_t* token = &state->tokens[dynarray_length(state->tokens - 1)];
|
|
||||||
if (token->type != tok_type) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _parse(parser_state_t* state);
|
int _parse(parser_state_t* state);
|
||||||
|
|
||||||
|
@ -128,4 +75,5 @@ int _parse(parser_state_t* state) {
|
||||||
assert(true && "TODO: parse all kw's");
|
assert(true && "TODO: parse all kw's");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
594
src/parser/precomp.c
Normal file
594
src/parser/precomp.c
Normal file
|
@ -0,0 +1,594 @@
|
||||||
|
#include "loc.h"
|
||||||
|
#include "logger.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <token.h>
|
||||||
|
#include <dynarray.h>
|
||||||
|
#include <parser/parser.h>
|
||||||
|
#include <parser/precomp.h>
|
||||||
|
#include <parser/tokcmp.h>
|
||||||
|
#include <parser/ast.h>
|
||||||
|
|
||||||
|
// compiles values in the token list, will error if invalid tokens
|
||||||
|
int compile_value(token_t* tokens) {
|
||||||
|
// 'f' for float, 'i' for int, 's' for string, 'c' for char
|
||||||
|
char exclusive_type = '\0';
|
||||||
|
token_t* tmp_toks = dynarray_create(token_t);
|
||||||
|
token_t tok = {0};
|
||||||
|
parser_state_t ps = {0};
|
||||||
|
ps.tokens = tokens;
|
||||||
|
while (dynarray_pop(tokens, &tok) == 0) {
|
||||||
|
switch (tok.type) {
|
||||||
|
case (TT_PUSH_CSTR):
|
||||||
|
case (TT_PUSH_STR): {
|
||||||
|
// TODO: Add C style string literall joining
|
||||||
|
if (dynarray_length(tokens) != 0) {
|
||||||
|
log_error(&tok.loc, "Constants do not support C style string literal joining yet");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_push(tmp_toks, tok);
|
||||||
|
}; break;
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
case (TT_PUSH_FLOAT):
|
||||||
|
case (TT_PUSH_CHAR):
|
||||||
|
case (TT_PUSH_BOOL):
|
||||||
|
case (TT_PUSH_MEM): {
|
||||||
|
dynarray_push(tmp_toks, tok);
|
||||||
|
}; break;
|
||||||
|
case (TT_KW): {
|
||||||
|
// TODO: Support if statements in constants at compile time against other constants
|
||||||
|
log_error(&tok.loc, "Keywords are currently not supported in constants");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case (TT_IDENT): {
|
||||||
|
// TODO: Support having other constants as arguments in constants, and memory values for making offsets
|
||||||
|
log_error(&tok.loc, "Identifiers are currently not supported in constants");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case (TT_OP): {
|
||||||
|
switch (tok.op_type) {
|
||||||
|
case (OP_ADD): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == TT_PUSH_INT && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v + t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_FLOAT && t2->type == TT_PUSH_FLOAT) {
|
||||||
|
double_t val = t1->float_v + t2->float_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_FLOAT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_MEM && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v + t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be added together", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_SUB): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == TT_PUSH_INT && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v - t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_FLOAT && t2->type == TT_PUSH_FLOAT) {
|
||||||
|
double_t val = t1->float_v - t2->float_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_FLOAT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_MEM && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v - t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be subtracted from eachother", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_MUL): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == TT_PUSH_INT && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v * t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_FLOAT && t2->type == TT_PUSH_FLOAT) {
|
||||||
|
double_t val = t1->float_v * t2->float_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_FLOAT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_MEM && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v * t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be multiplied together", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_DIV): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == TT_PUSH_INT && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v / t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_FLOAT && t2->type == TT_PUSH_FLOAT) {
|
||||||
|
double_t val = t1->float_v / t2->float_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_FLOAT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
|
||||||
|
} else if (t1->type == TT_PUSH_MEM && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v / t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be divided", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_MOD): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == TT_PUSH_INT && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v % t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else if (t1->type == TT_PUSH_MEM && t2->type == TT_PUSH_INT) {
|
||||||
|
size_t val = t1->int_v % t2->int_v;
|
||||||
|
loc_t loc = t1->loc;
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be modulo'd together", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_EQ): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v == t2->int_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CSTR):
|
||||||
|
case (TT_PUSH_STR):
|
||||||
|
val = strcmp(t1->str_v, t2->str_v) == 0;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_FLOAT):
|
||||||
|
val = t1->float_v == t2->float_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CHAR):
|
||||||
|
val = t1->char_v == t2->char_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_GT): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v > t2->int_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_FLOAT):
|
||||||
|
val = t1->float_v > t2->float_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CHAR):
|
||||||
|
val = t1->char_v > t2->char_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_LT): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v < t2->int_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_FLOAT):
|
||||||
|
val = t1->float_v < t2->float_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CHAR):
|
||||||
|
val = t1->char_v < t2->char_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_GE): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v >= t2->int_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_FLOAT):
|
||||||
|
val = t1->float_v >= t2->float_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CHAR):
|
||||||
|
val = t1->char_v >= t2->char_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_LE): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v <= t2->int_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_FLOAT):
|
||||||
|
val = t1->float_v <= t2->float_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CHAR):
|
||||||
|
val = t1->char_v <= t2->char_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_NE): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v != t2->int_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CSTR):
|
||||||
|
case (TT_PUSH_STR):
|
||||||
|
val = strcmp(t1->str_v, t2->str_v) != 0;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_FLOAT):
|
||||||
|
val = t1->float_v != t2->float_v;
|
||||||
|
break;
|
||||||
|
case (TT_PUSH_CHAR):
|
||||||
|
val = t1->char_v != t2->char_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be compared", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_SHR): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
size_t val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v >> t2->int_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be SHR'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be SHR'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_SHL): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
size_t val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v << t2->int_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be SHL'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be SHL'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_BOR): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
size_t val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v | t2->int_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be BOR'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be BOR'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_BAND): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
size_t val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->int_v & t2->int_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be BAND'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_INT, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be BAND'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_NOT): {
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = !t1->bool_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
log_error(&t1->loc, "Tokens %s cannot be negated", s1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
}; break;
|
||||||
|
case (OP_AND): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->bool_v && t2->bool_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be AND'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be SHL'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
case (OP_OR): {
|
||||||
|
token_t* t2 = &tmp_toks[dynarray_length(tmp_toks - 1)];
|
||||||
|
token_t* t1 = &tmp_toks[dynarray_length(tmp_toks - 2)];
|
||||||
|
if (t1->type == t2->type) {
|
||||||
|
bool val = 0;
|
||||||
|
switch (t1->type) {
|
||||||
|
case (TT_PUSH_INT):
|
||||||
|
val = t1->bool_v || t2->bool_v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be AND'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
dynarray_pop(tokens, NULL);
|
||||||
|
token_t tok = {.type = TT_PUSH_BOOL, .int_v = val, .loc = t1->loc};
|
||||||
|
dynarray_push(tokens, tok);
|
||||||
|
} else {
|
||||||
|
const char* s1 = get_tok_str_dbg(t1);
|
||||||
|
const char* s2 = get_tok_str_dbg(t2);
|
||||||
|
log_error(&t1->loc, "Tokens %s and %s cannot be SHL'd", s1, s2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}; break;
|
||||||
|
default:
|
||||||
|
const char* s1 = get_tok_str_dbg(&tok);
|
||||||
|
log_error(&tok.loc, "Using %s is not allowed in Constants", s1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case (TT_NONE):
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
81
src/parser/tokcmp.c
Normal file
81
src/parser/tokcmp.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#include "logger.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <token.h>
|
||||||
|
#include <dynarray.h>
|
||||||
|
#include <parser/parser.h>
|
||||||
|
#include <parser/precomp.h>
|
||||||
|
#include <parser/tokcmp.h>
|
||||||
|
#include <parser/ast.h>
|
||||||
|
|
||||||
|
token_t* expect_token_type(parser_state_t* state, token_type_t type) {
|
||||||
|
const char* exoected_type_str = get_tok_type_str_dbg(type);
|
||||||
|
if (dynarray_pop(state->tokens, &state->curr_tok) != 0) {
|
||||||
|
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got nothing.", exoected_type_str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (state->curr_tok.type != type) {
|
||||||
|
const char* s1 = get_tok_str_dbg(&state->curr_tok);
|
||||||
|
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got %s.", exoected_type_str, s1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &state->curr_tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
token_t* expect_token_type_mul(parser_state_t* state, token_type_t types[], int type_count) {
|
||||||
|
|
||||||
|
char* expected_type_str = malloc(1024 * 4);
|
||||||
|
int offset = 0;
|
||||||
|
for (int i = 0; i < type_count; i++) {
|
||||||
|
offset += snprintf(expected_type_str + offset, 1024, " %s", get_tok_type_str_dbg(types[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynarray_pop(state->tokens, &state->curr_tok) != 0) {
|
||||||
|
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got nothing.", expected_type_str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < type_count; i++) {
|
||||||
|
if (state->curr_tok.type == types[i]) {
|
||||||
|
return &state->curr_tok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char* s1 = get_tok_str_dbg(&state->curr_tok);
|
||||||
|
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got %s.", expected_type_str, s1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
token_t* expect_token_type_ex(parser_state_t* state, token_type_t type, int inner_type) {
|
||||||
|
const char* exoected_type_str = get_tok_type_str_dbg(state->curr_tok.type);
|
||||||
|
if (dynarray_pop(state->tokens, &state->curr_tok) != 0) {
|
||||||
|
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got nothing.", exoected_type_str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// NOTE: all inner types are in a union
|
||||||
|
if (state->curr_tok.type != type || state->curr_tok.kw_type != inner_type) {
|
||||||
|
const char* s1 = get_tok_str_dbg(&state->curr_tok);
|
||||||
|
log_error(&state->curr_tok.loc, "Invalid word, expected %s, got %s.", exoected_type_str, s1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &state->curr_tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
token_t* test_token_type_ex(parser_state_t* state, token_type_t tok_type, int gen_type) {
|
||||||
|
const char* exoected_type_str = get_tok_type_str_dbg(state->curr_tok.type);
|
||||||
|
token_t* token = &state->tokens[dynarray_length(state->tokens - 1)];
|
||||||
|
// NOTE: tests inner type in a generic way
|
||||||
|
if (token->type != tok_type || ((int)token->kw_type) != gen_type) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
token_t* test_token_type(parser_state_t* state, token_type_t tok_type) {
|
||||||
|
const char* exoected_type_str = get_tok_type_str_dbg(state->curr_tok.type);
|
||||||
|
token_t* token = &state->tokens[dynarray_length(state->tokens - 1)];
|
||||||
|
if (token->type != tok_type) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
|
@ -20,6 +20,8 @@ const char* OP_LIST[] = {
|
||||||
[OP_NE] = "ne",
|
[OP_NE] = "ne",
|
||||||
[OP_SHR] = "shr",
|
[OP_SHR] = "shr",
|
||||||
[OP_SHL] = "shl",
|
[OP_SHL] = "shl",
|
||||||
|
[OP_BOR] = "bor",
|
||||||
|
[OP_BAND] = "band",
|
||||||
[OP_OR] = "or",
|
[OP_OR] = "or",
|
||||||
[OP_AND] = "and",
|
[OP_AND] = "and",
|
||||||
[OP_NOT] = "not",
|
[OP_NOT] = "not",
|
||||||
|
@ -78,6 +80,7 @@ const char* get_tok_type_str_dbg(token_type_t tok_t) {
|
||||||
case (TT_PUSH_CSTR): return "CString";
|
case (TT_PUSH_CSTR): return "CString";
|
||||||
case (TT_PUSH_MEM): return "Memory address";
|
case (TT_PUSH_MEM): return "Memory address";
|
||||||
case (TT_PUSH_FLOAT): return "Float";
|
case (TT_PUSH_FLOAT): return "Float";
|
||||||
|
case (TT_PUSH_BOOL): return "Bool";
|
||||||
case (TT_NONE): assert(true && "Invalid");
|
case (TT_NONE): assert(true && "Invalid");
|
||||||
}
|
}
|
||||||
return "Unreachable";
|
return "Unreachable";
|
||||||
|
@ -119,6 +122,9 @@ const char* get_tok_str_dbg(token_t* tok) {
|
||||||
case (TT_PUSH_FLOAT): {
|
case (TT_PUSH_FLOAT): {
|
||||||
snprintf(buf, buf_size, "%f", tok->float_v);
|
snprintf(buf, buf_size, "%f", tok->float_v);
|
||||||
}; break;
|
}; break;
|
||||||
|
case (TT_PUSH_BOOL): {
|
||||||
|
snprintf(buf, buf_size, "%b", tok->bool_v);
|
||||||
|
}; break;
|
||||||
case (TT_NONE): assert(true && "Invalid");
|
case (TT_NONE): assert(true && "Invalid");
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user