From 9f8fc70a7690e26e75754e46eab9d484634819f1 Mon Sep 17 00:00:00 2001
From: Leo Tenenbaum <pommicket@gmail.com>
Date: Sun, 8 Mar 2020 12:57:51 -0400
Subject: more varargs

---
 copy.c  | 48 +++++++++++++++++++++++++++++-------------------
 main.c  |  1 +
 types.c |  4 ++--
 3 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/copy.c b/copy.c
index 178a1d2..07b003b 100644
--- a/copy.c
+++ b/copy.c
@@ -176,8 +176,16 @@ static inline void *copier_malloc(Copier *c, size_t n) {
 	return allocr_malloc(c->allocr, n);
 }
 
-static void copy_fn_expr(Copier *c, FnExpr *fout, FnExpr *fin, bool copy_body) {
+enum {
+	  COPY_FN_EXPR_DONT_COPY_HEADER = 0x01,
+	  COPY_FN_EXPR_DONT_COPY_BODY = 0x02
+};
+
+static void copy_fn_expr(Copier *c, FnExpr *fout, FnExpr *fin, U8 flags) {
 	*fout = *fin;
+	bool copy_body = (flags & COPY_FN_EXPR_DONT_COPY_BODY) == 0;
+	bool copy_header = (flags & COPY_FN_EXPR_DONT_COPY_HEADER) == 0;
+	
 	if (fin->flags & FN_EXPR_FOREIGN) {
 		copy_expr(c, fout->foreign.name_expr = copier_malloc(c, sizeof *fin->foreign.name_expr), fin->foreign.name_expr);
 		copy_expr(c, fout->foreign.lib_expr = copier_malloc(c, sizeof *fin->foreign.lib_expr), fin->foreign.lib_expr);
@@ -192,23 +200,25 @@ static void copy_fn_expr(Copier *c, FnExpr *fout, FnExpr *fin, bool copy_body) {
 			c->block = &fout->body;
 			idents_create(&fout->body.idents, c->allocr, &fout->body);
 		}
-		size_t i;
-		size_t nparam_decls = arr_len(fin->params);
-		fout->params = NULL;
-		arr_set_lena(&fout->params, nparam_decls, c->allocr);
-		for (i = 0; i < nparam_decls; ++i)
-			copy_decl(c, fout->params + i, fin->params + i);
-		size_t nret_decls = arr_len(fin->ret_decls);
-		if (fin->ret_decls) {
-			fout->ret_decls = NULL;
-			arr_set_lena(&fout->ret_decls, nret_decls, c->allocr);
-			for (i = 0; i < nret_decls; ++i)
-				copy_decl(c, fout->ret_decls + i, fin->ret_decls + i);
-		}
-		copy_type(c, &fout->ret_type, &fin->ret_type);
-		if (copy_body) {
-			c->block = prev;
-			copy_block(c, &fout->body, &fin->body, copy_body ? COPY_BLOCK_DONT_CREATE_IDENTS : 0);
+		if (copy_header) {
+			size_t i;
+			size_t nparam_decls = arr_len(fin->params);
+			fout->params = NULL;
+			arr_set_lena(&fout->params, nparam_decls, c->allocr);
+			for (i = 0; i < nparam_decls; ++i)
+				copy_decl(c, fout->params + i, fin->params + i);
+			size_t nret_decls = arr_len(fin->ret_decls);
+			if (fin->ret_decls) {
+				fout->ret_decls = NULL;
+				arr_set_lena(&fout->ret_decls, nret_decls, c->allocr);
+				for (i = 0; i < nret_decls; ++i)
+					copy_decl(c, fout->ret_decls + i, fin->ret_decls + i);
+			}
+			copy_type(c, &fout->ret_type, &fin->ret_type);
+			if (copy_body) {
+				c->block = prev;
+				copy_block(c, &fout->body, &fin->body, copy_body ? COPY_BLOCK_DONT_CREATE_IDENTS : 0);
+			}
 		}
 	}
 }
@@ -293,7 +303,7 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) {
 		copy_block(c, &fout->body, &fin->body, COPY_BLOCK_DONT_CREATE_IDENTS);
 	} break;
 	case EXPR_FN:
-		copy_fn_expr(c, out->fn = allocr_malloc(a, sizeof *out->fn), in->fn, true);
+		copy_fn_expr(c, out->fn = allocr_malloc(a, sizeof *out->fn), in->fn, 0);
 		break;
 	case EXPR_CAST: {
 		CastExpr *cin = &in->cast;
diff --git a/main.c b/main.c
index 9320f0e..c75618e 100644
--- a/main.c
+++ b/main.c
@@ -9,6 +9,7 @@
 /* 
 TODO:
 variadic fns
+const varargs
 make sure you can't have a variadic function pointer
 #foreign variadic fns
 where
diff --git a/types.c b/types.c
index 5e387dd..0466800 100644
--- a/types.c
+++ b/types.c
@@ -425,7 +425,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
 	bool generic = !(flags & TYPE_OF_FN_IS_INSTANCE) && fn_has_any_const_params(f);
 	if (generic) {
 		Copier cop = copier_create(tr->allocr, &f->body);
-		copy_fn_expr(&cop, &fn_copy, f, false);
+		copy_fn_expr(&cop, &fn_copy, f, COPY_FN_EXPR_DONT_COPY_BODY);
 		f = &fn_copy;
 	}
 	size_t idx = 0;
@@ -2009,7 +2009,7 @@ static Status types_expr(Typer *tr, Expression *e) {
 			original_fn = fn;
 			fn_copy = typer_malloc(tr, sizeof *fn_copy);
 			Copier cop = copier_create(tr->allocr, fn->body.parent);
-			copy_fn_expr(&cop, fn_copy, fn, true);
+			copy_fn_expr(&cop, fn_copy, fn, has_varargs ? COPY_FN_EXPR_DONT_COPY_HEADER : 0);
 		}
 
 		if (fn_type->constness) {
-- 
cgit v1.2.3