From d124ae2b599351c77a4eb5551b811804f0733466 Mon Sep 17 00:00:00 2001 From: Janis Date: Sat, 2 Aug 2025 21:25:04 +0200 Subject: [PATCH] nix flake/direnv --- .envrc | 1 + flake.lock | 96 +++++++++++++++++++++++++++++++++++++++ flake.nix | 31 +++++++++++++ src/ast2/biunification.rs | 88 +++++++++++++++++++++++++++++++++++ src/ast2/mod.rs | 2 + src/ast2/typecheck.rs | 4 -- 6 files changed, 218 insertions(+), 4 deletions(-) create mode 100644 .envrc create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 src/ast2/biunification.rs diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8392d15 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7396506 --- /dev/null +++ b/flake.lock @@ -0,0 +1,96 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1753939845, + "narHash": "sha256-K2ViRJfdVGE8tpJejs8Qpvvejks1+A4GQej/lBk5y7I=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "94def634a20494ee057c76998843c015909d6311", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlays": "rust-overlays" + } + }, + "rust-overlays": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1754102567, + "narHash": "sha256-d6nZ+1e4VDqW6VAwfx9EAUDJdPxSwqwGiuli32FEgoE=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "08ff39bf869cadca3102b39824f4c7025186b7dc", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9d515a2 --- /dev/null +++ b/flake.nix @@ -0,0 +1,31 @@ +{ + description = "A nix flake for nightly rust"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + rust-overlays.url = "github:oxalica/rust-overlay"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, rust-overlays, ...}: + flake-utils.lib.eachDefaultSystem (system: let + overlays = [ + (import rust-overlays) + ]; + pkgs = import nixpkgs { + inherit system overlays; + }; + rust = pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override { + extensions = ["rust-src" "rust-analyzer"]; + targets = [ "x86_64-unknown-linux-gnu" ]; + }); + in with pkgs; { + devShells.default = pkgs.mkShell { + buildInputs = [ + pkg-config + git + rust + ]; + }; + }); +} diff --git a/src/ast2/biunification.rs b/src/ast2/biunification.rs new file mode 100644 index 0000000..765140e --- /dev/null +++ b/src/ast2/biunification.rs @@ -0,0 +1,88 @@ +//! Type checking for the AST. +//! This module implements a bi-unification type-checking algorithm to infer +//! types for each node in the AST. + +// Visitor pattern has lots of unused arguments +#![allow(unused_variables)] + +use std::collections::HashMap; + +use super::{Ast, Index, intern, visitor::AstVisitorTrait}; + +type Id = u32; + +enum Type { + Reified(intern::Index), + Variable(Id), +} + +/// Variance of a type parameter or constraint. +/// A function of type `A -> B` is covariant in `B` and contravariant in `A`. +/// This means that a type `T` may be substituted for `A` if `T` is a subtype of `A`, but +/// a type `T` may only be substituted for `B` if `T` is a supertype of `B`. +/// +/// Namely, in a type system with `int` and `nat <: int`, for a function `f: int +/// -> int` in the expression `let u: int = 3; let t: nat = f(u);`, `u` may +/// safely be used as an argument to `f` because `nat <: int`, but `f(u`)` may +/// not be assigned to `t` because `int <: nat` is not true. +enum Variance { + #[doc(alias = "Positive")] + Covariant, + #[doc(alias = "Negative")] + Contravariant, +} + +#[derive(Debug, Clone, Copy)] +struct Value(Id); +#[derive(Debug, Clone, Copy)] +struct Use(Id); + +/// Typechecking error. +#[derive(Debug, Clone, thiserror::Error)] +enum Error { + #[error("Unimplemented feature")] + Unimplemented, +} + +type Result = std::result::Result; + +struct Bindings { + inner: HashMap, +} + +struct TypeChecker<'a> { + pool: &'a mut intern::InternPool, +} + +// Core +impl TypeChecker<'_> { + pub fn new(pool: &mut intern::InternPool) -> TypeChecker { + TypeChecker { pool } + } + + fn var(&mut self) -> (Value, Use) { + todo!() + } +} + +// Frontend + +impl<'a> AstVisitorTrait<&'a Ast> for TypeChecker<'_> { + type Error = Error; + type Value = Value; + + const UNIMPL: Self::Error = Error::Unimplemented; + + fn visit_constant_impl( + &mut self, + ast: &'a Ast, + idx: Index, + ty: Index, + value: intern::Index, + ) -> std::result::Result { + // constants may be of type `comptime_int`, which is a special type that + // cannot exist at runtime. + + todo!() + } +} diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs index 14597b6..cf27e46 100644 --- a/src/ast2/mod.rs +++ b/src/ast2/mod.rs @@ -13,6 +13,7 @@ use crate::{ symbol_table::syms2::DeclKind, tokens::Token, }; +pub mod biunification; pub mod debug; pub mod intern; pub mod ir; @@ -586,6 +587,7 @@ mod index { } } + /// Index tyoe for the AST. /// Index type that has 28 bits of index and 4 bits of kind. #[repr(transparent)] #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] diff --git a/src/ast2/typecheck.rs b/src/ast2/typecheck.rs index da52c77..184f2db 100644 --- a/src/ast2/typecheck.rs +++ b/src/ast2/typecheck.rs @@ -1,7 +1,3 @@ -//! Type checking for the AST. -//! This module implements a bi-unification type-checking algorithm to infer -//! types for each node in the AST. - // Visitor pattern has lots of unused arguments #![allow(unused_variables)]