lemonlang 0.0.4

an experimental, modern, purely safe, programming language.
use crate::ast::{self};

use super::diags::SyntaxErr;
use super::types::{Type, TypeId};
use super::{Checker, TyResult};

impl Checker<'_> {
	pub fn check_ident_expr(&mut self, ident: &mut ast::Ident) -> TyResult<TypeId> {
		if self.ctx.has_accessor_scope() {
			return self.self_acessor(ident);
		}

		if let Some(value) = self.ctx.get_value(ident.lexeme()) {
			ident.set_type_id(value.type_id);
			return Ok(value.type_id);
		}

		self.ctx.type_store.create_monomo_fn(ident.lexeme().to_string());
		if let Some(fn_value) = self.ctx.get_fn_value(ident.lexeme()) {
			ident.set_type_id(fn_value.type_id);
			return Ok(fn_value.type_id);
		}
		self.ctx.type_store.end_monomo_fn();
		Err(SyntaxErr::not_found_value(ident.lexeme(), ident.get_range()))
	}

	pub fn self_acessor(&mut self, ident: &mut ast::Ident) -> TyResult<TypeId> {
		let lexeme = ident.lexeme();
		let self_type = self.ctx.accessor_scope_type().expect("error: accessor scope not found");

		let self_type = self.get_stored_type_without_borrow(self_type);

		if let Type::Struct(struct_type) = self_type {
			let found = self.display_type_value(self_type);
			let name = ident.lexeme().to_owned();

			if self.ctx.is_acessor_associate_scope() {
				if let Some(field_id) = struct_type.get_associate(lexeme) {
					ident.set_type_id(*field_id);
					return Ok(*field_id);
				}
				return Err(SyntaxErr::not_found_associate_field(name, found, ident.get_range()));
			}

			if let Some(field) = struct_type.get_field(lexeme) {
				ident.set_type_id(field.type_id);
				return Ok(field.type_id);
			}

			if let Some(method) = struct_type.get_fn(lexeme) {
				ident.set_type_id(*method);
				return Ok(*method);
			}

			return Err(SyntaxErr::not_found_method_named(name, found, ident.get_range()));
		}

		todo!("error: self type not found: {:?}", self_type)
	}
}