support for builtin functions with 0 args
This commit is contained in:
		
							
								
								
									
										2
									
								
								ir.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								ir.c
									
									
									
									
									
								
							@@ -43,7 +43,7 @@ void irtoks_init_short(IRToks *v) {
 | 
			
		||||
 | 
			
		||||
void irtoks_term(IRToks *v) {
 | 
			
		||||
	for (size_t i = 0; i < v->len; i++) {
 | 
			
		||||
		if (v->toks[i].instr == IRCallInternal)
 | 
			
		||||
		if (v->toks[i].instr == IRCallInternal && v->toks[i].CallI.args)
 | 
			
		||||
			free(v->toks[i].CallI.args);
 | 
			
		||||
	}
 | 
			
		||||
	free(v->toks);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								parse.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								parse.c
									
									
									
									
									
								
							@@ -242,8 +242,15 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
 | 
			
		||||
			bool eval_func_in_place = !func.side_effects;
 | 
			
		||||
 | 
			
		||||
			size_t args_len = 0;
 | 
			
		||||
			IRParam *args = NULL;
 | 
			
		||||
 | 
			
		||||
			if (t->next->tok.kind == TokOp && t->next->tok.Op == OpRParen) {
 | 
			
		||||
				/* no args */
 | 
			
		||||
				toklist_del(toks, t->next, t->next); /* delete right parenthesis */
 | 
			
		||||
			} else {
 | 
			
		||||
				/* go through the arguments, evaluate them and put them into the args array */
 | 
			
		||||
				size_t args_cap = 16;
 | 
			
		||||
			IRParam *args = xmalloc(sizeof(IRParam) * args_cap);
 | 
			
		||||
				args = xmalloc(sizeof(IRParam) * args_cap);
 | 
			
		||||
				for (;;) {
 | 
			
		||||
					if (args_len+1 > args_cap)
 | 
			
		||||
						args = xrealloc(args, (args_cap *= 2));
 | 
			
		||||
@@ -254,10 +261,10 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
 | 
			
		||||
						eval_func_in_place = false;
 | 
			
		||||
					if (t->next->tok.kind == TokOp) {
 | 
			
		||||
						if (t->next->tok.Op == OpComma) {
 | 
			
		||||
						toklist_del(toks, t->next, t->next);
 | 
			
		||||
							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);
 | 
			
		||||
							toklist_del(toks, t->next, t->next); /* delete right parenthesis */
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
@@ -266,6 +273,7 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
 | 
			
		||||
					free(args);
 | 
			
		||||
					return (ExprRet){0};
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			t = func_ident;
 | 
			
		||||
			toklist_del(toks, t->next, t->next); /* delete left parenthesis */
 | 
			
		||||
@@ -274,20 +282,23 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
 | 
			
		||||
				mark_err(&func_ident->tok);
 | 
			
		||||
				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);
 | 
			
		||||
				if (args)
 | 
			
		||||
					free(args);
 | 
			
		||||
				return (ExprRet){0};
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (eval_func_in_place) {
 | 
			
		||||
				/* evaluate the function in place */
 | 
			
		||||
				Value *arg_vals = xmalloc(sizeof(Value) * args_len);
 | 
			
		||||
				Value *arg_vals = args_len ? xmalloc(sizeof(Value) * args_len) : NULL;
 | 
			
		||||
				for (size_t i = 0; i < args_len; i++)
 | 
			
		||||
					arg_vals[i] = args[i].Literal;
 | 
			
		||||
				func_ident->tok = (Tok) {
 | 
			
		||||
					.kind = TokVal,
 | 
			
		||||
					.Val = func.func(arg_vals),
 | 
			
		||||
				};
 | 
			
		||||
				if (arg_vals)
 | 
			
		||||
					free(arg_vals);
 | 
			
		||||
				if (args)
 | 
			
		||||
					free(args);
 | 
			
		||||
			} else {
 | 
			
		||||
				bool is_last_operation = t == start && t->next->tok.kind == TokOp && op_prec[t->next->tok.Op] == PREC_DELIM;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user