about summary refs log tree commit diff
path: root/boot/tree.c
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2025-06-01 04:50:51 +0200
committerMel <mel@rnrd.eu>2025-06-01 04:50:51 +0200
commita65c02b752722c873036a9246753f2e40c24305f (patch)
tree7ced7685f689234f79ef32ed52e0de3b7ebbb3f7 /boot/tree.c
parentcea333644191567bcfdd1e24e4606aafbf34e3cb (diff)
downloadcatskill-a65c02b752722c873036a9246753f2e40c24305f.tar.zst
catskill-a65c02b752722c873036a9246753f2e40c24305f.zip
Function literal expressions
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/tree.c')
-rw-r--r--boot/tree.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/boot/tree.c b/boot/tree.c
index dcda4da..64eb23b 100644
--- a/boot/tree.c
+++ b/boot/tree.c
@@ -335,10 +335,20 @@ struct Block_Node
     struct Cursor location;
 };
 
+void block_node_print(const struct Block_Node* block);
+
+enum Type_Type
+{
+    TYPE_NONE,
+    TYPE_NAME,
+};
+
 // a type node represents a type in the syntax tree.
 // currently, we only support types that are simple names.
+// or null types.
 struct Type_Node
 {
+    enum Type_Type type;
     // note: we could also just include the token here i think?
     struct String name;
     struct Span span;
@@ -362,6 +372,8 @@ enum Expression_Kind
     EXPRESSION_CALL,
     EXPRESSION_SUBSCRIPT,
     EXPRESSION_MEMBER,
+
+    EXPRESSION_FUNCTION,
 };
 
 struct Expression_Integer_Literal
@@ -425,6 +437,21 @@ struct Expression_Member
     struct String name;
 };
 
+#define EXPRESSION_FUNCTION_MAX_PARAMS 32
+
+struct Expression_Function
+{
+    struct Expression_Function_Parameter
+    {
+        struct String name;
+        struct Type_Node type;
+    } parameters[EXPRESSION_FUNCTION_MAX_PARAMS];
+    uint parameter_count;
+
+    struct Type_Node return_type;
+    struct Block_Node body;
+};
+
 union Expression_Value
 {
     struct Expression_Integer_Literal integer_literal;
@@ -438,6 +465,7 @@ union Expression_Value
     struct Expression_Call call;
     struct Expression_Subscript subscript;
     struct Expression_Member member;
+    struct Expression_Function function;
 };
 
 struct Expression
@@ -535,6 +563,20 @@ expression_print(const struct Expression* expression)
         expression_print(expression->value.member.subject);
         printf(")");
         break;
+    case EXPRESSION_FUNCTION: {
+        const struct Expression_Function* fun = &expression->value.function;
+        printf("(function");
+        for (uint i = 0; i < fun->parameter_count; ++i) {
+            const struct Expression_Function_Parameter* param = &fun->parameters[i];
+            printf(" (param %s)", param->name.data);
+            if (param->type.type != TYPE_NONE) { printf(" (type %s)", param->type.name.data); }
+        }
+        if (fun->return_type.type != TYPE_NONE) printf(" (returns %s)", fun->return_type.name.data);
+        printf(" ");
+        block_node_print(&fun->body);
+        printf(")");
+        break;
+    }
     default:
         failure("unexpected expression kind passed to `expression_print`");
         break;
@@ -559,11 +601,9 @@ struct Statement_Value_Expression
 
 struct Statement_Value_Declaration
 {
-    struct String_Array names;      // the names of the variables being declared.
-    struct Expression* initializer; // the expression to initialize the variable with.
-
-    bool has_type;         // whether the declaration has a type.
-    struct Type_Node type; // the type of the variable, if any.
+    struct String_Array names;
+    struct Expression* initializer;
+    struct Type_Node type;
 };
 
 struct Statement_Value_Block
@@ -657,7 +697,7 @@ statement_print(const struct Statement* statement)
         {
             printf("%s ", name.data);
         }
-        if (statement->value.declaration.has_type) {
+        if (statement->value.declaration.type.type != TYPE_NONE) {
             printf("(type %s) ", statement->value.declaration.type.name.data);
         }
         if (statement->value.declaration.initializer) {