aboutsummaryrefslogtreecommitdiff
path: root/src/compile/expressions.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-24 18:27:05 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-24 18:27:05 -0400
commit02a33f3dd65ff7be262116edb4a37b3e0a74ac57 (patch)
treeecb0b666b3672c60be3288d5b7a9a0bac9852f65 /src/compile/expressions.c
parent74e8aa30901dba029f3e39d187337a09740db4e0 (diff)
Move field access to its own file
Diffstat (limited to 'src/compile/expressions.c')
-rw-r--r--src/compile/expressions.c82
1 files changed, 2 insertions, 80 deletions
diff --git a/src/compile/expressions.c b/src/compile/expressions.c
index a6bcff75..ce22042f 100644
--- a/src/compile/expressions.c
+++ b/src/compile/expressions.c
@@ -4,7 +4,6 @@
#include "../ast.h"
#include "../config.h"
#include "../environment.h"
-#include "../stdlib/tables.h"
#include "../stdlib/text.h"
#include "../stdlib/util.h"
#include "../typecheck.h"
@@ -14,6 +13,7 @@
#include "conditionals.h"
#include "declarations.h"
#include "enums.h"
+#include "fieldaccess.h"
#include "functions.h"
#include "indexing.h"
#include "integers.h"
@@ -254,85 +254,7 @@ Text_t compile(env_t *env, ast_t *ast) {
case When: return compile_when_statement(env, ast);
case If: return compile_if_expression(env, ast);
case Reduction: return compile_reduction(env, ast);
- case FieldAccess: {
- DeclareMatch(f, ast, FieldAccess);
- type_t *fielded_t = get_type(env, f->fielded);
- type_t *value_t = value_type(fielded_t);
- switch (value_t->tag) {
- case TypeInfoType: {
- DeclareMatch(info, value_t, TypeInfoType);
- if (f->field[0] == '_') {
- if (!type_eq(env->current_type, info->type))
- code_err(ast, "Fields that start with underscores are not "
- "accessible "
- "on types outside of the type definition.");
- }
- binding_t *b = get_binding(info->env, f->field);
- if (!b) code_err(ast, "I couldn't find the field '", f->field, "' on this type");
- if (b->code.length == 0) code_err(ast, "I couldn't figure out how to compile this field");
- return b->code;
- }
- case TextType: {
- const char *lang = Match(value_t, TextType)->lang;
- if (lang && streq(f->field, "text")) {
- Text_t text = compile_to_pointer_depth(env, f->fielded, 0, false);
- return Texts("((Text_t)", text, ")");
- } else if (streq(f->field, "length")) {
- return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)");
- }
- code_err(ast, "There is no '", f->field, "' field on ", type_to_str(value_t), " values");
- }
- case StructType: {
- return compile_struct_field_access(env, ast);
- }
- case EnumType: {
- return compile_enum_field_access(env, ast);
- }
- case ListType: {
- if (streq(f->field, "length"))
- return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false), ").length)");
- code_err(ast, "There is no ", f->field, " field on lists");
- }
- case SetType: {
- if (streq(f->field, "items"))
- return Texts("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)");
- else if (streq(f->field, "length"))
- return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false),
- ").entries.length)");
- code_err(ast, "There is no '", f->field, "' field on sets");
- }
- case TableType: {
- if (streq(f->field, "length")) {
- return Texts("Int$from_int64((", compile_to_pointer_depth(env, f->fielded, 0, false),
- ").entries.length)");
- } else if (streq(f->field, "keys")) {
- return Texts("LIST_COPY((", compile_to_pointer_depth(env, f->fielded, 0, false), ").entries)");
- } else if (streq(f->field, "values")) {
- DeclareMatch(table, value_t, TableType);
- Text_t offset = Texts("offsetof(struct { ", compile_declaration(table->key_type, Text("k")), "; ",
- compile_declaration(table->value_type, Text("v")), "; }, v)");
- return Texts("({ List_t *entries = &(", compile_to_pointer_depth(env, f->fielded, 0, false),
- ").entries;\n"
- "LIST_INCREF(*entries);\n"
- "List_t values = *entries;\n"
- "values.data += ",
- offset,
- ";\n"
- "values; })");
- } else if (streq(f->field, "fallback")) {
- return Texts("({ Table_t *_fallback = (", compile_to_pointer_depth(env, f->fielded, 0, false),
- ").fallback; _fallback ? *_fallback : NONE_TABLE; })");
- }
- code_err(ast, "There is no '", f->field, "' field on tables");
- }
- case ModuleType: {
- const char *name = Match(value_t, ModuleType)->name;
- env_t *module_env = Table$str_get(*env->imports, name);
- return compile(module_env, WrapAST(ast, Var, f->field));
- }
- default: code_err(ast, "Field accesses are not supported on ", type_to_str(fielded_t), " values");
- }
- }
+ case FieldAccess: return compile_field_access(env, ast);
case Index: return compile_indexing(env, ast);
case InlineCCode: {
type_t *t = get_type(env, ast);