forked from wavefnd/Wave
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstructs.rs
More file actions
76 lines (63 loc) · 2.13 KB
/
structs.rs
File metadata and controls
76 lines (63 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use super::ExprGenEnv;
use inkwell::values::{BasicValue, BasicValueEnum};
use parser::ast::{Expression};
use crate::llvm_temporary::llvm_codegen::generate_address_ir;
pub(crate) fn gen_struct_literal<'ctx, 'a>(
env: &mut ExprGenEnv<'ctx, 'a>,
name: &str,
fields: &[(String, Expression)],
) -> BasicValueEnum<'ctx> {
let struct_ty = *env
.struct_types
.get(name)
.unwrap_or_else(|| panic!("Struct type '{}' not found", name));
let field_indices = env
.struct_field_indices
.get(name)
.unwrap_or_else(|| panic!("Field index map for struct '{}' not found", name));
let tmp_alloca = env
.builder
.build_alloca(struct_ty, &format!("tmp_{}_literal", name))
.unwrap();
for (field_name, field_expr) in fields {
let idx = field_indices
.get(field_name)
.unwrap_or_else(|| panic!("Field '{}' not found in struct '{}'", field_name, name));
let expected_field_ty = struct_ty
.get_field_type_at_index(*idx)
.unwrap_or_else(|| panic!("No field type at index {} for struct '{}'", idx, name));
let field_val = env.gen(field_expr, Some(expected_field_ty));
let field_ptr = env
.builder
.build_struct_gep(tmp_alloca, *idx, &format!("{}.{}", name, field_name))
.unwrap();
env.builder.build_store(field_ptr, field_val).unwrap();
}
env.builder
.build_load(tmp_alloca, &format!("{}_literal_val", name))
.unwrap()
.as_basic_value_enum()
}
pub(crate) fn gen_field_access<'ctx, 'a>(
env: &mut ExprGenEnv<'ctx, 'a>,
object: &Expression,
field: &str,
) -> BasicValueEnum<'ctx> {
let full = Expression::FieldAccess {
object: Box::new(object.clone()),
field: field.to_string(),
};
let ptr = generate_address_ir(
env.context,
env.builder,
&full,
env.variables,
env.module,
env.struct_types,
env.struct_field_indices,
);
env.builder
.build_load(ptr, &format!("load_field_{}", field))
.unwrap()
.as_basic_value_enum()
}