From 6717be038f3836bcaf86e1ecaf5722c5a5accb6e Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Wed, 15 Apr 2026 09:16:26 +0200 Subject: [PATCH] Top level scope --- Cargo.lock | 3 ++ parser/src/ast.rs | 8 +++ semantic/Cargo.toml | 1 + semantic/src/scope.rs | 22 +++----- semantic/src/top_level.rs | 111 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 126 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53b22b8..d1e4cb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,6 +158,9 @@ dependencies = [ [[package]] name = "semantic" version = "0.1.0" +dependencies = [ + "parser", +] [[package]] name = "serde" diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 63d7e24..4d9f0c7 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use serde::Serialize; #[derive(Debug, Clone, Serialize)] @@ -123,3 +125,9 @@ pub enum VarKind { Const, Var, } + +impl ParamList { + pub fn to_hashmap(&self, f: impl Fn(&String, &TypeExpr) -> T) -> HashMap { + self.0.iter().map(|(k, v)| (k.clone(), f(k, v))).collect() + } +} diff --git a/semantic/Cargo.toml b/semantic/Cargo.toml index c290a2c..69caf32 100644 --- a/semantic/Cargo.toml +++ b/semantic/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +parser = { path = "../parser" } diff --git a/semantic/src/scope.rs b/semantic/src/scope.rs index ea4398f..b395e5c 100644 --- a/semantic/src/scope.rs +++ b/semantic/src/scope.rs @@ -1,21 +1,13 @@ -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; +use std::sync::Arc; -use crate::top_level; +use crate::top_level::TopLevelScope; -pub enum Symbol { - Function(top_level::FunctionSymbol), - TypeSymbol(top_level::TypeSymbol), - StructSymbol(top_level::StructSymbol), -} - -pub struct Scope { - pub parent: Option>, - pub variables: Mutex>, +pub enum Scope { + TopLevel(TopLevelScope), } impl Scope { - pub fn from_top_level() {} + pub fn from_top(top_level: &Vec) -> Arc { + Arc::new(Self::TopLevel(TopLevelScope::from(top_level))) + } } diff --git a/semantic/src/top_level.rs b/semantic/src/top_level.rs index 904ea45..1817dc7 100644 --- a/semantic/src/top_level.rs +++ b/semantic/src/top_level.rs @@ -1,20 +1,123 @@ use std::collections::HashMap; -pub struct TypeSymbol { - pub export: bool, +use parser::ast::TopLevel; + +use parser::ast::{ParamList, TypeExpr}; + +pub struct TypeSymbol(pub String); + +pub struct VarSymbol { + pub var_type: TypeSymbol, pub name: String, } pub struct FunctionSymbol { pub export: bool, pub name: String, - pub params: HashMap, + pub params: HashMap, + pub return_type: Option, } pub struct StructSymbol { pub export: bool, pub name: String, - pub fields: HashMap, + pub fields: HashMap, pub methods: HashMap, } +impl TypeSymbol { + pub fn from_ast(expr: TypeExpr) -> Self { + TypeSymbol(match expr { + TypeExpr::Identifier(i) => i.to_string(), + }) + } +} + +impl FunctionSymbol { + pub fn from_ast( + export: bool, + name: String, + params: ParamList, + return_type: Option, + ) -> Self { + Self { + export: export, + name: name.clone(), + params: params.to_hashmap(|name, v| VarSymbol { + name: name.clone(), + var_type: TypeSymbol(match v { + TypeExpr::Identifier(i) => i.to_string(), + }), + }), + return_type: return_type.map(TypeSymbol::from_ast), + } + } +} + +impl StructSymbol { + pub fn from_ast(export: bool, name: String, fields: ParamList) -> Self { + Self { + export, + name, + fields: fields.to_hashmap(|name, v| VarSymbol { + name: name.clone(), + var_type: TypeSymbol(match v { + TypeExpr::Identifier(i) => i.to_string(), + }), + }), + // TODO - parse struct methods + methods: HashMap::new(), + } + } +} + +pub struct TopLevelScope { + pub structs: HashMap, + pub functions: HashMap, +} + +impl TopLevelScope { + pub fn from(top_level: &Vec) -> Self { + let mut scope = TopLevelScope { + structs: HashMap::new(), + functions: HashMap::new(), + }; + + for top in top_level { + match top { + TopLevel::Import(_) => unimplemented!(), + + TopLevel::FunctionDecl { + export, + name, + params, + return_type, + .. + } => { + scope.functions.insert( + name.clone(), + FunctionSymbol::from_ast( + *export, + name.clone(), + params.clone(), + return_type.clone(), + ), + ); + } + + TopLevel::StructDecl { + export, + name, + fields, + } => { + scope.structs.insert( + name.clone(), + StructSymbol::from_ast(*export, name.clone(), fields.clone()), + ); + } + } + } + + scope + } +}