112 lines
3.4 KiB
Rust
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>),
|
|
}
|
|
|
|
|