Add concurrency

This commit is contained in:
Mid
2025-09-03 01:03:45 +03:00
parent 64c21ca43a
commit 0165980111
7 changed files with 475 additions and 104 deletions

63
parse.c
View File

@@ -98,6 +98,7 @@ typedef enum ExprKind {
} ExprKind;
typedef struct Expr {
ExprKind kind;
struct Expr *next_to_die;
union {
struct {
struct Expr *A;
@@ -181,6 +182,19 @@ void free_vreg(Parser *P, int vreg) {
assert(P->current_chunk.used_vregs[vreg] >= 0 && "Cannot free unused vreg");
}
static void scope_kill(Parser *P) {
Scope *parent = P->scope->parent;
for(ScopeItem *si = P->scope->items; si;) {
ScopeItem *next = si->next;
free(si);
si = next;
}
free(P->scope);
P->scope = parent;
}
void parse_chunk(Parser *P);
int parse_functiondef(Parser *P, bool can_be_local) {
@@ -251,7 +265,7 @@ int parse_functiondef(Parser *P, bool can_be_local) {
size_t function_idx = P->unit_functions.size - 1;
P->current_chunk = old_chunk;
P->scope = P->scope->parent;
scope_kill(P);
int vreg = find_vreg(P);
assert(vreg != -1);
@@ -315,6 +329,17 @@ vec_Token parse_namelist(Parser *P) {
return v;
}
static Expr *last_desc = NULL;
static Expr *mark_for_death(Expr *e) {
e->next_to_die = last_desc;
last_desc = e;
return e;
}
static Expr *new_expr(size_t space) {
Expr *e = calloc(1, sizeof(*e) + space);
mark_for_death(e);
return e;
}
Expr *desc_subexp(Parser *P, int priority) {
if(priority == 0) {
Expr *a = desc_subexp(P, priority + 1);
@@ -324,7 +349,7 @@ Expr *desc_subexp(Parser *P, int priority) {
Expr *b = desc_subexp(P, priority + 1);
Expr *opex = calloc(1, sizeof(*opex));
Expr *opex = new_expr(0);
opex->A = a;
opex->B = b;
@@ -346,7 +371,7 @@ Expr *desc_subexp(Parser *P, int priority) {
Expr *b = desc_subexp(P, priority + 1);
Expr *opex = calloc(1, sizeof(*opex));
Expr *opex = new_expr(0);
opex->A = a;
opex->B = b;
@@ -368,7 +393,7 @@ Expr *desc_subexp(Parser *P, int priority) {
Expr *b = desc_subexp(P, priority + 1);
Expr *opex = calloc(1, sizeof(*opex));
Expr *opex = new_expr(0);
opex->A = a;
opex->B = b;
@@ -390,11 +415,11 @@ Expr *desc_subexp(Parser *P, int priority) {
Expr *e = NULL;
if(maybe(P, TOK_TRUE)) {
e = calloc(1, sizeof(*e));
e = new_expr(0);
e->kind = EX_BOOL;
e->b = true;
} else if(maybe(P, TOK_FALSE)) {
e = calloc(1, sizeof(*e));
e = new_expr(0);
e->kind = EX_BOOL;
e->b = false;
} else if(maybe(P, TOK_NUMBER)) {
@@ -403,7 +428,7 @@ Expr *desc_subexp(Parser *P, int priority) {
Token num = expect(P, TOK_NUMBER);
long i = strtol(num.text, NULL, 10);
e = calloc(1, sizeof(*e));
e = new_expr(0);
e->kind = EX_INT;
e->i = i;
} else if(maybe(P, TOK_NAME)) {
@@ -413,7 +438,7 @@ Expr *desc_subexp(Parser *P, int priority) {
ScopeItem *si = scope_find(P->scope, name.text);
e = calloc(1, sizeof(*e));
e = new_expr(0);
e->kind = si ? EX_LOCAL : EX_GLOBAL;
e->name = name;
} else if(maybe(P, TOK_STRING)) {
@@ -421,11 +446,11 @@ Expr *desc_subexp(Parser *P, int priority) {
Token str = expect(P, TOK_STRING);
e = calloc(1, sizeof(*e));
e = new_expr(0);
e->kind = EX_STR;
e->name = str;
} else if(maybe(P, TOK_SQUIGGLY_L)) {
e = calloc(1, sizeof(*e));
e = new_expr(0);
e->kind = EX_TBL_LIT;
e->table_first_token = P->i - 1;
@@ -448,15 +473,14 @@ Expr *desc_subexp(Parser *P, int priority) {
if(e) {
while(maybe(P, TOK_PAREN_L) || maybe(P, TOK_DOT)) {
if(peek(P, -1).type == TOK_PAREN_L) {
Expr *call = calloc(1, sizeof(*call) + sizeof(Expr*));
Expr *call = new_expr(sizeof(Expr*) + sizeof(Expr*) * 32);
call->kind = EX_CALL;
call->sub_count = 1;
call->subs[0] = e;
if(!maybe(P, TOK_PAREN_R)) {
while(1) {
call = realloc(call, sizeof(*call) + sizeof(Expr*) * (++call->sub_count));
call->subs[call->sub_count - 1] = desc_exp(P);
call->subs[call->sub_count++] = desc_exp(P);
if(maybe(P, TOK_PAREN_R)) {
break;
@@ -468,7 +492,7 @@ Expr *desc_subexp(Parser *P, int priority) {
e = call;
} else if(peek(P, -1).type == TOK_DOT) {
Expr *dot = calloc(1, sizeof(*dot));
Expr *dot = new_expr(0);
dot->kind = EX_INDEX;
dot->A = e;
dot->B_tok = expect(P, TOK_NAME);
@@ -932,7 +956,7 @@ bool parse_stat(Parser *P) {
P->current_chunk.instrs.data[jump2end].bc = P->current_chunk.instrs.size - 1 - jump2end;
P->scope = P->scope->parent;
scope_kill(P);
} else if(maybe(P, TOK_FOR)) {
if(peek(P, 0).type == TOK_NAME && peek(P, 1).type == TOK_EQUAL) {
// Range loop
@@ -985,7 +1009,7 @@ bool parse_stat(Parser *P) {
P->current_chunk.instrs.data[jump2end].bc = P->current_chunk.instrs.size - 1 - jump2end;
P->scope = P->scope->parent;
scope_kill(P);
expect(P, TOK_END);
@@ -1049,5 +1073,12 @@ LUnit *lparse(size_t sz, Token *tokens, LTable *environment) {
unit->func_count = 1;
unit->funcs = P.unit_functions.data;
for(Expr *e = last_desc; e;) {
Expr *n = e->next_to_die;
free(e);
e = n;
}
last_desc = NULL;
return unit;
}