mclangc/src/parser/ast/mod.rs
2026-01-17 16:31:40 +02:00

112 lines
3.4 KiB
Rust

use std::collections::HashMap;
use statement::{ConstVar, Enum, Function, StaticVar, Struct};
use crate::{common::loc::LocBox, parser::ast::{expr::Path, statement::Let, typ::Type}};
pub use crate::tokeniser::tokentype::*;
pub mod expr;
pub mod literal;
pub mod statement;
pub mod typ;
#[derive(Debug, Clone)]
pub struct Scope {
pub vars: HashMap<Ident, LocBox<Let>>,
pub static_vars: HashMap<Ident, StaticVar>,
pub const_vars: HashMap<Ident, ConstVar>,
pub inner_scope: Option<Box<Scope>>
}
#[derive(Debug, Clone)]
pub struct Program {
pub ast: expr::Block,
pub structs: HashMap<Ident, LocBox<Struct>>,
pub enums: HashMap<Ident, LocBox<Enum>>,
pub types: HashMap<Ident, LocBox<Type>>,
pub functions: HashMap<Ident, LocBox<Function>>,
pub member_functions: HashMap<Ident, HashMap<Ident, LocBox<Function>>>,
pub static_vars: HashMap<Ident, StaticVar>,
pub const_vars: HashMap<Ident, ConstVar>,
pub scope: Option<Scope>
}
impl Scope {
pub fn get_var(&self, name: &Ident) -> Option<(Ident, LocBox<Let>)> {
if let Some(inner) = &self.inner_scope {
if let Some((ident, var)) = inner.get_var(name) {
return Some((ident, var));
}
}
if let Some(var) = self.vars.get(name) {
return Some((name.clone(), var.clone()));
}
None
}
pub fn get_static_var(&self, name: &Ident) -> Option<(Ident, LocBox<StaticVar>)> {
if let Some(inner) = &self.inner_scope {
if let Some((ident, var)) = inner.get_static_var(name) {
return Some((ident, var));
}
}
if let Some(var) = self.static_vars.get(name) {
return Some((name.clone(), LocBox::new(var.typ.loc(), var.clone())));
}
None
}
pub fn get_const_var(&self, name: &Ident) -> Option<(Ident, LocBox<ConstVar>)> {
if let Some(inner) = &self.inner_scope {
if let Some((ident, var)) = inner.get_const_var(name) {
return Some((ident, var));
}
}
if let Some(var) = self.const_vars.get(name) {
return Some((name.clone(), LocBox::new(var.typ.loc(), var.clone())));
}
None
}
}
impl Program {
pub fn get_var(&self, name: &Ident) -> Option<(Ident, LocBox<Let>)> {
if let Some(scope) = &self.scope {
scope.get_var(name)
} else {
None
}
}
pub fn get_static_var(&self, name: &Ident) -> Option<(Ident, LocBox<StaticVar>)> {
if let Some(scope) = &self.scope {
if let Some((name, var)) = scope.get_static_var(name) {
return Some((name, var));
}
}
if let Some(var) = self.static_vars.get(name) {
return Some((name.clone(), LocBox::new(var.typ.loc(), var.clone())));
}
None
}
pub fn get_const_var(&self, name: &Ident) -> Option<(Ident, LocBox<ConstVar>)> {
if let Some(scope) = &self.scope {
if let Some((name, var)) = scope.get_const_var(name) {
return Some((name, var));
}
}
if let Some(var) = self.const_vars.get(name) {
return Some((name.clone(), LocBox::new(var.typ.loc(), var.clone())));
}
None
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum Ast {
Expr(LocBox<expr::Expr>),
Statement(LocBox<statement::Statement>),
}