From e5fda1c96af409065fedbe032b0f7908d9f312ac Mon Sep 17 00:00:00 2001
From: Kimplul <kimi.h.kuparinen@gmail.com>
Date: Fri, 6 Dec 2024 18:14:40 +0200
Subject: add types to parser

+ No actual type checking is implemented as of yet, but with references
  and pointers I should be able to start playing around with checking
  move semantics and so on

+ Might at some point also look into type propagation for let,
  annoying to have to specify the same thing twice.
---
 src/lower.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 100 insertions(+), 18 deletions(-)

(limited to 'src/lower.c')

diff --git a/src/lower.c b/src/lower.c
index 46ce2c3..cf36fb0 100644
--- a/src/lower.c
+++ b/src/lower.c
@@ -31,10 +31,14 @@ static void indent(struct state *state)
 		putchar(' ');
 }
 
+static int lower_var(struct ast *expr);
+
 static int lower_expr(struct state *state, struct ast *expr);
 static int lower_block(struct state *state, struct ast *block);
 static int lower_closure(struct state *state, struct ast *closure);
+static int lower_statement(struct state *state, struct ast *stmt);
 
+static int lower_type(struct type *type);
 static int lower_types(struct type *types);
 
 static int lower_binop(struct state *state, struct ast *binop)
@@ -105,14 +109,8 @@ static int lower_exprs(struct state *state, struct ast *exprs)
 	return 0;
 }
 
-static int lower_type(struct type *type)
+static int lower_type_construct(struct type *type)
 {
-	if (type->k == TYPE_ID) {
-		printf("%s", tid_str(type));
-		return 0;
-	}
-
-	assert(type->k == TYPE_CONSTRUCT);
 	printf("%s", tconstruct_id(type));
 	printf("<");
 
@@ -123,6 +121,51 @@ static int lower_type(struct type *type)
 	return 0;
 }
 
+static int lower_type_callable(struct type *type)
+{
+	printf("std::function<void(");
+
+	if (lower_types(tcallable_args(type)))
+		return -1;
+
+	printf(")>");
+	return 0;
+}
+
+static int lower_type_ref(struct type *type)
+{
+	if (lower_type(tref_base(type)))
+		return -1;
+
+	printf("&");
+	return 0;
+}
+
+static int lower_type_ptr(struct type *type)
+{
+	if (lower_type(tptr_base(type)))
+		return -1;
+
+	printf("*");
+	return 0;
+}
+
+static int lower_type(struct type *type)
+{
+	switch (type->k) {
+	case TYPE_ID: printf("%s", tid_str(type)); return 0;
+	case TYPE_CONSTRUCT: return lower_type_construct(type);
+	case TYPE_CALLABLE: return lower_type_callable(type);
+	case TYPE_REF: return lower_type_ref(type);
+	case TYPE_PTR: return lower_type_ptr(type);
+	default:
+		internal_error("missing type lowering");
+		return -1;
+	}
+
+	return 0;
+}
+
 static int lower_types(struct type *types)
 {
 	if (!types)
@@ -250,7 +293,11 @@ static int lower_call(struct state *state, struct ast *call)
 
 static int lower_let(struct state *state, struct ast *let)
 {
-	printf("auto %s = ", let_id(let));
+	if (lower_var(let_var(let)))
+		return -1;
+
+	printf(" = ");
+
 	if (lower_expr(state, let_expr(let)))
 		return -1;
 
@@ -258,11 +305,34 @@ static int lower_let(struct state *state, struct ast *let)
 	return 0;
 }
 
+static int lower_if(struct state *state, struct ast *stmt)
+{
+	printf("if (");
+	if (lower_expr(state, if_cond(stmt)))
+		return -1;
+
+	printf(") ");
+
+	if (lower_block(state, if_body(stmt)))
+		return -1;
+
+	if (!if_else(stmt))
+		return 0;
+
+	printf(" else ");
+	if (lower_block(state, if_else(stmt)))
+		return -1;
+
+	printf("\n");
+	return 0;
+}
+
 static int lower_statement(struct state *state, struct ast *stmt)
 {
 	switch (stmt->k) {
-	case AST_LET: return lower_let(state, stmt);
-	case AST_CALL: return lower_call(state, stmt);
+	case AST_LET:	return lower_let(state, stmt);
+	case AST_CALL:	return lower_call(state, stmt);
+	case AST_IF:	return lower_if(state, stmt);
 	default:
 		internal_error("missing statement lowering");
 		return -1;
@@ -290,15 +360,27 @@ static int lower_block(struct state *state, struct ast *block)
 	return 0;
 }
 
-static int lower_params(struct ast *params)
+static int lower_var(struct ast *var)
+{
+	if (lower_type(var_type(var)))
+		return -1;
+
+	printf(" %s", var_id(var));
+	return 0;
+}
+
+static int lower_vars(struct ast *vars)
 {
-	if (!params)
+	if (!vars)
 		return 0;
 
-	printf("auto %s", var_id(params));
+	if (lower_var(vars))
+		return -1;
 
-	foreach_node(param, params->n) {
-		printf(", auto %s", var_id(param));
+	foreach_node(var, vars->n) {
+		printf(", ");
+		if (lower_var(var))
+			return -1;
 	}
 
 	return 0;
@@ -307,7 +389,7 @@ static int lower_params(struct ast *params)
 static int lower_closure(struct state *state, struct ast *closure)
 {
 	printf("[&](");
-	if (lower_params(closure_bindings(closure)))
+	if (lower_vars(closure_bindings(closure)))
 		return -1;
 
 	printf(")");
@@ -327,7 +409,7 @@ static int lower_proto(struct ast *proc)
 
 	printf("%s(", proc_id(proc));
 
-	if (lower_params(proc_params(proc)))
+	if (lower_vars(proc_params(proc)))
 		return -1;
 
 	printf(");\n\n");
@@ -343,7 +425,7 @@ static int lower_proc(struct ast *proc)
 
 	printf("%s(", proc_id(proc));
 
-	if (lower_params(proc_params(proc)))
+	if (lower_vars(proc_params(proc)))
 		return -1;
 
 	printf(")\n");
-- 
cgit v1.2.3