aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-24 17:33:19 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-24 17:33:19 -0400
commite3e7c60dd75ef0f06a25ddde2685868062302eeb (patch)
tree71671de131f1e5a5a375b559820d37e834984d82 /src
parent9b16e1c06cad326b79e3aab8a95d5f97ea07af90 (diff)
Move method calls
Diffstat (limited to 'src')
-rw-r--r--src/compile.c41
-rw-r--r--src/compile/functions.c43
-rw-r--r--src/compile/functions.h1
3 files changed, 45 insertions, 40 deletions
diff --git a/src/compile.c b/src/compile.c
index 4aba2008..6c10c763 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -305,46 +305,7 @@ Text_t compile(env_t *env, ast_t *ast) {
else return compile(env, WrapAST(ast, List, .items = new (ast_list_t, .ast = ast)));
}
case Lambda: return compile_lambda(env, ast);
- case MethodCall: {
- DeclareMatch(call, ast, MethodCall);
- type_t *self_t = get_type(env, call->self);
-
- if (streq(call->name, "serialized")) {
- if (call->args) code_err(ast, ".serialized() doesn't take any arguments");
- return Texts("generic_serialize((", compile_declaration(self_t, Text("[1]")), "){",
- compile(env, call->self), "}, ", compile_type_info(self_t), ")");
- }
-
- type_t *self_value_t = value_type(self_t);
- if (self_value_t->tag == TypeInfoType || self_value_t->tag == ModuleType) {
- return compile(env,
- WrapAST(ast, FunctionCall,
- .fn = WrapAST(call->self, FieldAccess, .fielded = call->self, .field = call->name),
- .args = call->args));
- }
-
- type_t *field_type = get_field_type(self_value_t, call->name);
- if (field_type && field_type->tag == ClosureType) field_type = Match(field_type, ClosureType)->fn;
- if (field_type && field_type->tag == FunctionType)
- return compile(env,
- WrapAST(ast, FunctionCall,
- .fn = WrapAST(call->self, FieldAccess, .fielded = call->self, .field = call->name),
- .args = call->args));
-
- switch (self_value_t->tag) {
- case ListType: return compile_list_method_call(env, ast);
- case SetType: return compile_set_method_call(env, ast);
- case TableType: return compile_table_method_call(env, ast);
- default: {
- DeclareMatch(methodcall, ast, MethodCall);
- type_t *fn_t = get_method_type(env, methodcall->self, methodcall->name);
- arg_ast_t *args = new (arg_ast_t, .value = methodcall->self, .next = methodcall->args);
- binding_t *b = get_namespace_binding(env, methodcall->self, methodcall->name);
- if (!b) code_err(ast, "No such method");
- return Texts(b->code, "(", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, args), ")");
- }
- }
- }
+ case MethodCall: return compile_method_call(env, ast);
case FunctionCall: return compile_function_call(env, ast);
case Deserialize: {
ast_t *value = Match(ast, Deserialize)->value;
diff --git a/src/compile/functions.c b/src/compile/functions.c
index 418705aa..d0235c66 100644
--- a/src/compile/functions.c
+++ b/src/compile/functions.c
@@ -14,9 +14,12 @@
#include "assignments.h"
#include "blocks.h"
#include "integers.h"
+#include "lists.h"
#include "promotions.h"
+#include "sets.h"
#include "statements.h"
#include "structs.h"
+#include "tables.h"
#include "text.h"
#include "types.h"
@@ -781,3 +784,43 @@ Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *static
text = Texts(text, ")");
return definition;
}
+
+public
+Text_t compile_method_call(env_t *env, ast_t *ast) {
+ DeclareMatch(call, ast, MethodCall);
+ type_t *self_t = get_type(env, call->self);
+
+ if (streq(call->name, "serialized")) {
+ if (call->args) code_err(ast, ".serialized() doesn't take any arguments");
+ return Texts("generic_serialize((", compile_declaration(self_t, Text("[1]")), "){", compile(env, call->self),
+ "}, ", compile_type_info(self_t), ")");
+ }
+
+ type_t *self_value_t = value_type(self_t);
+ if (self_value_t->tag == TypeInfoType || self_value_t->tag == ModuleType) {
+ return compile(env, WrapAST(ast, FunctionCall,
+ .fn = WrapAST(call->self, FieldAccess, .fielded = call->self, .field = call->name),
+ .args = call->args));
+ }
+
+ type_t *field_type = get_field_type(self_value_t, call->name);
+ if (field_type && field_type->tag == ClosureType) field_type = Match(field_type, ClosureType)->fn;
+ if (field_type && field_type->tag == FunctionType)
+ return compile(env, WrapAST(ast, FunctionCall,
+ .fn = WrapAST(call->self, FieldAccess, .fielded = call->self, .field = call->name),
+ .args = call->args));
+
+ switch (self_value_t->tag) {
+ case ListType: return compile_list_method_call(env, ast);
+ case SetType: return compile_set_method_call(env, ast);
+ case TableType: return compile_table_method_call(env, ast);
+ default: {
+ DeclareMatch(methodcall, ast, MethodCall);
+ type_t *fn_t = get_method_type(env, methodcall->self, methodcall->name);
+ arg_ast_t *args = new (arg_ast_t, .value = methodcall->self, .next = methodcall->args);
+ binding_t *b = get_namespace_binding(env, methodcall->self, methodcall->name);
+ if (!b) code_err(ast, "No such method");
+ return Texts(b->code, "(", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, args), ")");
+ }
+ }
+}
diff --git a/src/compile/functions.h b/src/compile/functions.h
index da9a6992..736662af 100644
--- a/src/compile/functions.h
+++ b/src/compile/functions.h
@@ -8,3 +8,4 @@ Text_t compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg_ast_
Text_t compile_lambda(env_t *env, ast_t *ast);
Table_t get_closed_vars(env_t *env, arg_ast_t *args, ast_t *block);
Text_t compile_function(env_t *env, Text_t name_code, ast_t *ast, Text_t *staticdefs);
+Text_t compile_method_call(env_t *env, ast_t *ast);