Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,17 +169,24 @@ Tree-sitter: `((a) (b))` — Plotnik: `{(a) (b)}`. The #1 syntax error.
```
crates/
plotnik-cli/ # CLI tool
src/commands/ # Subcommands (debug, exec, langs, types)
plotnik-core/ # Common code
src/commands/ # Subcommands (check, dump, infer, tree, langs)
plotnik-core/ # Common code (Interner, Symbol)
plotnik-lib/ # Plotnik as library
src/
diagnostics/ # Diagnostics (user-friendly errors)
parser/ # Syntactic parsing of the query
query/ # Analysis and representation of the parsed query
plotnik-langs/ # Tree-sitter language bindings (wrapped)
plotnik-macros/ # Proc macros of the project
analyze/ # Semantic analysis (symbol_table, dependencies, type_check, validation)
bytecode/ # Binary format definitions
typegen/ # Type declaration extraction (bytecode → .d.ts)
compile/ # Thompson NFA construction (AST → IR)
diagnostics/ # User-friendly error reporting
emit/ # Bytecode emission (IR → binary)
parser/ # Syntactic parsing (lexer, grammar, AST)
query/ # Query facade (Query, QueryBuilder, SourceMap)
type_system/ # Shared type primitives
plotnik-langs/ # Tree-sitter language bindings
plotnik-macros/ # Proc macros
docs/
adr/ # Architecture Decision Records (ADRs)
adr/ # Architecture Decision Records
binary-format/ # Bytecode format specification
lang-reference.md # Language specification
```

Expand Down
2 changes: 1 addition & 1 deletion crates/plotnik-cli/src/commands/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::PathBuf;

use plotnik_lib::QueryBuilder;
use plotnik_lib::bytecode::Module;
use plotnik_lib::codegen::typescript;
use plotnik_lib::typegen::typescript;

use super::lang_resolver::{resolve_lang, resolve_lang_required, suggest_language};
use super::query_loader::load_query_source;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ use std::collections::{HashMap, HashSet};

use indexmap::{IndexMap, IndexSet};
use plotnik_core::{Interner, Symbol};

use super::source_map::SourceId;
use rowan::TextRange;

use super::symbol_table::SymbolTable;
use super::type_check::DefId;
use super::visitor::{Visitor, walk_expr};
use crate::Diagnostics;
use crate::diagnostics::DiagnosticKind;
use crate::parser::{AnonymousNode, Def, Expr, NamedNode, Ref, Root, SeqExpr};
use crate::query::symbol_table::SymbolTable;
use crate::query::type_check::DefId;
use crate::query::visitor::{Visitor, walk_expr};
use crate::query::source_map::SourceId;

/// Result of dependency analysis.
#[derive(Clone, Debug, Default)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ pub struct LinkOutput {
pub node_field_ids: IndexMap<Symbol, NodeFieldId>,
}

use super::symbol_table::SymbolTable;
use super::utils::find_similar;
use super::visitor::{Visitor, walk};
use crate::diagnostics::{DiagnosticKind, Diagnostics};
use crate::parser::ast::{self, Expr, NamedNode};
use crate::parser::cst::{SyntaxKind, SyntaxToken};
use crate::parser::token_src;

use super::query::AstMap;
use super::source_map::{SourceId, SourceMap};
use super::symbol_table::SymbolTable;
use super::utils::find_similar;
use super::visitor::{Visitor, walk};
use crate::query::query::AstMap;
use crate::query::source_map::{SourceId, SourceMap};

/// Link query against a language grammar.
///
Expand Down
32 changes: 32 additions & 0 deletions crates/plotnik-lib/src/analyze/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//! Semantic analysis passes.
//!
//! Provides analysis passes that transform parsed AST into analyzed form:
//! - Name resolution (symbol_table)
//! - Dependency analysis and recursion detection (dependencies)
//! - Type inference (type_check)
//! - Grammar linking (link)
//! - Semantic validation (validation)

pub mod dependencies;
mod invariants;
pub mod link;
pub mod refs;
pub mod symbol_table;
pub mod type_check;
mod utils;
pub mod validation;
pub mod visitor;

#[cfg(test)]
mod dependencies_tests;
#[cfg(all(test, feature = "plotnik-langs"))]
mod link_tests;
#[cfg(test)]
mod symbol_table_tests;

pub use dependencies::DependencyAnalysis;
pub use link::LinkOutput;
pub use symbol_table::{SymbolTable, UNNAMED_DEF};
pub use type_check::{TypeContext, infer_types, primary_def_name};
pub use validation::{validate_alt_kinds, validate_anchors};
pub use visitor::{Visitor, walk_expr};
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::Diagnostics;
use crate::diagnostics::DiagnosticKind;
use crate::parser::{Root, ast, token_src};

use super::source_map::{SourceId, SourceMap};
use super::visitor::Visitor;
use crate::query::source_map::{SourceId, SourceMap};

/// Sentinel name for unnamed definitions (bare expressions at root level).
/// Code generators can emit whatever name they want for this.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ mod tests {
use std::collections::BTreeMap;

use super::*;
use crate::query::type_check::types::FieldInfo;

#[test]
fn builtin_types_have_correct_ids() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ use super::types::{
};
use super::unify::{UnifyError, unify_flows};

use crate::analyze::symbol_table::SymbolTable;
use crate::analyze::visitor::{Visitor, walk_alt_expr, walk_def, walk_named_node, walk_seq_expr};
use crate::diagnostics::{DiagnosticKind, Diagnostics};
use crate::parser::ast::{
AltExpr, AltKind, AnonymousNode, CapturedExpr, Def, Expr, FieldExpr, NamedNode, QuantifiedExpr,
Ref, Root, SeqExpr,
};
use crate::parser::cst::SyntaxKind;
use crate::query::source_map::SourceId;
use crate::query::symbol_table::SymbolTable;
use crate::query::visitor::{Visitor, walk_alt_expr, walk_def, walk_named_node, walk_seq_expr};

/// Inference context for a single pass over the AST.
pub struct InferenceVisitor<'a, 'd> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
mod context;
mod infer;
mod symbol;
mod types;
pub(crate) mod types;
mod unify;

#[cfg(test)]
Expand All @@ -24,11 +24,11 @@ use std::collections::BTreeMap;

use indexmap::IndexMap;

use crate::analyze::dependencies::DependencyAnalysis;
use crate::analyze::symbol_table::{SymbolTable, UNNAMED_DEF};
use crate::diagnostics::Diagnostics;
use crate::parser::ast::Root;
use crate::query::dependencies::DependencyAnalysis;
use crate::query::source_map::SourceId;
use crate::query::symbol_table::{SymbolTable, UNNAMED_DEF};

use infer::infer_root;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ fn unify_type_ids(a: TypeId, b: TypeId, field: Symbol) -> Result<TypeId, UnifyEr
#[cfg(test)]
mod tests {
use super::*;
use crate::query::type_check::TYPE_NODE;
use crate::analyze::type_check::TYPE_NODE;
use plotnik_core::Interner;

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
//! Checks constraints that are easier to express after parsing:
//! - Mixed tagged/untagged alternations

use super::invariants::ensure_both_branch_kinds;
use super::visitor::{Visitor, walk, walk_alt_expr};
use crate::SourceId;
use crate::analyze::invariants::ensure_both_branch_kinds;
use crate::analyze::visitor::{Visitor, walk, walk_alt_expr};
use crate::diagnostics::{DiagnosticKind, Diagnostics};
use crate::parser::{AltExpr, AltKind, Branch, Root};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//!
//! This validation ensures anchors are placed where they can be meaningfully compiled.

use super::visitor::{Visitor, walk_named_node, walk_seq_expr};
use crate::SourceId;
use crate::analyze::visitor::{Visitor, walk_named_node, walk_seq_expr};
use crate::diagnostics::{DiagnosticKind, Diagnostics};
use crate::parser::ast::{NamedNode, Root, SeqExpr, SeqItem};

Expand Down
16 changes: 16 additions & 0 deletions crates/plotnik-lib/src/analyze/validation/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! Semantic validation passes.
//!
//! Validates semantic constraints that aren't captured by parsing or type checking:
//! - Alternation kind consistency (alt_kinds)
//! - Anchor placement rules (anchors)

pub mod alt_kinds;
pub mod anchors;

#[cfg(test)]
mod alt_kinds_tests;
#[cfg(test)]
mod anchors_tests;

pub use alt_kinds::validate_alt_kinds;
pub use anchors::validate_anchors;
10 changes: 0 additions & 10 deletions crates/plotnik-lib/src/bytecode/emit/mod.rs

This file was deleted.

2 changes: 1 addition & 1 deletion crates/plotnik-lib/src/bytecode/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use super::effects::{EffectOp, EffectOpcode};
use super::ids::StepId;
use super::instructions::{Call, Match, Return, select_match_opcode};
use super::nav::Nav;
use crate::query::type_check::TypeId;
use crate::analyze::type_check::TypeId;

/// Symbolic reference, resolved to StepId at layout time.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
Expand Down
4 changes: 0 additions & 4 deletions crates/plotnik-lib/src/bytecode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
mod constants;
mod dump;
mod effects;
pub mod emit;
mod entrypoint;
mod header;
mod ids;
mod instructions;
pub mod ir;
pub mod layout;
mod module;
mod nav;
mod sections;
Expand Down Expand Up @@ -52,6 +50,4 @@ mod dump_tests;
#[cfg(test)]
mod instructions_tests;
#[cfg(test)]
mod layout_tests;
#[cfg(test)]
mod module_tests;
21 changes: 0 additions & 21 deletions crates/plotnik-lib/src/codegen/mod.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::collections::HashSet;
use crate::bytecode::ir::EffectIR;
use crate::bytecode::EffectOpcode;
use crate::parser::ast::{self, Expr};
use crate::query::type_check::{TypeContext, TypeId, TypeShape};
use crate::analyze::type_check::{TypeContext, TypeId, TypeShape};

use super::navigation::{inner_creates_scope, is_star_or_plus_quantifier};
use super::Compiler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::num::NonZeroU16;
use crate::bytecode::ir::{CallIR, Instruction, Label, MatchIR};
use crate::bytecode::Nav;
use crate::parser::ast::{self, Expr};
use crate::query::type_check::Arity;
use crate::analyze::type_check::Arity;

use super::capture::CaptureEffects;
use super::navigation::{check_trailing_anchor, inner_creates_scope, is_skippable_quantifier, is_star_or_plus_quantifier};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ use crate::bytecode::ir::{Instruction, Label, ReturnIR};
use crate::bytecode::Nav;
use crate::parser::ast::Expr;

use super::codegen::StringTableBuilder;
use super::symbol_table::SymbolTable;
use super::type_check::{DefId, TypeContext};
use crate::emit::StringTableBuilder;
use crate::analyze::symbol_table::SymbolTable;
use crate::analyze::type_check::{DefId, TypeContext};

pub use capture::CaptureEffects;
use scope::StructScope;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::bytecode::ir::{EffectIR, Label};
use crate::bytecode::{EffectOpcode, Nav};
use crate::parser::ast::{self, Expr};
use crate::parser::cst::SyntaxKind;
use crate::query::type_check::TypeId;
use crate::analyze::type_check::TypeId;

use super::capture::{check_needs_struct_wrapper, get_row_type_id, CaptureEffects};
use super::navigation::{is_star_or_plus_quantifier, repeat_nav_for};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use crate::bytecode::ir::{EffectIR, Instruction, Label, MatchIR, MemberRef};
use crate::bytecode::{EffectOpcode, Nav};
use crate::parser::ast::Expr;
use crate::query::type_check::TypeId;
use crate::analyze::type_check::TypeId;

use super::capture::CaptureEffects;
use super::Compiler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use crate::bytecode::ir::{EffectIR, Instruction, Label, MatchIR, MemberRef};
use crate::bytecode::{EffectOpcode, Nav};
use crate::parser::ast::{self, Expr, SeqItem};
use crate::query::type_check::TypeShape;
use crate::analyze::type_check::TypeShape;

use super::capture::CaptureEffects;
use super::navigation::{compute_nav_modes, is_down_nav, is_skippable_quantifier, repeat_nav_for};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use indoc::indoc;

use crate::Query;
use crate::bytecode::{Header, MAGIC, Module, QTypeId, VERSION};
use crate::query::codegen::{StringTableBuilder, TypeTableBuilder};
use super::{StringTableBuilder, TypeTableBuilder};

#[test]
fn emit_minimal_query() {
Expand Down Expand Up @@ -182,12 +182,12 @@ fn string_table_builder_intern_str() {

#[test]
fn type_table_builder_builtins() {
use crate::query::type_check::{TYPE_NODE, TYPE_STRING, TYPE_VOID};
use crate::analyze::type_check::{TYPE_NODE, TYPE_STRING, TYPE_VOID};

let mut builder = TypeTableBuilder::new();

// Build with empty context
let type_ctx = crate::query::type_check::TypeContext::new();
let type_ctx = crate::analyze::type_check::TypeContext::new();
let interner = plotnik_core::Interner::new();
let mut strings = StringTableBuilder::new();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

use std::collections::{BTreeMap, HashSet};

use super::ids::StepId;
use super::ir::{Instruction, Label, LayoutResult};
use crate::bytecode::StepId;
use crate::bytecode::ir::{Instruction, Label, LayoutResult};

const CACHE_LINE: usize = 64;
const STEP_SIZE: usize = 8;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::num::NonZeroU16;

use super::ids::StepId;
use super::ir::{CallIR, EffectIR, Instruction, Label, MatchIR, ReturnIR};
use crate::bytecode::StepId;
use crate::bytecode::ir::{CallIR, EffectIR, Instruction, Label, MatchIR, ReturnIR};
use crate::bytecode::EffectOpcode;
use crate::bytecode::Nav;
use super::layout::CacheAligned;
use crate::bytecode::effects::EffectOpcode;
use crate::bytecode::nav::Nav;

#[test]
fn layout_empty() {
Expand Down
Loading