Skip to content

Commit

Permalink
Merge pull request #34 from Ricardicus/prioqueue
Browse files Browse the repository at this point in the history
Priority queue data type
  • Loading branch information
Ricardicus authored Dec 23, 2023
2 parents 54ab0ba + e614db1 commit dae1f64
Show file tree
Hide file tree
Showing 24 changed files with 2,075 additions and 1,478 deletions.
4 changes: 3 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ RIC_SOURCES = \
dl \
interpret \
print \
prioqueue \
$(LIB_DIR)/libio \
$(LIB_DIR)/libmath \
$(LIB_DIR)/libstd \
Expand All @@ -47,7 +48,8 @@ RIC_SOURCES = \
$(LIB_DIR)/libctx \
$(LIB_DIR)/libjson \
$(LIB_DIR)/libbigint \
$(LIB_DIR)/libcrypto
$(LIB_DIR)/libcrypto \
$(LIB_DIR)/libprioqueue

UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
Expand Down
26 changes: 24 additions & 2 deletions src/ast.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "ast.h"
#include "eval.h"
#include "hashtable.h"
#include "prioqueue.h"

extern int yylinenor;
extern char *ParsedFile;
Expand Down Expand Up @@ -275,13 +276,22 @@ expr_t *newExpr_Cachepot() {
cachepot_t *cachepot = ast_emalloc(sizeof(expr_t));

cachepot->hash = hashtable_new(CACHEPOT_STANDARD_SIZE, CACHEPOT_STANDARD_LOAD);

expr->type = EXPR_TYPE_CACHEPOT;
expr->cachepot = cachepot;

return expr;
}

expr_t *newExpr_PriorityQueue(int capacity, int is_minimum) {
expr_t *expr = ast_emalloc(sizeof(expr_t));
priority_queue_t *prioqueue = new_priority_queue(capacity, is_minimum);

expr->type = EXPR_TYPE_PRIOQUEUE;
expr->prioqueue = prioqueue;

return expr;
}

expr_t *newExpr_Text(char *text) {
size_t textLen = strlen(text);
expr_t *expr = ast_emalloc(sizeof(expr_t));
Expand Down Expand Up @@ -585,6 +595,16 @@ expr_t *newExpr_Copy(expr_t *expr, int alloc, EXPRESSION_PARAMS()) {
newExp->dict = copyNewDictionary(expr->dict, EXPRESSION_ARGS());
}
} break;
case EXPR_TYPE_PRIOQUEUE: {
priority_queue_t *pq = expr->prioqueue;
newExp = newExpr_PriorityQueue(pq->capacity, pq->minimum);
newExp->prioqueue->size = pq->size;
for (int i = 0; i < pq->size; i++) {
newExp->prioqueue->items[i].value =
newExpr_Copy(pq->items[i].value, alloc, EXPRESSION_ARGS());
newExp->prioqueue->items[i].priority = pq->items[i].priority;
}
} break;
case EXPR_TYPE_EMPTY:
default:
break;
Expand Down Expand Up @@ -826,6 +846,9 @@ void free_expression(expr_t *expr) {
free_expression((expr_t *)expr->add.right);
break;
} break;
case EXPR_TYPE_PRIOQUEUE: {
free_priority_queue(expr->prioqueue);
} break;
case EXPR_TYPE_OPDIV: {
free_expression((expr_t *)expr->add.left);
free_expression((expr_t *)expr->add.right);
Expand Down Expand Up @@ -895,7 +918,6 @@ void free_expression(expr_t *expr) {
v = v->next;
free(p);
++vecWalk;
// printf("(2.1)\n");
}

if (vec->forEach != NULL) {
Expand Down
103 changes: 63 additions & 40 deletions src/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#define EXPR_TYPE_BIGINT 26
#define EXPR_TYPE_CLASSACCESSER 27
#define EXPR_TYPE_CACHEPOT 28
#define EXPR_TYPE_PRIOQUEUE 29

#define LANG_ENTITY_DECL 1
#define LANG_ENTITY_ARGS 2
Expand Down Expand Up @@ -95,16 +96,13 @@
// Max number of input arguments
#define MAX_NBR_ARGUMENTS 10
// Max number of locals that can be defined at the same time
#define MAX_NBR_LOCALS 1024
#define MAX_NBR_LOCALS 4096
// Maximum body depth
#define MAX_BODY_LEVELS 30 // If you need more; I am sorry.
// Number of elements on the stack of this interpreter (arbitrary number?)
#define RIC_STACKSIZE 1024
// Number of elements on the heap of this interpreter (arbitrary number?)
#define RIC_HEAPSIZE 4096
// maximum number of variables in the langauge, need to be known by current
// garbage collector algorithm (making a list of all active)
#define RIC_MAX_NBR_VARS 4096
#define RIC_HEAPSIZE 8096
// Big integers max size (in character width base 10)
#define RIC_BIG_INT_MAX_SIZE 4096

Expand Down Expand Up @@ -211,6 +209,9 @@ typedef struct dictionary {
int type;
} dictionary_t;

typedef struct priority_queue_item priority_queue_item;
typedef struct priority_queue priority_queue_t;

typedef struct cachepot {
hashtable_t *hash;
} cachepot_t;
Expand Down Expand Up @@ -243,6 +244,7 @@ typedef struct expr_s {
mpz_t *bigInt;
classAccesser_t *classAccess;
cachepot_t *cachepot;
priority_queue_t *prioqueue;
};
} expr_t;

Expand Down Expand Up @@ -376,6 +378,7 @@ expr_t *newExpr_BigIntFromStr(const char *intStr);
expr_t *newExpr_BigIntFromInt(intptr_t val);
expr_t *newExpr_BigInt(mpz_t *n);
expr_t *newExpr_Cachepot();
expr_t *newExpr_PriorityQueue(int capacity, int is_minimum);
expr_t *newClassAccesser(expr_t *classID, char *memberID);
expr_t *newConditional(int type, expr_t *left, expr_t *right);

Expand Down Expand Up @@ -413,7 +416,8 @@ typedef enum stackvaltypes {
RAWDATATYPE,
INDEXER,
BIGINT,
CACHEPOT
CACHEPOT,
PRIOQUEUE
} stackvaltypes_t;

typedef struct stackval {
Expand All @@ -433,6 +437,7 @@ typedef struct stackval {
indexer_t *indexer;
mpz_t *bigInt;
cachepot_t *cachepot;
priority_queue_t *prioqueue;
};
} stackval_t;

Expand Down Expand Up @@ -581,7 +586,7 @@ typedef struct libFunction {
intptr_t p; \
*sb = calloc(sz + 1, sizeof(stackval_t)); \
assert(*sb != NULL); \
p = ((intptr_t)*sb) % sizeof(stackval_t); \
p = ((intptr_t) * sb) % sizeof(stackval_t); \
if (p != 0) { \
p = (sizeof(stackval_t) - (p % sizeof(stackval_t))); \
} \
Expand All @@ -595,7 +600,7 @@ typedef struct libFunction {
heapval_t hpbv; \
*hb = calloc(hz + 2, sizeof(heapval_t)); \
assert(*hb != NULL); \
p = ((intptr_t)*hb) % sizeof(heapval_t); \
p = ((intptr_t) * hb) % sizeof(heapval_t); \
p = (sizeof(heapval_t) - (p % sizeof(heapval_t))); \
hpbv.sv.type = INT32TYPE; \
hpbv.sv.i = (int32_t)hz; \
Expand Down Expand Up @@ -838,6 +843,23 @@ This is not supposed to happen, I hope I can fix the intepreter!\n", \
*sc = *sc + 1; \
} while (0)

#define PUSH_PRIOQUEUE(a, sp, sc) \
do { \
stackval_t stackval; \
if (*sc >= *PROVIDE_CONTEXT()->stacksize) { \
fprintf(stderr, "Error: Interpreter stack overflow\n\
Please include the script and file an error report to me here:\n %s\n\
This is not supposed to happen, I hope I can fix the intepreter!\n", \
GENERAL_ERROR_ISSUE_URL); \
exit(1); \
} \
stackval.type = PRIOQUEUE; \
stackval.prioqueue = a; \
**((stackval_t **)sp) = stackval; \
*((stackval_t **)sp) += 1; \
*sc = *sc + 1; \
} while (0)

#define POP_VAL(a, sp, sc) \
do { \
if (*sc == 0) { \
Expand All @@ -856,38 +878,39 @@ This is not supposed to happen, I hope I can fix the intepreter!\n", \
extern void getContext(void *);
extern void releaseContext(void *);

#define ALLOC_HEAP(a, hp, hpv, upd) \
do { \
int32_t size = (*(heapval_t *)hp).sv.i; \
int32_t i = 0; \
heapval_t hv; \
getContext(PROVIDE_CONTEXT()->syncCtx); \
if (upd != NULL) { \
*(int *)upd = 1; \
} \
hv.sv = *a; \
if (hv.sv.type == TEXT || hv.sv.type == VECTORTYPE || hv.sv.type == DICTTYPE \
|| hv.sv.type == CLASSTYPE || hv.sv.type == RAWDATATYPE || hv.sv.type == BIGINT) { \
hv.toFree = true; \
} else { \
hv.toFree = false; \
} \
hv.occupied = true; \
while (i < size) { \
if (!((heapval_t *)hp)[i].occupied) { \
((heapval_t *)hp)[i] = hv; \
*hpv = &((heapval_t *)hp)[i]; \
break; \
} \
++i; \
} \
if (i == size) { \
fprintf(stderr, "Error: Heap full (size: %d)\n", size); \
fprintf(stderr, " The heap size can be increased with the -ah flag\n"); \
fprintf(stderr, " For more information, see: ric -h\n"); \
exit(1); \
} \
releaseContext(PROVIDE_CONTEXT()->syncCtx); \
#define ALLOC_HEAP(a, hp, hpv, upd) \
do { \
int32_t size = (*(heapval_t *)hp).sv.i; \
int32_t i = 0; \
heapval_t hv; \
getContext(PROVIDE_CONTEXT()->syncCtx); \
if (upd != NULL) { \
*(int *)upd = 1; \
} \
hv.sv = *a; \
if (hv.sv.type == TEXT || hv.sv.type == VECTORTYPE || hv.sv.type == DICTTYPE \
|| hv.sv.type == CLASSTYPE || hv.sv.type == RAWDATATYPE || hv.sv.type == BIGINT \
|| hv.sv.type == PRIOQUEUE) { \
hv.toFree = true; \
} else { \
hv.toFree = false; \
} \
hv.occupied = true; \
while (i < size) { \
if (!((heapval_t *)hp)[i].occupied) { \
((heapval_t *)hp)[i] = hv; \
*hpv = &((heapval_t *)hp)[i]; \
break; \
} \
++i; \
} \
if (i == size) { \
fprintf(stderr, "Error: Heap full (size: %d)\n", size); \
fprintf(stderr, " The heap size can be increased with the -ah flag\n"); \
fprintf(stderr, " For more information, see: ric -h\n"); \
exit(1); \
} \
releaseContext(PROVIDE_CONTEXT()->syncCtx); \
} while (0);

#define ALLOC_HEAP_UNSAFE(a, hp, hpv, upd) \
Expand Down
49 changes: 48 additions & 1 deletion src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ void push_stackval(stackval_t *stackval, PROVIDE_CONTEXT_ARGS()) {
case CACHEPOT: {
PUSH_CACHEPOT(sv.cachepot, sp, sc);
} break;
case PRIOQUEUE: {
PUSH_PRIOQUEUE(sv.prioqueue, sp, sc);
} break;
default:
fprintf(stderr, "error: Unknown stackval_t type: %d\n", sv.type);
exit(1);
Expand Down Expand Up @@ -124,6 +127,10 @@ void push_heapval(heapval_t *hv, PROVIDE_CONTEXT_ARGS()) {
PUSH_CACHEPOT(hv->sv.cachepot, sp, sc);
break;
}
case PRIOQUEUE: {
PUSH_PRIOQUEUE(hv->sv.prioqueue, sp, sc);
break;
}
default:
break;
}
Expand Down Expand Up @@ -284,6 +291,9 @@ int push_expression(expr_t *expArg, EXPRESSION_PARAMS()) {
case EXPR_TYPE_CACHEPOT:
PUSH_CACHEPOT(expArg->cachepot, sp, sc);
break;
case EXPR_TYPE_PRIOQUEUE:
PUSH_PRIOQUEUE(expArg->prioqueue, sp, sc);
break;
case EXPR_TYPE_TEXT: {
PUSH_STRING(expArg->text, sp, sc);
break;
Expand Down Expand Up @@ -332,6 +342,13 @@ expr_t *stackval_to_expression(stackval_t *sv, int alloc, EXPRESSION_PARAMS()) {
free(newExp->cachepot);
newExp->cachepot = sv->cachepot;
} break;
case PRIOQUEUE: {
expr_t *e = ast_emalloc(sizeof(expr_t));
e->type = EXPR_TYPE_PRIOQUEUE;
e->prioqueue = sv->prioqueue;
newExp = newExpr_Copy(e, alloc, EXPRESSION_ARGS());
free(e);
} break;
case RAWDATATYPE: {
newExp = newExpr_RawData(sv->rawdata->size);
memcpy(newExp->rawdata->data, sv->rawdata->data, sv->rawdata->size);
Expand Down Expand Up @@ -1133,6 +1150,7 @@ void evaluate_expression(expr_t *expr, EXPRESSION_PARAMS()) {
vector_t *vec = NULL;
dictionary_t *dict = NULL;
cachepot_t *cachepot = NULL;
priority_queue_t *prioqueue = NULL;
argsList_t *walk;
char *text = NULL;
rawdata_t *rawdata = NULL;
Expand All @@ -1149,7 +1167,7 @@ void evaluate_expression(expr_t *expr, EXPRESSION_PARAMS()) {
POP_VAL(&sv, sp, sc);

if (sv.type != VECTORTYPE && sv.type != DICTTYPE && sv.type != TEXT
&& sv.type != RAWDATATYPE && sv.type != CACHEPOT) {
&& sv.type != RAWDATATYPE && sv.type != CACHEPOT && sv.type != PRIOQUEUE) {
fprintf(stderr,
"%s.%d index error: '%s' is a datatype (%d) that does not support indexing.\n",
((statement_t *)stmt)->file, ((statement_t *)stmt)->line, id->id.id, sv.type);
Expand All @@ -1169,6 +1187,8 @@ void evaluate_expression(expr_t *expr, EXPRESSION_PARAMS()) {
rawdata = sv.rawdata;
} else if (sv.type == CACHEPOT) {
cachepot = sv.cachepot;
} else if (sv.type == PRIOQUEUE) {
prioqueue = sv.prioqueue;
}
} else {
fprintf(stderr, "error: Invalid indexing %d\n", id->type);
Expand Down Expand Up @@ -1486,6 +1506,33 @@ void evaluate_expression(expr_t *expr, EXPRESSION_PARAMS()) {

push_expression(e, EXPRESSION_ARGS());
} break;
case PRIOQUEUE: {
/* Indexing a prioqueue */
int idx = 0;
expr_t *e = NULL;

evaluate_expression(index, EXPRESSION_ARGS());
POP_VAL(&sv, sp, sc);

if (sv.type != INT32TYPE) {
fprintf(stderr, "index error: Must provide an integer as index for prioqueues\n");
exit(1);
}

idx = sv.i;

if (idx >= prioqueue->size) {
fprintf(stderr, "index error: index out of bounds\n");
exit(1);
}

if (idx < 0) {
idx = prioqueue->size - ((prioqueue->size - idx) % prioqueue->size);
}

e = prioqueue->items[idx].value;
push_expression(e, EXPRESSION_ARGS());
} break;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions src/eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,5 @@ void locals_remove(locals_stack_t *stack, char *id);

expr_t *stackval_to_expression(stackval_t *sv, int alloc, EXPRESSION_PARAMS());
void push_stackval(stackval_t *stackval, PROVIDE_CONTEXT_ARGS());
int push_expression(expr_t *expArg, EXPRESSION_PARAMS());
#endif
Loading

0 comments on commit dae1f64

Please sign in to comment.