Compare commits

..

No commits in common. "92c4c5c991dcf007bca4a2db0c81555c5b3817bd" and "bb75b78a36cb58328b1be41ead155fdb7f4d7c1f" have entirely different histories.

2 changed files with 26 additions and 37 deletions

2
ir.c
View File

@ -43,7 +43,7 @@ void irtoks_init_short(IRToks *v) {
void irtoks_term(IRToks *v) { void irtoks_term(IRToks *v) {
for (size_t i = 0; i < v->len; i++) { for (size_t i = 0; i < v->len; i++) {
if (v->toks[i].instr == IRCallInternal && v->toks[i].CallI.args) if (v->toks[i].instr == IRCallInternal)
free(v->toks[i].CallI.args); free(v->toks[i].CallI.args);
} }
free(v->toks); free(v->toks);

61
parse.c
View File

@ -242,37 +242,29 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
bool eval_func_in_place = !func.side_effects; bool eval_func_in_place = !func.side_effects;
size_t args_len = 0; size_t args_len = 0;
IRParam *args = NULL; size_t args_cap = 16;
IRParam *args = xmalloc(sizeof(IRParam) * args_cap);
if (t->next->tok.kind == TokOp && t->next->tok.Op == OpRParen) { for (;;) {
/* no args */ if (args_len+1 > args_cap)
toklist_del(toks, t->next, t->next); /* delete right parenthesis */ args = xrealloc(args, (args_cap *= 2));
} else { IRParam a;
/* go through the arguments, evaluate them and put them into the args array */ TRY_RET_ELSE(a = expr_into_irparam(out_ir, toks, funcs, &sc, t->next), (ExprRet){0}, free(args));
size_t args_cap = 16; args[args_len++] = a;
args = xmalloc(sizeof(IRParam) * args_cap); if (a.kind != IRParamLiteral)
for (;;) { eval_func_in_place = false;
if (args_len+1 > args_cap) if (t->next->tok.kind == TokOp) {
args = xrealloc(args, (args_cap *= 2)); if (t->next->tok.Op == OpComma) {
IRParam a; toklist_del(toks, t->next, t->next);
TRY_RET_ELSE(a = expr_into_irparam(out_ir, toks, funcs, &sc, t->next), (ExprRet){0}, free(args)); continue;
args[args_len++] = a; } else if (t->next->tok.Op == OpRParen) {
if (a.kind != IRParamLiteral) toklist_del(toks, t->next, t->next);
eval_func_in_place = false; break;
if (t->next->tok.kind == TokOp) {
if (t->next->tok.Op == OpComma) {
toklist_del(toks, t->next, t->next); /* delete right parenthesis */
continue;
} else if (t->next->tok.Op == OpRParen) {
toklist_del(toks, t->next, t->next); /* delete right parenthesis */
break;
}
} }
mark_err(&t->next->tok);
set_err("Expected ',' or ')' after function argument");
free(args);
return (ExprRet){0};
} }
mark_err(&t->next->tok);
set_err("Expected ',' or ')' after function argument");
free(args);
return (ExprRet){0};
} }
t = func_ident; t = func_ident;
@ -282,24 +274,21 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
mark_err(&func_ident->tok); mark_err(&func_ident->tok);
const char *plural = func.n_args == 1 ? "" : "s"; const char *plural = func.n_args == 1 ? "" : "s";
set_err("Function %s() takes %zu argument%s but got %zu", func.name, func.n_args, plural, args_len); set_err("Function %s() takes %zu argument%s but got %zu", func.name, func.n_args, plural, args_len);
if (args) free(args);
free(args);
return (ExprRet){0}; return (ExprRet){0};
} }
if (eval_func_in_place) { if (eval_func_in_place) {
/* evaluate the function in place */ /* evaluate the function in place */
Value *arg_vals = args_len ? xmalloc(sizeof(Value) * args_len) : NULL; Value *arg_vals = xmalloc(sizeof(Value) * args_len);
for (size_t i = 0; i < args_len; i++) for (size_t i = 0; i < args_len; i++)
arg_vals[i] = args[i].Literal; arg_vals[i] = args[i].Literal;
func_ident->tok = (Tok) { func_ident->tok = (Tok) {
.kind = TokVal, .kind = TokVal,
.Val = func.func(arg_vals), .Val = func.func(arg_vals),
}; };
if (arg_vals) free(arg_vals);
free(arg_vals); free(args);
if (args)
free(args);
} else { } else {
bool is_last_operation = t == start && t->next->tok.kind == TokOp && op_prec[t->next->tok.Op] == PREC_DELIM; bool is_last_operation = t == start && t->next->tok.kind == TokOp && op_prec[t->next->tok.Op] == PREC_DELIM;