feat: Add StaticType and type checking
This commit introduces `StaticType` and enhances the `Binder` to perform
basic type checking during the binding phase.
Key changes include:
- **`StaticType` enum:** Represents static types such as `Any`, `Void`,
`Bool`, `Int`, `Float`, `Text`, `List`, `Record`, and `Function`.
- **`Node<K, T>`:** The generic `Node` now includes a `ty` field to
store its inferred static type.
- **Binder enhancements:**
- `CompilerScope` now stores `LocalInfo` containing the variable's
slot and `StaticType`.
- `FunctionCompiler` stores upvalues with their associated
`StaticType`.
- `Binder::bind` now returns `Node<BoundKind, StaticType>`,
propagating type information.
- Type checking is added for `If` conditions and `Assign`
operations.
- `Def` nodes now infer and store the type of the defined variable.
- **`Value::static_type()`:** A new method to determine the `StaticType`
of a `Value`.
- **Environment modifications:** `global_names` now stores `(u32,
StaticType)` to associate global variables with their types.
- **Parser modifications:** The `ty` field of nodes is initialized to
`()` by default.
- **VM modifications:** `VM::run` and `VM::eval` now operate on
`Node<BoundKind, StaticType>`.
- **Tests:** Added basic evaluation and type error tests.
feat: Add StaticType and type checking
Introduces `StaticType` enum and integrates it into the AST. The binder
now performs type checking during compilation, ensuring that expressions
conform to expected types, especially for control flow structures like
`if`. This lays the groundwork for static type analysis and error
reporting.
This commit is contained in:
+37
-4
@@ -1,19 +1,19 @@
|
||||
use std::collections::{HashMap, BTreeMap};
|
||||
use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::sync::Mutex;
|
||||
use lazy_static::lazy_static;
|
||||
use std::any::Any;
|
||||
|
||||
/// Simple source location
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct SourceLocation {
|
||||
pub line: u32,
|
||||
pub col: u32,
|
||||
}
|
||||
|
||||
/// Shared identity for nodes (Location, etc.)
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct NodeIdentity {
|
||||
pub location: SourceLocation,
|
||||
}
|
||||
@@ -21,7 +21,7 @@ pub struct NodeIdentity {
|
||||
pub type Identity = Arc<NodeIdentity>;
|
||||
|
||||
/// Interned string identifier
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Keyword(pub u32);
|
||||
|
||||
lazy_static! {
|
||||
@@ -70,6 +70,24 @@ pub enum Value {
|
||||
Object(Arc<dyn Object>), // For compiled Closures and other opaque types
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum StaticType {
|
||||
Any,
|
||||
Void,
|
||||
Bool,
|
||||
Int,
|
||||
Float,
|
||||
Text,
|
||||
Keyword,
|
||||
List(Box<StaticType>),
|
||||
Record(Arc<BTreeMap<Keyword, StaticType>>),
|
||||
Function {
|
||||
params: Vec<StaticType>,
|
||||
ret: Box<StaticType>,
|
||||
},
|
||||
Object(&'static str),
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub fn is_truthy(&self) -> bool {
|
||||
match self {
|
||||
@@ -78,6 +96,21 @@ impl Value {
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn static_type(&self) -> StaticType {
|
||||
match self {
|
||||
Value::Void => StaticType::Void,
|
||||
Value::Bool(_) => StaticType::Bool,
|
||||
Value::Int(_) => StaticType::Int,
|
||||
Value::Float(_) => StaticType::Float,
|
||||
Value::Text(_) => StaticType::Text,
|
||||
Value::Keyword(_) => StaticType::Keyword,
|
||||
Value::List(_) => StaticType::List(Box::new(StaticType::Any)),
|
||||
Value::Record(_) => StaticType::Record(Arc::new(BTreeMap::new())), // Empty for now
|
||||
Value::Function { .. } => StaticType::Any, // Dynamic function
|
||||
Value::Object(o) => StaticType::Object(o.type_name()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Value {
|
||||
|
||||
Reference in New Issue
Block a user