Add concurrency
This commit is contained in:
63
parse.c
63
parse.c
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user