mica/ll/codegen/
structs.rs1use std::{collections::HashMap, rc::Rc};
4
5use super::{
6 variables::{VariableAllocation, VariablePlace},
7 CodeGenerator, ExpressionResult,
8};
9use crate::ll::{
10 ast::{Ast, NodeId},
11 bytecode::{Opcode, Opr24},
12 error::{LanguageError, LanguageErrorKind},
13};
14
15#[derive(Debug, Default)]
16pub(super) struct StructData {
17 pub(crate) fields: HashMap<Rc<str>, Opr24>,
19 pub(crate) receiver: Option<VariablePlace>,
21}
22
23impl StructData {
24 pub(super) fn get_or_create_field(&mut self, name: &str) -> Result<Opr24, LanguageErrorKind> {
27 if !self.fields.contains_key(name) {
28 let index =
29 Opr24::try_from(self.fields.len()).map_err(|_| LanguageErrorKind::TooManyFields)?;
30 self.fields.insert(Rc::from(name), index);
31 Ok(index)
32 } else {
33 Ok(*self.fields.get(name).unwrap())
34 }
35 }
36
37 pub(super) fn get_field(&self, name: &str) -> Option<Opr24> {
39 self.fields.get(name).copied()
40 }
41}
42
43impl<'e> CodeGenerator<'e> {
44 pub(super) fn generate_field(
46 &mut self,
47 ast: &Ast,
48 node: NodeId,
49 ) -> Result<ExpressionResult, LanguageError> {
50 let (name, _) = ast.node_pair(node);
51 let name = ast.string(name).unwrap();
52 let struct_data = self
53 .struct_data
54 .as_deref()
55 .ok_or_else(|| ast.error(node, LanguageErrorKind::FieldOutsideOfImpl))?;
56 let field_id = struct_data.get_field(name).ok_or_else(|| {
57 ast.error(node, LanguageErrorKind::FieldDoesNotExist(Rc::clone(name)))
58 })?;
59 let receiver = struct_data.receiver.unwrap();
63 self.generate_variable_load(receiver);
64 self.chunk.emit((Opcode::GetField, field_id));
65 Ok(ExpressionResult::Present)
66 }
67
68 pub(super) fn generate_struct(
70 &mut self,
71 ast: &Ast,
72 node: NodeId,
73 ) -> Result<ExpressionResult, LanguageError> {
74 let (name, _) = ast.node_pair(node);
75 let name = ast.string(name).unwrap();
76
77 self.chunk.emit(Opcode::CreateType);
78 self.chunk.emit_string(name);
79 let variable = self
80 .create_variable(name, VariableAllocation::Allocate)
81 .map_err(|kind| ast.error(node, kind))?;
82 self.generate_variable_assign(variable);
83
84 Ok(ExpressionResult::Present)
85 }
86}