From 467863004cc1872bb207616cb4d58dcf053ba60e Mon Sep 17 00:00:00 2001 From: LunaStev Date: Wed, 19 Aug 2026 15:43:26 +0900 Subject: [PATCH 1/2] toolchain.rs comment 1 --- llvm/src/toolchain.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/llvm/src/toolchain.rs b/llvm/src/toolchain.rs index 93e8c1ac..ade3f2cd 100644 --- a/llvm/src/toolchain.rs +++ b/llvm/src/toolchain.rs @@ -13,12 +13,25 @@ use std::env; use std::path::{Path, PathBuf}; +/** +- This function creates candidate paths and finds + the first one where the actual file exists. + + - The function means “Linux C Runtime-related objects included + with the programming package,” or, in other words, + “Find the Linux CRT files bundled with Wave.” +*/ pub fn find_bundled_linux_crt(target: &str, abi: Option<&str>, name: &str) -> Option { bundled_linux_crt_candidates(target, abi, name) .into_iter() .find(|path| path.is_file()) } +/** +- This function creates and returns a predicted path where the CRT should be located. + +- The function name means “returns the path where the bundled Linux CRT is expected to be located.” + */ pub fn expected_bundled_linux_crt(target: &str, abi: Option<&str>, name: &str) -> PathBuf { bundled_linux_crt_candidates(target, abi, name) .into_iter() From cbfd2d5038a62ae6d0a9a1216b653a3326015b1a Mon Sep 17 00:00:00 2001 From: LunaStev Date: Thu, 20 Aug 2026 13:46:02 +0900 Subject: [PATCH 2/2] Document compiler architecture and contributor contracts Add module-level documentation across all Rust source files so contributors can identify each component's responsibility and phase boundaries before modifying it. Explain frontend parsing, import expansion, generic monomorphization, semantic typing, CLI planning, target resolution, C ABI classification, LLVM lowering, inline assembly, CRT discovery, and pre-link validation contracts. Document opaque-pointer and expression-type invariants, distinguish active implementations from compatibility paths, and add concrete safety rationale around LLVM FFI, GEP, and inline-assembly operations. Replace temporary or informal comments with concise Rustdoc that passes strict rustdoc warning checks without changing compiler behavior. --- front/error/src/error.rs | 6 +++ front/error/src/lib.rs | 5 +++ front/lexer/src/core.rs | 6 +++ front/lexer/src/cursor.rs | 5 +++ front/lexer/src/ident.rs | 6 +++ front/lexer/src/lib.rs | 6 +++ front/lexer/src/literals.rs | 5 +++ front/lexer/src/scan.rs | 7 +++ front/lexer/src/token.rs | 6 +++ front/lexer/src/trivia.rs | 6 +++ front/parser/src/arch/aarch64.rs | 2 + front/parser/src/arch/mod.rs | 6 +++ front/parser/src/arch/riscv64.rs | 2 + front/parser/src/arch/x86_64.rs | 2 + front/parser/src/ast.rs | 7 +++ front/parser/src/expr/assign.rs | 5 +++ front/parser/src/expr/binary.rs | 7 +++ front/parser/src/expr/helpers.rs | 6 +++ front/parser/src/expr/mod.rs | 6 +++ front/parser/src/expr/postfix.rs | 6 +++ front/parser/src/expr/primary.rs | 5 +++ front/parser/src/expr/unary.rs | 5 +++ front/parser/src/format.rs | 5 +++ front/parser/src/generics.rs | 25 +++++++++++ front/parser/src/import.rs | 7 +++ front/parser/src/lib.rs | 6 +++ front/parser/src/parser/asm.rs | 6 +++ front/parser/src/parser/control.rs | 6 +++ front/parser/src/parser/decl.rs | 6 +++ front/parser/src/parser/expr.rs | 6 +++ front/parser/src/parser/functions.rs | 6 +++ front/parser/src/parser/io.rs | 7 ++- front/parser/src/parser/items.rs | 6 +++ front/parser/src/parser/mod.rs | 5 +++ front/parser/src/parser/parse.rs | 6 +++ front/parser/src/parser/stmt.rs | 6 +++ front/parser/src/parser/types.rs | 5 +++ front/parser/src/stdlib.rs | 5 +++ front/parser/src/verification.rs | 13 ++++++ front/parser/tests/parse_var_and_generics.rs | 2 + llvm/src/backend.rs | 6 +++ llvm/src/codegen/abi_c.rs | 45 +++++++++++++++----- llvm/src/codegen/address.rs | 7 +++ llvm/src/codegen/arch/aarch64.rs | 5 +++ llvm/src/codegen/arch/mod.rs | 11 +++++ llvm/src/codegen/arch/riscv64.rs | 8 ++++ llvm/src/codegen/arch/x86_64.rs | 6 +++ llvm/src/codegen/consts.rs | 7 +++ llvm/src/codegen/format.rs | 13 +++--- llvm/src/codegen/ir.rs | 31 ++++++++++++++ llvm/src/codegen/legacy.rs | 12 ++++++ llvm/src/codegen/mod.rs | 5 +++ llvm/src/codegen/plan.rs | 7 ++- llvm/src/codegen/semantic.rs | 8 ++++ llvm/src/codegen/target.rs | 22 ++++++++++ llvm/src/codegen/types.rs | 6 +++ llvm/src/expression/lvalue.rs | 6 +++ llvm/src/expression/mod.rs | 6 +++ llvm/src/expression/rvalue/arrays.rs | 7 +++ llvm/src/expression/rvalue/asm.rs | 11 +++++ llvm/src/expression/rvalue/assign.rs | 7 +++ llvm/src/expression/rvalue/binary.rs | 9 ++++ llvm/src/expression/rvalue/calls.rs | 7 +++ llvm/src/expression/rvalue/cast.rs | 10 ++++- llvm/src/expression/rvalue/dispatch.rs | 6 +++ llvm/src/expression/rvalue/incdec.rs | 9 ++++ llvm/src/expression/rvalue/index.rs | 6 +++ llvm/src/expression/rvalue/literals.rs | 6 +++ llvm/src/expression/rvalue/mod.rs | 7 +++ llvm/src/expression/rvalue/pointers.rs | 6 +++ llvm/src/expression/rvalue/structs.rs | 6 +++ llvm/src/expression/rvalue/unary.rs | 5 +++ llvm/src/expression/rvalue/utils.rs | 2 + llvm/src/expression/rvalue/variables.rs | 6 +++ llvm/src/importgen.rs | 6 +++ llvm/src/lib.rs | 9 ++++ llvm/src/statement/asm.rs | 6 +++ llvm/src/statement/assign.rs | 6 +++ llvm/src/statement/control.rs | 9 ++++ llvm/src/statement/expr_stmt.rs | 5 +++ llvm/src/statement/io.rs | 6 +++ llvm/src/statement/mod.rs | 9 ++++ llvm/src/statement/variable.rs | 6 +++ llvm/src/toolchain.rs | 34 +++++++++------ src/cli.rs | 7 +++ src/errors.rs | 6 +++ src/flags.rs | 6 +++ src/lib.rs | 6 +++ src/link_validation/elf.rs | 9 +++- src/link_validation/mod.rs | 5 +++ src/link_validation/riscv.rs | 8 ++++ src/main.rs | 6 +++ src/runner.rs | 13 ++++++ src/std.rs | 6 +++ src/version.rs | 6 +++ utils/src/colorex.rs | 6 +++ utils/src/formatx.rs | 11 +++-- utils/src/json.rs | 6 +++ utils/src/lib.rs | 5 +++ 99 files changed, 728 insertions(+), 40 deletions(-) diff --git a/front/error/src/error.rs b/front/error/src/error.rs index 6de4c9a6..bbce070f 100644 --- a/front/error/src/error.rs +++ b/front/error/src/error.rs @@ -1,3 +1,9 @@ +//! Structured Wave diagnostics and human/JSON rendering. +//! +//! [`WaveError`] is the canonical diagnostic record. Renderers consume the same +//! code, location, context, label, note, and help fields so machine-readable +//! output cannot diverge from terminal diagnostics. + #[derive(Debug, Clone, PartialEq)] pub enum WaveErrorKind { // Lexer errors diff --git a/front/error/src/lib.rs b/front/error/src/lib.rs index 5df18265..bce5065a 100644 --- a/front/error/src/lib.rs +++ b/front/error/src/lib.rs @@ -1,3 +1,8 @@ +//! Structured diagnostics shared by the Wave frontend and compiler driver. +//! +//! Diagnostics retain source locations, labels, notes, and machine-readable +//! error codes so human and JSON renderers report the same underlying failure. + pub mod error; pub use error::*; diff --git a/front/lexer/src/core.rs b/front/lexer/src/core.rs index 03db3d19..e601234d 100644 --- a/front/lexer/src/core.rs +++ b/front/lexer/src/core.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Core token and lexer state. +//! +//! Cursor positions are UTF-8 byte offsets, while diagnostic columns count +//! Unicode scalar values from `line_start`. Cursor helpers must preserve that +//! distinction. + use crate::token::TokenType; use error::{WaveError, WaveErrorKind}; diff --git a/front/lexer/src/cursor.rs b/front/lexer/src/cursor.rs index e0b63037..521caffe 100644 --- a/front/lexer/src/cursor.rs +++ b/front/lexer/src/cursor.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! UTF-8-safe cursor movement and lookahead for the lexer. +//! +//! `current` is a byte offset. All movement advances by the selected character's +//! encoded width; lookahead never treats it as a character index. + use crate::Lexer; impl<'a> Lexer<'a> { diff --git a/front/lexer/src/ident.rs b/front/lexer/src/ident.rs index 11d8caf4..798ec699 100644 --- a/front/lexer/src/ident.rs +++ b/front/lexer/src/ident.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Identifier scanning and keyword classification. +//! +//! The lexer first consumes the complete identifier spelling, then maps exact +//! language keywords to dedicated tokens. Context-sensitive names such as +//! `ptr` and `array` remain identifiers for the parser's type grammar. + use crate::token::*; use crate::{Lexer, Token}; diff --git a/front/lexer/src/lib.rs b/front/lexer/src/lib.rs index cd62d86e..bdf96868 100644 --- a/front/lexer/src/lib.rs +++ b/front/lexer/src/lib.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Wave source lexer. +//! +//! The lexer converts UTF-8 source text into positioned tokens. Token spelling +//! is preserved for diagnostics, while literal and identifier modules perform +//! the validation needed before parsing begins. + // Lexer errors intentionally retain complete diagnostic context for rendering. #![allow(clippy::result_large_err)] diff --git a/front/lexer/src/literals.rs b/front/lexer/src/literals.rs index 766bb2b2..d190dec9 100644 --- a/front/lexer/src/literals.rs +++ b/front/lexer/src/literals.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! String, character, and numeric literal scanners. +//! +//! Literal escape validation belongs here rather than in the parser so invalid +//! source spellings retain precise lexer locations and diagnostic suggestions. + use super::Lexer; use error::{WaveError, WaveErrorKind}; diff --git a/front/lexer/src/scan.rs b/front/lexer/src/scan.rs index c6a2c7fa..dcdb9164 100644 --- a/front/lexer/src/scan.rs +++ b/front/lexer/src/scan.rs @@ -10,12 +10,19 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Top-level token dispatch for the Wave lexer. +//! +//! Trivia is consumed before every token. Multi-character operators must be +//! recognized before their one-character prefixes so the parser receives one +//! unambiguous token for each source operator. + use crate::token::*; use crate::{Lexer, Token}; use error::{WaveError, WaveErrorKind}; impl<'a> Lexer<'a> { #[allow(clippy::never_loop)] + /// Scans the next non-trivia token while preserving its source line. pub fn next_token(&mut self) -> Result { loop { self.skip_trivia()?; diff --git a/front/lexer/src/token.rs b/front/lexer/src/token.rs index bb9bd592..8566a0d9 100644 --- a/front/lexer/src/token.rs +++ b/front/lexer/src/token.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Token vocabulary produced by the lexer and consumed by the parser. +//! +//! Built-in type spellings have dedicated variants, while user-defined types +//! remain `TypeCustom`. Preserve that distinction when adding keywords because +//! type parsing and context-sensitive identifier handling depend on it. + use std::fmt; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] diff --git a/front/lexer/src/trivia.rs b/front/lexer/src/trivia.rs index a33361fe..afa67c6a 100644 --- a/front/lexer/src/trivia.rs +++ b/front/lexer/src/trivia.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Whitespace and comment consumption with line tracking. +//! +//! Block comments may nest. Every consumed newline updates both the logical line +//! and byte offset used for later token columns, including newlines inside +//! comments. + use super::Lexer; use error::WaveError; use error::WaveErrorKind; diff --git a/front/parser/src/arch/aarch64.rs b/front/parser/src/arch/aarch64.rs index ee51fae3..8d2e8b66 100644 --- a/front/parser/src/arch/aarch64.rs +++ b/front/parser/src/arch/aarch64.rs @@ -10,6 +10,8 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Canonical AArch64 name and accepted target-attribute aliases. + pub(super) const NAME: &str = "aarch64"; pub(super) fn recognizes(value: &str) -> bool { diff --git a/front/parser/src/arch/mod.rs b/front/parser/src/arch/mod.rs index efd4b641..35bd3788 100644 --- a/front/parser/src/arch/mod.rs +++ b/front/parser/src/arch/mod.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Canonical architecture names used by target-attribute preprocessing. +//! +//! Common host/toolchain aliases normalize to stable Wave spellings. Unknown +//! values are preserved in lowercase so future targets can still participate in +//! string-based conditions before receiving a dedicated enum variant. + mod aarch64; mod riscv64; mod x86_64; diff --git a/front/parser/src/arch/riscv64.rs b/front/parser/src/arch/riscv64.rs index 7e5ca26c..0bb58e71 100644 --- a/front/parser/src/arch/riscv64.rs +++ b/front/parser/src/arch/riscv64.rs @@ -10,6 +10,8 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Canonical RISC-V 64-bit name used by target attributes. + pub(super) const NAME: &str = "riscv64"; pub(super) fn recognizes(value: &str) -> bool { diff --git a/front/parser/src/arch/x86_64.rs b/front/parser/src/arch/x86_64.rs index c0c9d75d..09b9baaf 100644 --- a/front/parser/src/arch/x86_64.rs +++ b/front/parser/src/arch/x86_64.rs @@ -10,6 +10,8 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Canonical x86-64 name and accepted target-attribute aliases. + pub(super) const NAME: &str = "x86_64"; pub(super) fn recognizes(value: &str) -> bool { diff --git a/front/parser/src/ast.rs b/front/parser/src/ast.rs index 3e49a3a0..837b8ec6 100644 --- a/front/parser/src/ast.rs +++ b/front/parser/src/ast.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Source-level syntax tree shared by parsing, semantic analysis, and codegen. +//! +//! Nodes describe Wave concepts, not LLVM storage or ABI decisions. Generic +//! monomorphization rewrites this representation before backend entry, so new +//! node forms must be handled by both semantic passes and that rewrite where +//! they may contain types or expressions. + use std::collections::HashMap; #[derive(Debug, Clone)] diff --git a/front/parser/src/expr/assign.rs b/front/parser/src/expr/assign.rs index c7013864..8af46f47 100644 --- a/front/parser/src/expr/assign.rs +++ b/front/parser/src/expr/assign.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Assignment expressions at the lowest precedence level. +//! +//! The right-hand side recurses at the same level, making chained assignment +//! right-associative. Assignability and mutability are validated after parsing. + use crate::ast::{AssignOperator, Expression}; use crate::expr::binary::parse_logical_or_expression; use lexer::token::TokenType; diff --git a/front/parser/src/expr/binary.rs b/front/parser/src/expr/binary.rs index 31803113..3d25b460 100644 --- a/front/parser/src/expr/binary.rs +++ b/front/parser/src/expr/binary.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Precedence-climbing entry points for binary and cast expressions. +//! +//! Precedence is encoded by the call chain rather than a numeric table: each +//! function parses its tighter-binding child, then folds operators at its own +//! level from left to right. Insert a new operator at the intended layer instead +//! of handling it in the primary-expression parser. + use crate::ast::{Expression, Operator}; use crate::expr::unary::parse_unary_expression; use crate::types::parse_type_from_stream; diff --git a/front/parser/src/expr/helpers.rs b/front/parser/src/expr/helpers.rs index 1669e5d2..9b4f6347 100644 --- a/front/parser/src/expr/helpers.rs +++ b/front/parser/src/expr/helpers.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Shared expression predicates and lvalue reconstruction helpers. +//! +//! Assignability is a syntax property here: variables, dereferences, fields, and +//! indices may form storage targets. Mutability and type legality are checked by +//! semantic validation. + use crate::ast::Expression; use crate::expr::parse_expression; use crate::expr::unary::parse_unary_expression; diff --git a/front/parser/src/expr/mod.rs b/front/parser/src/expr/mod.rs index d30667ee..92c1f24e 100644 --- a/front/parser/src/expr/mod.rs +++ b/front/parser/src/expr/mod.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Wave expression grammar from assignment down to primary expressions. +//! +//! The module split mirrors precedence and postfix/prefix roles. Callers enter +//! through [`parse_expression`] rather than selecting an internal precedence +//! layer directly. + mod assign; mod binary; mod helpers; diff --git a/front/parser/src/expr/postfix.rs b/front/parser/src/expr/postfix.rs index b1d7193a..5d0fcf77 100644 --- a/front/parser/src/expr/postfix.rs +++ b/front/parser/src/expr/postfix.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Postfix chaining for fields, methods, indices, calls, and increment/decrement. +//! +//! The loop repeatedly wraps the expression parsed so far, allowing chains such +//! as field access followed by indexing. Postfix mutation is accepted only for +//! expressions classified as assignable by the shared expression helper. + use std::iter::Peekable; use lexer::token::TokenType; diff --git a/front/parser/src/expr/primary.rs b/front/parser/src/expr/primary.rs index c2465380..ea572aad 100644 --- a/front/parser/src/expr/primary.rs +++ b/front/parser/src/expr/primary.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Primary expressions at the base of the precedence parser. +//! +//! This layer distinguishes literals, names, calls, struct literals, grouping, +//! and other atomic forms before postfix and binary operators are applied. + use std::iter::Peekable; use lexer::token::TokenType; diff --git a/front/parser/src/expr/unary.rs b/front/parser/src/expr/unary.rs index 481a49fe..860becb3 100644 --- a/front/parser/src/expr/unary.rs +++ b/front/parser/src/expr/unary.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Prefix unary parsing before primary and postfix expressions. +//! +//! Unary operators associate right-to-left through recursion. Address-of and +//! prefix increment/decrement additionally require an assignable operand. + use crate::ast::{Expression, IncDecKind, Literal, Operator}; use crate::expr::is_assignable; use crate::expr::primary::parse_primary_expression; diff --git a/front/parser/src/format.rs b/front/parser/src/format.rs index ec94ed1d..0fb607ee 100644 --- a/front/parser/src/format.rs +++ b/front/parser/src/format.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Splitting simple `{}` format strings into literal and placeholder AST parts. +//! +//! Only an empty brace pair is a placeholder here; other opening braces remain +//! literal text. + use crate::ast::FormatPart; pub fn parse_format_string(s: &str) -> Vec { diff --git a/front/parser/src/generics.rs b/front/parser/src/generics.rs index 65f069de..4bc77ee8 100644 --- a/front/parser/src/generics.rs +++ b/front/parser/src/generics.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Ahead-of-time generic monomorphization for the Wave AST. +//! +//! Generic templates are removed from the emitted AST and replaced by concrete +//! instances discovered while rewriting non-generic roots. Instance names are +//! deterministic so repeated references resolve to one generated definition. + use crate::ast::{ ASTNode, EnumNode, Expression, ExternFunctionNode, FunctionNode, Literal, MatchArm, MatchPattern, ParameterNode, ProtoImplNode, StatementNode, StructNode, TypeAliasNode, Value, @@ -20,6 +26,8 @@ use std::collections::{BTreeMap, HashMap, HashSet}; #[derive(Default)] struct GenericEnv { + // Templates are source definitions; instances are fully substituted nodes + // that may be emitted. BTreeMap keeps generated output deterministic. function_templates: HashMap, function_parameters: HashMap>, struct_templates: HashMap, @@ -31,9 +39,17 @@ struct GenericEnv { struct_in_progress: HashSet, } +/// Rewrites a parsed program into an AST containing only concrete generic instances. +/// +/// Callers must run this after import expansion and before concrete-AST +/// validation or code generation. A template-aware semantic pass may run first, +/// but later phases do not accept unresolved generic parameters in emitted +/// function and struct definitions. pub fn monomorphize_generics(ast: Vec) -> Result, String> { let mut env = GenericEnv::default(); + // Pass one records every callable signature and generic template before any + // body is rewritten, allowing forward references between declarations. for node in &ast { match node { ASTNode::Function(f) => { @@ -74,6 +90,8 @@ pub fn monomorphize_generics(ast: Vec) -> Result, String> let mut out: Vec = Vec::new(); let empty_subst: HashMap = HashMap::new(); + // Pass two rewrites concrete roots. Referenced generic instances are added + // to the environment recursively and appended after source declarations. for node in ast { match node { ASTNode::Function(f) => { @@ -720,6 +738,9 @@ fn ensure_struct_instance( if env.struct_instances.contains_key(&inst_name) { return Ok(inst_name); } + // Recursive types may refer to their own mangled name while the body is + // still being rewritten. Returning the reserved name breaks the recursion + // without emitting a duplicate definition. if env.struct_in_progress.contains(&inst_name) { return Ok(inst_name); } @@ -769,6 +790,7 @@ fn ensure_function_instance( if env.function_instances.contains_key(&inst_name) { return Ok(inst_name); } + // Recursive generic calls reuse the symbol reserved by the outer rewrite. if env.function_in_progress.contains(&inst_name) { return Ok(inst_name); } @@ -827,6 +849,9 @@ fn parse_wave_type_from_str(raw: &str) -> Result { } fn mangle_instance_name(base: &str, args: &[WaveType]) -> String { + // This is an internal compiler symbol scheme, not a public Wave ABI. Each + // type component is encoded explicitly to avoid collisions between nested + // pointer, array, scalar, and struct arguments. let mut out = String::with_capacity(base.len() + 16); out.push_str(base); out.push_str("$g"); diff --git a/front/parser/src/import.rs b/front/parser/src/import.rs index 50eb5dc9..dd153bd2 100644 --- a/front/parser/src/import.rs +++ b/front/parser/src/import.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Target-aware source preprocessing and recursive import expansion. +//! +//! Target attributes are resolved before lexing while preserving line structure +//! for diagnostics. Import expansion tracks canonical paths to detect cycles, +//! retains each source unit for later error mapping, and resolves local, +//! dependency, and standard-library roots through explicit configuration. + use crate::arch; use crate::ast::ASTNode; use crate::{parse_syntax_only, ParseError}; diff --git a/front/parser/src/lib.rs b/front/parser/src/lib.rs index 1173c7d4..3964ade0 100644 --- a/front/parser/src/lib.rs +++ b/front/parser/src/lib.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Wave syntax, AST, import expansion, generic specialization, and semantic validation. +//! +//! Parsing intentionally produces a source-oriented AST first. Imports and +//! generics are expanded before the semantic verifier establishes the typed +//! program contract consumed by code generation. + // These legacy parser APIs are being migrated incrementally; keep new lints fatal // without forcing risky mechanical rewrites into a release hardening change. #![allow( diff --git a/front/parser/src/parser/asm.rs b/front/parser/src/parser/asm.rs index 855b53a5..7c92807e 100644 --- a/front/parser/src/parser/asm.rs +++ b/front/parser/src/parser/asm.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Inline-assembly syntax for instruction, input, output, and clobber clauses. +//! +//! This parser validates clause shape and assignable output expressions. Target +//! register names and stack contracts are intentionally deferred to the +//! architecture-aware backend planner. + use crate::ast::{ASTNode, Expression, Literal, StatementNode}; use crate::expr::is_assignable; use lexer::token::TokenType; diff --git a/front/parser/src/parser/control.rs b/front/parser/src/parser/control.rs index ea4170b9..b763d018 100644 --- a/front/parser/src/parser/control.rs +++ b/front/parser/src/parser/control.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Parsing for conditional, loop, and match statements. +//! +//! Control-flow parsers delegate bodies to the shared block parser and return +//! syntax-only nodes. Match-arm `=>` is currently represented by two lexer +//! tokens, so this module owns consuming that pair as one delimiter. + use crate::ast::{ ASTNode, Expression, MatchArm, MatchPattern, Mutability, StatementNode, VariableNode, }; diff --git a/front/parser/src/parser/decl.rs b/front/parser/src/parser/decl.rs index f88caf24..f489fbb7 100644 --- a/front/parser/src/parser/decl.rs +++ b/front/parser/src/parser/decl.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Variable, external function, type-alias, and enum declarations. +//! +//! Declaration parsing records source types and ABI annotations without making +//! backend layout decisions. Nested generic text is consumed with delimiter +//! depth so inner commas and closing chevrons cannot terminate the outer type. + use crate::ast::{ ASTNode, EnumNode, EnumVariantNode, Expression, ExternFunctionNode, Mutability, TypeAliasNode, VariableNode, WaveType, diff --git a/front/parser/src/parser/expr.rs b/front/parser/src/parser/expr.rs index e36d0ce6..6819c1ce 100644 --- a/front/parser/src/parser/expr.rs +++ b/front/parser/src/parser/expr.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Compatibility helpers for token-slice function calls and parenthesized spans. +//! +//! The main precedence parser handles current expression syntax. Keep these +//! helpers isolated so older parser consumers do not influence operator or +//! generic-call parsing. + use crate::ast::Expression; use crate::expr::parse_expression; use lexer::token::TokenType; diff --git a/front/parser/src/parser/functions.rs b/front/parser/src/parser/functions.rs index e46160f0..a1631f95 100644 --- a/front/parser/src/parser/functions.rs +++ b/front/parser/src/parser/functions.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Function declarations, generic parameters, parameters, and function bodies. +//! +//! Function parsing establishes syntax and declared types only. Duplicate names +//! within generic parameter lists are rejected here; program-wide symbol and +//! body type checks remain the semantic verifier's responsibility. + use crate::ast::{ASTNode, ExportAttribute, FunctionNode, ParameterNode, StatementNode, Value}; use crate::expr::parse_expression; use crate::parser::asm::*; diff --git a/front/parser/src/parser/io.rs b/front/parser/src/parser/io.rs index 6149e313..5a45cf97 100644 --- a/front/parser/src/parser/io.rs +++ b/front/parser/src/parser/io.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Parsing of `print`, `println`, and `input` statements. +//! +//! Placeholder counts are checked while parsing so the AST distinguishes plain +//! literal output from formatted calls. Argument types and C format conversion +//! remain semantic/backend responsibilities. + use crate::ast::{ASTNode, StatementNode}; use crate::expr::parse_expression; use lexer::token::TokenType; @@ -18,7 +24,6 @@ use std::iter::Peekable; use std::slice::Iter; use utils::formatx::*; -// PRINTLN parsing pub fn parse_println(tokens: &mut Peekable>) -> Option { if tokens.peek()?.token_type != TokenType::Lparen { println!("Error: Expected '(' after 'println'"); diff --git a/front/parser/src/parser/items.rs b/front/parser/src/parser/items.rs index cc0124f2..5d711bc8 100644 --- a/front/parser/src/parser/items.rs +++ b/front/parser/src/parser/items.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Parsers for top-level imports, proto implementations, and structures. +//! +//! These item parsers consume their complete declaration, including the closing +//! delimiter or semicolon. Method bodies reuse the function parser so parameter, +//! generic, and return-type grammar stays consistent across item kinds. + use crate::ast::{ASTNode, ProtoImplNode, StatementNode, StructNode, WaveType}; use crate::parser::functions::{parse_function, parse_generic_param_names}; use crate::types::parse_type_from_stream; diff --git a/front/parser/src/parser/mod.rs b/front/parser/src/parser/mod.rs index 52d9f904..23831ea2 100644 --- a/front/parser/src/parser/mod.rs +++ b/front/parser/src/parser/mod.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Syntax parser modules and public parsing entry points. +//! +//! Submodules consume complete grammar units. `parse_syntax_only` exposes the +//! source-oriented AST used before import expansion and semantic validation. + pub mod asm; pub mod control; pub mod decl; diff --git a/front/parser/src/parser/parse.rs b/front/parser/src/parser/parse.rs index 6a2c9bf9..e56e823e 100644 --- a/front/parser/src/parser/parse.rs +++ b/front/parser/src/parser/parse.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Parser entry points and top-level declaration dispatch. +//! +//! These routines construct a source-oriented AST only. Import expansion, +//! generic specialization, and semantic type validation are later phases and +//! must not be silently performed while consuming syntax. + use crate::ast::ASTNode; use crate::parser::decl::*; use crate::parser::functions::{parse_export, parse_function}; diff --git a/front/parser/src/parser/stmt.rs b/front/parser/src/parser/stmt.rs index 8444a40e..333a0332 100644 --- a/front/parser/src/parser/stmt.rs +++ b/front/parser/src/parser/stmt.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Statement parsing and statement-level recovery boundaries. +//! +//! A statement parser consumes its complete terminator or block. Keeping that +//! ownership local prevents a failed statement from shifting the token stream +//! seen by the following declaration. + use crate::ast::{ASTNode, AssignOperator, Expression, StatementNode}; use crate::expr::{is_assignable, parse_expression, parse_expression_from_token}; use crate::parser::control::{parse_for, parse_if, parse_match, parse_while}; diff --git a/front/parser/src/parser/types.rs b/front/parser/src/parser/types.rs index 8b0b37e8..b402ee65 100644 --- a/front/parser/src/parser/types.rs +++ b/front/parser/src/parser/types.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Wave type grammar used by declarations and explicit type arguments. +//! +//! Nested pointer, array, and generic forms are parsed structurally so commas +//! and closing chevrons are interpreted at the correct nesting depth. + use crate::ast::WaveType; use crate::decl::collect_generic_inner; use lexer::token::*; diff --git a/front/parser/src/stdlib.rs b/front/parser/src/stdlib.rs index 83c7078b..473c8eef 100644 --- a/front/parser/src/stdlib.rs +++ b/front/parser/src/stdlib.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Registry of standard-library module signatures known to the frontend. +//! +//! Strict mode requires imports to name a registered module. Non-strict mode is +//! retained for environments that resolve standard-library source externally. + use crate::ast::{FunctionSignature, WaveType}; use std::collections::{HashMap, HashSet}; diff --git a/front/parser/src/verification.rs b/front/parser/src/verification.rs index 30415a6a..28e6fdfd 100644 --- a/front/parser/src/verification.rs +++ b/front/parser/src/verification.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Whole-program semantic validation and expression type analysis. +//! +//! The verifier runs after imports and generics have been expanded. It first +//! collects declarations into a program-wide type environment, then validates +//! bodies with lexical scopes and expected types. It reports source-oriented +//! hints instead of retaining parser token positions in the AST. + use crate::ast::{ ASTNode, AssignOperator, Expression, FunctionNode, IncDecKind, Literal, MatchPattern, Mutability, Operator, StatementNode, WaveType, @@ -68,6 +75,8 @@ struct FunctionType { #[derive(Clone, Debug)] enum ExpressionType { + // Literal and null states stay distinct until an expected type supplies the + // width, signedness, element type, or pointer pointee required to commit. Known(WaveType), IntLiteral(String), FloatLiteral, @@ -95,6 +104,8 @@ impl ProgramTypes { fn collect(nodes: &[ASTNode]) -> Result)> { let mut out = Self::default(); + // Reserve all type names and generic parameters first. The second pass + // can then resolve forward references without depending on source order. for (index, node) in nodes.iter().enumerate() { let type_name = match node { ASTNode::Struct(structure) => Some(structure.name.as_str()), @@ -136,6 +147,8 @@ impl ProgramTypes { let mut value_names = HashSet::new(); + // Values, fields, methods, aliases, and constants need their complete + // signatures before any function body is checked. for (index, node) in nodes.iter().enumerate() { let failure = |message: String, primary: Option| (index, message, primary); diff --git a/front/parser/tests/parse_var_and_generics.rs b/front/parser/tests/parse_var_and_generics.rs index 5dde675a..9d374641 100644 --- a/front/parser/tests/parse_var_and_generics.rs +++ b/front/parser/tests/parse_var_and_generics.rs @@ -1,3 +1,5 @@ +//! Regression coverage for variable declarations and generic type syntax. + use lexer::Lexer; use parser::parse_syntax_only; diff --git a/llvm/src/backend.rs b/llvm/src/backend.rs index 2a7df027..0f29303b 100644 --- a/llvm/src/backend.rs +++ b/llvm/src/backend.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! External LLVM tool and native-linker orchestration. +//! +//! In-process IR generation lives in `codegen`; this module translates resolved +//! backend options into `llc` and linker invocations, locates bundled tools, and +//! supplies platform startup/default-library arguments. + use crate::codegen::target::{target_spec_for_triple, CodegenTarget}; use std::env; use std::path::PathBuf; diff --git a/llvm/src/codegen/abi_c.rs b/llvm/src/codegen/abi_c.rs index c7f858bb..5044f0b6 100644 --- a/llvm/src/codegen/abi_c.rs +++ b/llvm/src/codegen/abi_c.rs @@ -10,7 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. -// src/llvm_temporary/llvm_codegen/abi_c.rs +//! Target-specific C calling-convention classification. +//! +//! Wave object representation and C ABI transport representation are separate: +//! an aggregate may be passed directly, split across registers, ignored, or +//! addressed indirectly without changing its in-memory layout. Classification +//! happens here; call and function emission only apply the resulting contract. use inkwell::attributes::{Attribute, AttributeLoc}; use inkwell::context::Context; use inkwell::targets::TargetData; @@ -27,17 +32,30 @@ use super::types::{wave_type_to_llvm_type, TypeFlavor}; #[derive(Clone)] pub enum ParamLowering<'ctx> { Ignore, - Direct(BasicTypeEnum<'ctx>), // pass as this llvm type - Split(Vec>), // pass as multiple params - Indirect { ty: AnyTypeEnum<'ctx> }, // pass a pointer without byval - ByVal { ty: AnyTypeEnum<'ctx>, align: u32 }, // pass ptr + byval + align + /// Pass the value as one LLVM parameter of this transport type. + Direct(BasicTypeEnum<'ctx>), + /// Decompose one Wave parameter into multiple LLVM parameters. + Split(Vec>), + /// Pass a pointer without attaching the C `byval` attribute. + Indirect { + ty: AnyTypeEnum<'ctx>, + }, + /// Pass a pointer carrying the C `byval` size/alignment contract. + ByVal { + ty: AnyTypeEnum<'ctx>, + align: u32, + }, } #[derive(Clone)] pub enum RetLowering<'ctx> { Void, Direct(BasicTypeEnum<'ctx>), - SRet { ty: AnyTypeEnum<'ctx>, align: u32 }, // hidden first param + /// Return through a hidden first parameter with the `sret` attribute. + SRet { + ty: AnyTypeEnum<'ctx>, + align: u32, + }, } #[derive(Clone, Copy)] @@ -48,13 +66,18 @@ pub enum IntegerExtension { #[derive(Clone)] pub struct ExternCInfo<'ctx> { - pub llvm_name: String, // actual LLVM symbol name - pub wave_ret: WaveType, // Wave-level return type (needed when sret => llvm void) + /// Actual symbol name emitted to LLVM. + pub llvm_name: String, + /// Source return type, retained when an `sret` function returns LLVM void. + pub wave_ret: WaveType, pub ret: RetLowering<'ctx>, pub ret_extension: Option, - pub params: Vec>, // per-wave param - pub param_extensions: Vec>, // per-wave param - pub llvm_param_types: Vec>, // final lowered param list (including sret ptr, split, byval ptr) + /// One classification for each source-level parameter. + pub params: Vec>, + /// Narrow-integer extension contract for each source-level parameter. + pub param_extensions: Vec>, + /// Final LLVM parameter list, including hidden, split, and indirect values. + pub llvm_param_types: Vec>, pub variadic: bool, pub variadic_integer_extension: Option, } diff --git a/llvm/src/codegen/address.rs b/llvm/src/codegen/address.rs index 73a17895..10f68fd4 100644 --- a/llvm/src/codegen/address.rs +++ b/llvm/src/codegen/address.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Address calculation for assignable expressions. +//! +//! LLVM pointers are opaque, so lvalue lowering must recover pointee and field +//! types from Wave semantic types rather than from the LLVM pointer itself. +//! This module returns both the address and its storage type to keep subsequent +//! loads and stores consistent. + use inkwell::builder::Builder; use inkwell::context::Context; use inkwell::module::Module; diff --git a/llvm/src/codegen/arch/aarch64.rs b/llvm/src/codegen/arch/aarch64.rs index 3b6553df..c7ba3bc9 100644 --- a/llvm/src/codegen/arch/aarch64.rs +++ b/llvm/src/codegen/arch/aarch64.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! AArch64 register aliases, inline-assembly clobbers, and stack effects. +//! +//! The platform register (`x18`), stack pointer, and zero register are excluded +//! from general operand allocation even though they are valid assembler names. + #[cfg(any(feature = "llvm-target-all", feature = "llvm-target-aarch64"))] pub(crate) const CPUS: &[&str] = &["generic", "cortex-a53", "cortex-a72"]; #[cfg(any(feature = "llvm-target-all", feature = "llvm-target-aarch64"))] diff --git a/llvm/src/codegen/arch/mod.rs b/llvm/src/codegen/arch/mod.rs index fc0c2a58..42288210 100644 --- a/llvm/src/codegen/arch/mod.rs +++ b/llvm/src/codegen/arch/mod.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Architecture-specific inline-assembly contracts. +//! +//! The shared codegen layer dispatches through this module for register aliases, +//! operand eligibility, clobbers, dialect selection, and conservative stack +//! analysis. Target-specific spelling must stay in the architecture modules so +//! accepting syntax for one ISA cannot silently affect another. + pub(crate) mod aarch64; pub(crate) mod riscv64; pub(crate) mod x86_64; @@ -95,6 +102,8 @@ pub(crate) struct StackAnalysis { } pub(crate) fn instruction_text(line: &str, hash_is_comment: bool) -> String { + // `#` starts a comment on x86/RISC-V but introduces immediates on AArch64. + // Callers choose the rule before labels and mnemonics are normalized. let without_slash_comment = line.split_once("//").map(|(code, _)| code).unwrap_or(line); let line = if hash_is_comment { without_slash_comment @@ -127,6 +136,8 @@ pub(crate) fn mnemonic(code: &str) -> &str { } pub(crate) fn stack_analysis(architecture: Architecture, line: &str) -> StackAnalysis { + // This is deliberately conservative. Unknown writes reject an inline-asm + // contract instead of pretending that stack balance can be proven. match architecture { Architecture::X86_64 => x86_64::stack_analysis(line), Architecture::Aarch64 => aarch64::stack_analysis(line), diff --git a/llvm/src/codegen/arch/riscv64.rs b/llvm/src/codegen/arch/riscv64.rs index 4b50da0a..59ceb398 100644 --- a/llvm/src/codegen/arch/riscv64.rs +++ b/llvm/src/codegen/arch/riscv64.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! RISC-V 64-bit target features, ABI names, registers, and stack effects. +//! +//! Integer and floating-point ABI aliases are normalized to physical register +//! numbers. Feature-to-ISA spelling lives here; compatibility between the +//! selected ISA and LP64/LP64F/LP64D is enforced by the target resolver. + #[cfg(any(feature = "llvm-target-all", feature = "llvm-target-riscv"))] pub(crate) const CPUS: &[&str] = &["generic", "generic-rv64", "rocket-rv64", "sifive-u74"]; #[cfg(any(feature = "llvm-target-all", feature = "llvm-target-riscv"))] @@ -36,6 +42,8 @@ pub(crate) fn isa_name( zicsr: bool, zifencei: bool, ) -> String { + // Prefer the standard `g` shorthand only when the complete general-purpose + // extension set is present; otherwise preserve the precise extension set. if m && a && f && d && c && zicsr && zifencei { return "rv64gc".to_string(); } diff --git a/llvm/src/codegen/arch/x86_64.rs b/llvm/src/codegen/arch/x86_64.rs index f01e8b20..57ae44a1 100644 --- a/llvm/src/codegen/arch/x86_64.rs +++ b/llvm/src/codegen/arch/x86_64.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! x86-64 register aliases, inline-assembly clobbers, and stack effects. +//! +//! Register groups collapse partial-register spellings to their physical +//! register so constraint and clobber validation cannot allocate overlapping +//! operands independently. + #[cfg(any(feature = "llvm-target-all", feature = "llvm-target-x86"))] pub(crate) const CPUS: &[&str] = &["generic", "x86-64", "x86-64-v2", "x86-64-v3"]; #[cfg(any(feature = "llvm-target-all", feature = "llvm-target-x86"))] diff --git a/llvm/src/codegen/consts.rs b/llvm/src/codegen/consts.rs index 3602704f..87e3d949 100644 --- a/llvm/src/codegen/consts.rs +++ b/llvm/src/codegen/consts.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Compile-time evaluation of Wave constants into LLVM constant values. +//! +//! Evaluation is intentionally separate from runtime expression lowering: +//! globals require LLVM constants and cannot emit instructions. Unknown names +//! are reported distinctly so module construction can resolve forward constant +//! references in dependency rounds. + use inkwell::context::Context; use inkwell::types::{BasicTypeEnum, StringRadix, StructType}; use inkwell::values::{BasicValue, BasicValueEnum}; diff --git a/llvm/src/codegen/format.rs b/llvm/src/codegen/format.rs index 72b5b290..07b32b49 100644 --- a/llvm/src/codegen/format.rs +++ b/llvm/src/codegen/format.rs @@ -10,16 +10,19 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Translation of Wave formatting placeholders to C `printf`/`scanf` formats. +//! +//! Format selection combines LLVM value types with Wave-level pointer meaning; +//! opaque LLVM pointers alone cannot distinguish C strings from other pointers. + use inkwell::context::Context; use inkwell::types::BasicTypeEnum; use parser::ast::WaveType; -/// Wave format string -> C printf format string +/// Converts a Wave format string into a C `printf` format string. /// -/// NOTE: -/// - Inkwell (opaque pointers) cannot extract the element type from PointerType. -/// - Therefore, determining "whether this pointer is a C string" cannot be done solely with LLVM types. -/// - The caller (io.rs) must also pass arg_is_cstr. +/// `arg_types` and `arg_is_cstr` are parallel arrays. The latter carries the +/// semantic pointer information unavailable from LLVM opaque pointer types. pub fn wave_format_to_c<'ctx>( context: &'ctx Context, format: &str, diff --git a/llvm/src/codegen/ir.rs b/llvm/src/codegen/ir.rs index 5d61080f..2af6d24c 100644 --- a/llvm/src/codegen/ir.rs +++ b/llvm/src/codegen/ir.rs @@ -10,6 +10,14 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Construction and emission of a complete LLVM module. +//! +//! This is the backend assembly point: it resolves named types, installs the +//! semantic expression-type table, lowers C ABI boundaries, emits functions, +//! and applies the selected optimization pipeline. Target +//! initialization is process-wide, while each compilation receives its own LLVM +//! context and module. + use inkwell::attributes::{Attribute, AttributeLoc}; use inkwell::context::Context; use inkwell::module::{FlagBehavior, Linkage, Module}; @@ -145,6 +153,10 @@ fn rebuild_split_abi_value<'ctx>( .unwrap(); builder.build_store(part_ptr, *part).unwrap(); let offset_value = context.i64_type().const_int(offset, false); + // SAFETY: `target_ptr` is an opaque pointer to a live stack allocation; + // using `i8` makes this a byte offset. When the offset reaches or passes + // the allocation size, `copy_size` is zero and the pointer is not used + // for a memory access. let destination = unsafe { builder .build_gep( @@ -455,6 +467,13 @@ fn apply_function_codegen_attrs<'ctx>( } } +/// Builds an LLVM module and returns its textual representation. +/// +/// # Safety +/// +/// This function retains an unsafe signature for compatibility with the +/// compiler driver's LLVM boundary. It imposes no additional caller-side +/// memory-safety requirements. pub unsafe fn generate_ir( ast_nodes: &[ASTNode], opt_flag: &str, @@ -464,6 +483,13 @@ pub unsafe fn generate_ir( generated.module.print_to_string().to_string() } +/// Builds a module and emits one target-machine output file. +/// +/// # Safety +/// +/// This function retains an unsafe signature for compatibility with the +/// compiler driver's LLVM boundary. It imposes no additional caller-side +/// memory-safety requirements. pub unsafe fn emit_codegen_file( ast_nodes: &[ASTNode], opt_flag: &str, @@ -510,6 +536,11 @@ fn build_module( codegen_trace("initialize targets"); initialize_llvm_targets(); + // Inkwell ties every module and builder to its context through lifetimes. + // GeneratedModule crosses this function boundary, so these allocations live + // for the compiler process. The CLI is short-lived and never calls LLVM + // shutdown; a long-lived embedding API should replace this with an owned + // compilation-session object rather than copying this pattern. codegen_trace("create context"); let context: &'static Context = Box::leak(Box::new(Context::create())); codegen_trace("create module"); diff --git a/llvm/src/codegen/legacy.rs b/llvm/src/codegen/legacy.rs index 8e021c5b..780ad0dc 100644 --- a/llvm/src/codegen/legacy.rs +++ b/llvm/src/codegen/legacy.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Compatibility helpers for the former token-based code-generation API. +//! +//! Current lowering uses semantic [`WaveType`](parser::ast::WaveType) values. +//! Do not extend this module with new language types; migrate remaining callers +//! to `codegen::types` instead. + use inkwell::context::Context; use inkwell::types::{BasicType, BasicTypeEnum}; use inkwell::values::{FunctionValue, PointerValue}; @@ -54,6 +60,12 @@ pub fn get_llvm_type<'a>(context: &'a Context, ty: &TokenType) -> BasicTypeEnum< } #[allow(dead_code)] +/// Creates a legacy `i32` stack slot at the builder's current insertion point. +/// +/// # Safety +/// +/// This function retains an unsafe signature for API compatibility and imposes +/// no additional caller-side memory-safety requirements. pub unsafe fn create_alloc<'a>( context: &'a Context, builder: &'a inkwell::builder::Builder<'a>, diff --git a/llvm/src/codegen/mod.rs b/llvm/src/codegen/mod.rs index d16f794a..77ef92da 100644 --- a/llvm/src/codegen/mod.rs +++ b/llvm/src/codegen/mod.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Public assembly point for LLVM code-generation services. +//! +//! New lowering belongs in a focused submodule. Re-export only the small set of +//! entry points required by the compiler driver and expression/statement layers. + pub mod abi_c; pub mod address; pub mod arch; diff --git a/llvm/src/codegen/plan.rs b/llvm/src/codegen/plan.rs index 0d2e16db..7bfcd9b6 100644 --- a/llvm/src/codegen/plan.rs +++ b/llvm/src/codegen/plan.rs @@ -10,7 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. -// codegen/asm/plan.rs +//! Architecture-aware validation and normalization of inline assembly. +//! +//! An [`AsmPlan`] is the checked boundary between source syntax and LLVM inline +//! assembly. It normalizes register aliases, orders constraints, detects +//! conflicting operands and clobbers, and verifies stack/noreturn declarations +//! against conservative instruction analysis. use crate::codegen::arch; use crate::codegen::target::CodegenTarget; use parser::ast::Expression; diff --git a/llvm/src/codegen/semantic.rs b/llvm/src/codegen/semantic.rs index 3a1f9663..30f345c5 100644 --- a/llvm/src/codegen/semantic.rs +++ b/llvm/src/codegen/semantic.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Thread-local bridge from frontend expression types to backend lowering. +//! +//! Keys are addresses of expressions in the exact AST allocation analyzed before +//! codegen. The table must be installed after the last AST clone or rewrite and +//! consumed on the same thread; a future typed AST should replace this bridge. + use parser::ast::{Expression, WaveType}; use std::cell::RefCell; use std::collections::HashMap; @@ -19,6 +25,8 @@ thread_local! { } pub(super) fn install_expression_types(types: HashMap) { + // Replace rather than extend so one compilation cannot observe entries from + // an earlier module built on the same worker thread. EXPRESSION_TYPES.with(|current| *current.borrow_mut() = types); } diff --git a/llvm/src/codegen/target.rs b/llvm/src/codegen/target.rs index 8b38efaa..801c6b29 100644 --- a/llvm/src/codegen/target.rs +++ b/llvm/src/codegen/target.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Supported-target registry and target-option contract validation. +//! +//! A [`TargetSpec`] is the single source of truth shared by CLI validation, +//! LLVM target-machine creation, inline assembly, and C ABI classification. +//! Keep exact triples here rather than accepting an architecture prefix: OS, +//! environment, and object format are ABI-relevant parts of a target. + use inkwell::module::Module; use inkwell::targets::TargetTriple; use std::collections::{BTreeMap, BTreeSet}; @@ -55,6 +62,11 @@ pub struct EffectiveTargetOptions { pub isa: Option, } +/// Resolves user overrides into the complete option set passed to LLVM. +/// +/// RISC-V ABI, floating-point extensions, and ISA spelling are coupled. This +/// function validates that contract once so later codegen does not need to +/// reinterpret partially specified options. pub fn resolve_target_options( spec: &TargetSpec, cpu: Option<&str>, @@ -93,6 +105,8 @@ pub fn resolve_target_options( .collect::>(); if spec.architecture == Architecture::Riscv64 { + // The ABI establishes the initial F/D state. Explicit feature settings + // are applied afterward and must still describe the same ABI. match abi.or(spec.default_abi) { Some("lp64") => { enabled.insert("f", false); @@ -151,6 +165,9 @@ pub fn resolve_target_options( let mut effective_abi = abi.or(spec.default_abi).map(str::to_string); let mut isa = None; if spec.architecture == Architecture::Riscv64 { + // LLVM requires the CSR extension for floating-point instructions. Add + // it implicitly unless the user explicitly disabled it, in which case + // the consistency check below produces a useful error. if enabled.get("f").copied().unwrap_or(false) && !explicitly_set.contains("zicsr") { enabled.insert("zicsr", true); } @@ -203,6 +220,9 @@ pub fn resolve_target_options( )); } + // RISC-V passes every supported feature with an explicit sign. Omitting a + // disabled F/D feature can let LLVM's CPU defaults silently contradict the + // effective ABI. let render_all_features = spec.architecture == Architecture::Riscv64; let features = spec .features @@ -411,6 +431,7 @@ const FREESTANDING_RISCV64: TargetSpec = TargetSpec { default_abi: Some(arch::riscv64::FREESTANDING_DEFAULT_ABI), }; +/// Returns the targets compiled into this backend, in deterministic order. pub fn supported_target_specs() -> Vec<&'static TargetSpec> { let mut specs: Vec<&'static TargetSpec> = Vec::new(); @@ -433,6 +454,7 @@ pub fn supported_target_specs() -> Vec<&'static TargetSpec> { specs } +/// Performs an exact lookup in the compiled target registry. pub fn target_spec_for_triple(triple: &str) -> Option<&'static TargetSpec> { supported_target_specs() .into_iter() diff --git a/llvm/src/codegen/types.rs b/llvm/src/codegen/types.rs index ca8db5dd..77bc9dcf 100644 --- a/llvm/src/codegen/types.rs +++ b/llvm/src/codegen/types.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Mapping between Wave semantic types and LLVM value/storage types. +//! +//! [`TypeFlavor`] keeps ordinary value lowering separate from C ABI-facing type +//! construction. Calling-convention transport decisions are not made here; the +//! C ABI classifier consumes these object representations afterward. + use inkwell::context::Context; use inkwell::types::{BasicType, BasicTypeEnum}; use inkwell::values::PointerValue; diff --git a/llvm/src/expression/lvalue.rs b/llvm/src/expression/lvalue.rs index 9fea22e8..f7d5b63a 100644 --- a/llvm/src/expression/lvalue.rs +++ b/llvm/src/expression/lvalue.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Loading values from Wave lvalue expressions. +//! +//! Variables, dereferences, indices, and fields first resolve to a typed storage +//! address. Loads then use the recovered Wave type, avoiding guesses from +//! LLVM's opaque pointer type and preserving aggregate storage representation. + use inkwell::targets::TargetData; use inkwell::{ builder::Builder, diff --git a/llvm/src/expression/mod.rs b/llvm/src/expression/mod.rs index c96e444e..625cc871 100644 --- a/llvm/src/expression/mod.rs +++ b/llvm/src/expression/mod.rs @@ -10,5 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! LLVM lowering split between storage addresses and computed values. +//! +//! Lvalue lowering answers where a value is stored; rvalue lowering answers what +//! value an expression produces. Keep that distinction explicit for aggregates +//! and opaque pointers. + pub mod lvalue; pub mod rvalue; diff --git a/llvm/src/expression/rvalue/arrays.rs b/llvm/src/expression/rvalue/arrays.rs index ea787154..b808bc66 100644 --- a/llvm/src/expression/rvalue/arrays.rs +++ b/llvm/src/expression/rvalue/arrays.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Array literal construction under an expected array type. +//! +//! LLVM opaque pointers cannot recover an array shape from a pointer expectation, +//! so literals require a concrete array type supplied by semantic context. + use super::ExprGenEnv; use inkwell::types::BasicTypeEnum; use inkwell::values::{BasicValue, BasicValueEnum}; @@ -57,6 +62,8 @@ Use a temp variable: `var tmp: array = [...]; foo(tmp);`" let idx = env.context.i32_type().const_int(i as u64, false); + // SAFETY: `i` ranges over the literal elements accepted for `arr_ty`; the + // semantic verifier guarantees the literal length matches the array type. let gep = unsafe { env.builder .build_in_bounds_gep(arr_ty, alloca, &[zero, idx], &format!("arr_gep_{}", i)) diff --git a/llvm/src/expression/rvalue/asm.rs b/llvm/src/expression/rvalue/asm.rs index 686b58d2..9dcd2ebc 100644 --- a/llvm/src/expression/rvalue/asm.rs +++ b/llvm/src/expression/rvalue/asm.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Inline-assembly expression lowering. +//! +//! [`AsmPlan`] performs target-specific validation before this module creates an +//! LLVM inline-asm value. Expressions may produce at most one value; statement +//! assembly handles the multi-output form separately. + use super::ExprGenEnv; use crate::codegen::arch; use crate::codegen::plan::*; @@ -66,6 +72,9 @@ pub(crate) fn gen<'ctx, 'a>( false, ); + // SAFETY: `create_inline_asm` returns an LLVM value whose type is exactly + // `fn_type`; wrapping that same value as a callee pointer preserves the + // context and function signature used by `build_indirect_call` below. let callee = unsafe { PointerValue::new(inline_asm.as_value_ref()) }; env.builder @@ -100,6 +109,8 @@ pub(crate) fn gen<'ctx, 'a>( false, ); + // SAFETY: The inline-asm value was created in this context with `fn_type`, + // which is also supplied to the indirect call immediately below. let callee = unsafe { PointerValue::new(inline_asm.as_value_ref()) }; let call = env diff --git a/llvm/src/expression/rvalue/assign.rs b/llvm/src/expression/rvalue/assign.rs index f3110b38..5b44f314 100644 --- a/llvm/src/expression/rvalue/assign.rs +++ b/llvm/src/expression/rvalue/assign.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Assignment and compound-assignment expression lowering. +//! +//! Lvalue type recovery happens before the right-hand side is generated so +//! literals and `null` receive the destination's semantic type. The destination +//! address is evaluated once, which is required for indexed and dereferenced +//! compound assignments with side effects. + use super::ExprGenEnv; use crate::codegen::types::TypeFlavor; use crate::codegen::{generate_address_ir, wave_type_to_llvm_type}; diff --git a/llvm/src/expression/rvalue/binary.rs b/llvm/src/expression/rvalue/binary.rs index 8623fad7..1ab8a557 100644 --- a/llvm/src/expression/rvalue/binary.rs +++ b/llvm/src/expression/rvalue/binary.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Binary-expression lowering, including numeric inference and pointer offsets. +//! +//! Unsuffixed numeric literals borrow a concrete LLVM type from the surrounding +//! expectation or the opposite operand. Pointer arithmetic is scaled by the +//! inferred pointee type and retains Wave's unchecked, C-like memory contract. + use super::{utils::to_bool, ExprGenEnv}; use crate::codegen::types::{wave_type_to_llvm_type, TypeFlavor}; use inkwell::types::{BasicType, BasicTypeEnum}; @@ -112,6 +118,9 @@ fn gep_with_i64_offset<'ctx, 'a>( tag: &str, ) -> PointerValue<'ctx> { let pointee_ty = infer_ptr_pointee_ty(env, ptr_expr); + // SAFETY: Wave pointer arithmetic is explicitly unchecked. A source program + // must keep an inbounds result within the original allocation (or one past + // it), which is the contract required by LLVM's `inbounds` GEP. unsafe { env.builder .build_in_bounds_gep(pointee_ty, ptr, &[idx_i64], tag) diff --git a/llvm/src/expression/rvalue/calls.rs b/llvm/src/expression/rvalue/calls.rs index be0b712d..cf10ea0e 100644 --- a/llvm/src/expression/rvalue/calls.rs +++ b/llvm/src/expression/rvalue/calls.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Function and method call lowering across Wave and C ABI boundaries. +//! +//! Ordinary Wave calls use source parameter types directly. `extern(c)` calls +//! instead apply the classifier's direct, split, indirect, or `sret` transport +//! plan and attach call-site attributes. Variadic arguments use semantic +//! expression types for C default promotions. + use super::ExprGenEnv; use crate::codegen::abi_c::{ apply_extern_c_callsite_attrs, apply_extern_c_variadic_callsite_attrs, ParamLowering, diff --git a/llvm/src/expression/rvalue/cast.rs b/llvm/src/expression/rvalue/cast.rs index 5036a1e0..2b02918e 100644 --- a/llvm/src/expression/rvalue/cast.rs +++ b/llvm/src/expression/rvalue/cast.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Explicit `as` cast lowering. +//! +//! Casts use the explicit coercion policy, which permits conversions that +//! implicit assignment rejects. Integer literals cast to pointers receive a +//! pointer-width source hint before conversion. + use super::ExprGenEnv; use crate::codegen::types::{wave_type_to_llvm_type, TypeFlavor}; use crate::statement::variable::{coerce_basic_value, CoercionMode}; @@ -29,8 +35,8 @@ pub(crate) fn gen<'ctx, 'a>( TypeFlavor::Value, ); - // Integer literals default to i32 with no context. - // For explicit cast to pointer, prefer i64 source width. + // Integer literals default to i32 without context. A pointer cast needs a + // width capable of carrying the supported 64-bit target addresses. let src_hint = match (expr, dst_ty) { (Expression::Literal(Literal::Int(_)), BasicTypeEnum::PointerType(_)) => { Some(env.context.i64_type().as_basic_type_enum()) diff --git a/llvm/src/expression/rvalue/dispatch.rs b/llvm/src/expression/rvalue/dispatch.rs index d254ec24..dc02d113 100644 --- a/llvm/src/expression/rvalue/dispatch.rs +++ b/llvm/src/expression/rvalue/dispatch.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Exhaustive dispatch from Wave expression nodes to specialized lowerers. +//! +//! New expression variants must be routed here and added to semantic analysis. +//! The expected LLVM type is forwarded only to forms whose value representation +//! may depend on surrounding context. + use super::*; use inkwell::types::BasicTypeEnum; use inkwell::values::BasicValueEnum; diff --git a/llvm/src/expression/rvalue/incdec.rs b/llvm/src/expression/rvalue/incdec.rs index 40602558..f16e5582 100644 --- a/llvm/src/expression/rvalue/incdec.rs +++ b/llvm/src/expression/rvalue/incdec.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Prefix and postfix increment/decrement lowering for assignable expressions. +//! +//! The target address is evaluated once, then the old and new values are kept +//! separate so postfix operations can store the update while returning the old +//! value. Pointer steps are scaled by their recovered Wave pointee type. + use super::ExprGenEnv; use crate::codegen::generate_address_ir; use crate::codegen::types::{wave_type_to_llvm_type, TypeFlavor}; @@ -227,6 +233,9 @@ pub(crate) fn gen<'ctx, 'a>( }; let pointee_ty = infer_ptr_pointee_type(env, target); + // SAFETY: Wave pointer arithmetic is unchecked and requires the + // source pointer and stepped result to satisfy LLVM's inbounds GEP + // contract for the same allocation. let gep = unsafe { env.builder .build_in_bounds_gep(pointee_ty, pv, &[idx], "pincdec") diff --git a/llvm/src/expression/rvalue/index.rs b/llvm/src/expression/rvalue/index.rs index 833595ae..73a979ae 100644 --- a/llvm/src/expression/rvalue/index.rs +++ b/llvm/src/expression/rvalue/index.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Reading an indexed array or pointer element. +//! +//! Address computation is shared with lvalue lowering. Aggregate elements remain +//! addresses so later field/index operations retain their storage identity; +//! scalar elements are loaded immediately. + use super::ExprGenEnv; use crate::codegen::generate_address_and_type_ir; use inkwell::values::{BasicValue, BasicValueEnum}; diff --git a/llvm/src/expression/rvalue/literals.rs b/llvm/src/expression/rvalue/literals.rs index 5c340991..d5c7e5b6 100644 --- a/llvm/src/expression/rvalue/literals.rs +++ b/llvm/src/expression/rvalue/literals.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! LLVM constants and globals for source literals. +//! +//! Unsuffixed numeric literals require an expected type when context determines +//! width or signedness. `null` likewise requires a pointer expectation; codegen +//! does not invent a pointee type for an untyped null literal. + use super::ExprGenEnv; use inkwell::types::{BasicTypeEnum, StringRadix}; use inkwell::values::{BasicValue, BasicValueEnum}; diff --git a/llvm/src/expression/rvalue/mod.rs b/llvm/src/expression/rvalue/mod.rs index 0e2f9366..e582dec8 100644 --- a/llvm/src/expression/rvalue/mod.rs +++ b/llvm/src/expression/rvalue/mod.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Shared environment and entry point for expression value lowering. +//! +//! [`ExprGenEnv`] carries the LLVM construction state plus Wave semantic tables. +//! An optional expected type flows downward to resolve literals, null pointers, +//! aggregates, and ABI-sensitive coercions without reconstructing types from AST +//! shape. + use crate::codegen::abi_c::ExternCInfo; use crate::codegen::VariableInfo; use inkwell::builder::Builder; diff --git a/llvm/src/expression/rvalue/pointers.rs b/llvm/src/expression/rvalue/pointers.rs index 02ae2e7f..4b7c5d63 100644 --- a/llvm/src/expression/rvalue/pointers.rs +++ b/llvm/src/expression/rvalue/pointers.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Address-of and dereference expression lowering. +//! +//! LLVM pointers are opaque, so dereference loads recover their value type from +//! the Wave expression and struct tables. Address-of returns the existing lvalue +//! address and never allocates replacement storage. + use super::ExprGenEnv; use crate::codegen::types::{wave_type_to_llvm_type, TypeFlavor}; use crate::codegen::{generate_address_and_type_ir, generate_address_ir}; diff --git a/llvm/src/expression/rvalue/structs.rs b/llvm/src/expression/rvalue/structs.rs index 93a74916..1ee8cac5 100644 --- a/llvm/src/expression/rvalue/structs.rs +++ b/llvm/src/expression/rvalue/structs.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Struct literal construction and field-value access. +//! +//! Field names are resolved through the declaration-built index map. Aggregate +//! fields remain addresses when required by later lowering; scalar fields are +//! loaded as values. + use super::ExprGenEnv; use crate::codegen::generate_address_and_type_ir; use inkwell::types::{BasicType, BasicTypeEnum}; diff --git a/llvm/src/expression/rvalue/unary.rs b/llvm/src/expression/rvalue/unary.rs index 1d2debf4..4499385d 100644 --- a/llvm/src/expression/rvalue/unary.rs +++ b/llvm/src/expression/rvalue/unary.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Numeric negation, logical negation, and bitwise complement lowering. +//! +//! Logical negation normalizes non-boolean integers by comparing them with zero; +//! bitwise complement preserves the operand width. + use super::ExprGenEnv; use inkwell::types::BasicTypeEnum; use inkwell::values::{BasicValue, BasicValueEnum}; diff --git a/llvm/src/expression/rvalue/utils.rs b/llvm/src/expression/rvalue/utils.rs index f97d590e..02987e3f 100644 --- a/llvm/src/expression/rvalue/utils.rs +++ b/llvm/src/expression/rvalue/utils.rs @@ -10,6 +10,8 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Small value-normalization helpers shared by expression lowerers. + use inkwell::builder::Builder; use inkwell::values::IntValue; use inkwell::IntPredicate; diff --git a/llvm/src/expression/rvalue/variables.rs b/llvm/src/expression/rvalue/variables.rs index 45086b11..752f6f35 100644 --- a/llvm/src/expression/rvalue/variables.rs +++ b/llvm/src/expression/rvalue/variables.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Resolution and loading of constants, locals, and static variables. +//! +//! Arrays evaluate to their storage address rather than an aggregate load, while +//! other variables load using their Wave type. Expected pointer types guide +//! opaque-pointer loads without redefining the variable's semantic type. + use super::ExprGenEnv; use inkwell::types::BasicTypeEnum; use inkwell::values::{BasicValue, BasicValueEnum}; diff --git a/llvm/src/importgen.rs b/llvm/src/importgen.rs index 794d845d..f37532e9 100644 --- a/llvm/src/importgen.rs +++ b/llvm/src/importgen.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Compatibility entry point for recursively expanding local imports before codegen. +//! +//! The compiler driver uses the richer parser import expansion that retains +//! source origins and dependency configuration. This helper remains for callers +//! that already provide a parsed entry AST and need local imports only. + use std::collections::HashSet; use std::path::Path; diff --git a/llvm/src/lib.rs b/llvm/src/lib.rs index 3fdb7565..97cb83d4 100644 --- a/llvm/src/lib.rs +++ b/llvm/src/lib.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! LLVM backend for Wave. +//! +//! This crate lowers the verified Wave AST into target-specific LLVM IR, +//! applies ABI classifications, emits requested artifacts, and locates the +//! bundled toolchain components needed by the compiler driver. + // Backend lowering APIs mirror LLVM's explicit context and ABI structures. // Refactor these lints separately from release hardening to avoid ABI regressions. #![allow( @@ -37,8 +43,11 @@ pub mod importgen; pub mod statement; pub mod toolchain; +/// Returns the linked LLVM backend version reported by the LLVM C API. pub fn backend() -> Option { let (mut major, mut minor, mut patch) = (0_u32, 0_u32, 0_u32); + // SAFETY: LLVMGetVersion writes three integers to valid, uniquely borrowed + // stack locations and does not retain their addresses after returning. unsafe { llvm_sys::core::LLVMGetVersion(&mut major, &mut minor, &mut patch); } diff --git a/llvm/src/statement/asm.rs b/llvm/src/statement/asm.rs index 02f92f16..90e40b63 100644 --- a/llvm/src/statement/asm.rs +++ b/llvm/src/statement/asm.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Lowering of inline-assembly statements with inputs and multiple outputs. +//! +//! Target validation and constraint ordering come from [`AsmPlan`]. This module +//! evaluates input expressions, constructs the LLVM call, then stores returned +//! values into variables or memory operands using their recovered Wave types. + use crate::codegen::arch; use crate::codegen::plan::*; use crate::codegen::target::require_supported_target_from_module; diff --git a/llvm/src/statement/assign.rs b/llvm/src/statement/assign.rs index f773d4e0..be05016e 100644 --- a/llvm/src/statement/assign.rs +++ b/llvm/src/statement/assign.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Lowering for the legacy name-based assignment statement node. +//! +//! General lvalue assignment is represented as an expression and handled by +//! `expression::rvalue::assign`. This path accepts only a named mutable variable +//! and rejects constants and immutable bindings. + use crate::codegen::abi_c::ExternCInfo; use crate::codegen::types::TypeFlavor; use crate::codegen::{wave_type_to_llvm_type, VariableInfo}; diff --git a/llvm/src/statement/control.rs b/llvm/src/statement/control.rs index 48149236..d3182e73 100644 --- a/llvm/src/statement/control.rs +++ b/llvm/src/statement/control.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! LLVM lowering for control-flow statements and Wave truthiness. +//! +//! Wave conditions intentionally accept integers, floats, and pointers. Every +//! such value is normalized to an LLVM `i1` here before branches are built. +//! Loop termination analysis distinguishes a break for the current loop from a +//! break nested inside another loop. + use crate::codegen::abi_c::ExternCInfo; use crate::codegen::VariableInfo; use crate::expression::rvalue::generate_expression_ir; @@ -30,6 +37,8 @@ fn truthy_to_i1<'ctx>( v: BasicValueEnum<'ctx>, name: &str, ) -> inkwell::values::IntValue<'ctx> { + // Floating-point truthiness uses ordered comparison: NaN does not compare + // as a non-zero value. Keep this choice explicit when changing semantics. match v { BasicValueEnum::IntValue(iv) => { if iv.get_type().get_bit_width() == 1 { diff --git a/llvm/src/statement/expr_stmt.rs b/llvm/src/statement/expr_stmt.rs index 0e82c7b7..15bceb81 100644 --- a/llvm/src/statement/expr_stmt.rs +++ b/llvm/src/statement/expr_stmt.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Lowering for expressions evaluated only for side effects. +//! +//! The expression still goes through normal value lowering; its result is +//! intentionally discarded by the statement context. + use crate::codegen::abi_c::ExternCInfo; use crate::codegen::VariableInfo; use crate::expression::rvalue::generate_expression_ir; diff --git a/llvm/src/statement/io.rs b/llvm/src/statement/io.rs index ae20ffff..76b1217c 100644 --- a/llvm/src/statement/io.rs +++ b/llvm/src/statement/io.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Lowering of Wave print and input statements to C vararg calls. +//! +//! Format conversion uses Wave semantic types because opaque LLVM pointers do +//! not reveal whether an argument is a C string. `printf` arguments receive C +//! default promotions, while `scanf` arguments must resolve to writable lvalues. + use crate::codegen::abi_c::ExternCInfo; use crate::codegen::types::{wave_type_to_llvm_type, TypeFlavor}; use crate::codegen::{wave_format_to_c, wave_format_to_scanf, VariableInfo}; diff --git a/llvm/src/statement/mod.rs b/llvm/src/statement/mod.rs index 1e8a76ae..e01987a7 100644 --- a/llvm/src/statement/mod.rs +++ b/llvm/src/statement/mod.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Statement dispatcher for LLVM lowering. +//! +//! Specialized modules own each statement family; this module carries shared +//! function state and prevents emission after the current basic block has been +//! terminated. Adding a statement kind requires updating this dispatch as well +//! as semantic validation. + pub mod asm; pub mod assign; pub mod control; @@ -45,6 +52,8 @@ pub fn generate_statement_ir<'ctx>( target_data: &'ctx TargetData, extern_c_info: &HashMap>, ) { + // A return, break, continue, or unconditional branch may have terminated the + // block while walking a source-level list. LLVM rejects a second terminator. if builder .get_insert_block() .is_some_and(|block| block.get_terminator().is_some()) diff --git a/llvm/src/statement/variable.rs b/llvm/src/statement/variable.rs index ac40268c..a8e4c87d 100644 --- a/llvm/src/statement/variable.rs +++ b/llvm/src/statement/variable.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Local variable storage, initialization, and value coercion. +//! +//! Allocations are placed in the function entry block even when declarations +//! appear in nested control flow. Coercion behavior is selected explicitly for +//! implicit assignment, explicit casts, and inline-assembly operands. + use crate::codegen::abi_c::ExternCInfo; use crate::codegen::types::TypeFlavor; use crate::codegen::{wave_type_to_llvm_type, VariableInfo}; diff --git a/llvm/src/toolchain.rs b/llvm/src/toolchain.rs index ade3f2cd..9fbd742a 100644 --- a/llvm/src/toolchain.rs +++ b/llvm/src/toolchain.rs @@ -10,28 +10,30 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Discovery of CRT objects bundled with Wave distributions. +//! +//! Search order supports explicit overrides, installed compiler layouts, and the +//! repository build tree. This module only locates files; target-specific link +//! planning decides which CRT objects are required. + use std::env; use std::path::{Path, PathBuf}; -/** -- This function creates candidate paths and finds - the first one where the actual file exists. - - - The function means “Linux C Runtime-related objects included - with the programming package,” or, in other words, - “Find the Linux CRT files bundled with Wave.” -*/ +/// Finds the first existing Wave-bundled Linux CRT object for a target. +/// +/// Candidate order is significant: explicit environment overrides take +/// precedence over paths relative to the running compiler and the build-time +/// fallback directory. pub fn find_bundled_linux_crt(target: &str, abi: Option<&str>, name: &str) -> Option { bundled_linux_crt_candidates(target, abi, name) .into_iter() .find(|path| path.is_file()) } -/** -- This function creates and returns a predicted path where the CRT should be located. - -- The function name means “returns the path where the bundled Linux CRT is expected to be located.” - */ +/// Returns the highest-priority path where a bundled CRT object is expected. +/// +/// Unlike [`find_bundled_linux_crt`], this function does not require the file +/// to exist. Diagnostics use the result to report the path that was searched. pub fn expected_bundled_linux_crt(target: &str, abi: Option<&str>, name: &str) -> PathBuf { bundled_linux_crt_candidates(target, abi, name) .into_iter() @@ -43,6 +45,8 @@ fn bundled_linux_crt_candidates(target: &str, abi: Option<&str>, name: &str) -> let mut paths = Vec::new(); let relative = crt_relative_path(target, abi, name); + // A file-specific override exists for compatibility with release and CI + // environments that supply only the conventional process entry object. if name == "crt1.o" { if let Ok(path) = env::var("WAVE_LINUX_CRT1_OBJECT") { if !path.trim().is_empty() { @@ -57,6 +61,8 @@ fn bundled_linux_crt_candidates(target: &str, abi: Option<&str>, name: &str) -> } } + // Installed archives place CRT files either beside wavec or below the + // installation prefix. Keep these layouts ahead of the build-tree path. if let Ok(exe) = env::current_exe() { if let Some(dir) = exe.parent() { paths.push(dir.join("crt").join(&relative)); @@ -75,6 +81,8 @@ fn crt_relative_path(target: &str, abi: Option<&str>, name: &str) -> PathBuf { if target == "riscv64-unknown-linux-gnu" { path.push(abi.unwrap_or("lp64d")); } + // Accept only the final component so a caller cannot escape the target CRT + // directory by passing a path instead of an object-file name. path.push(Path::new(name).file_name().unwrap_or_default()); path } diff --git a/src/cli.rs b/src/cli.rs index 8719c765..2f9a2221 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -10,6 +10,13 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! `wavec` command-line parsing, validation, and execution planning. +//! +//! Raw arguments are converted into a `BuildRequest` before compilation +//! starts. Target and output contracts are validated here so the runner receives +//! a coherent request and dry-run output describes the same plan that execution +//! would follow. + use crate::errors::CliError; use crate::flags::{ validate_opt_flag, DebugFlags, DepFlags, DepPackage, LinkFlags, LlvmFlags, WhaleFlags, diff --git a/src/errors.rs b/src/errors.rs index 3eb41f21..8c323fd5 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Errors produced while parsing or executing the `wavec` command line. +//! +//! CLI failures are separate from source diagnostics because they have no Wave +//! source span. Stable `kind` and exit-code mappings are shared by human and JSON +//! output. + use std::fmt; use std::path::PathBuf; diff --git a/src/flags.rs b/src/flags.rs index 8fee895a..281b4ad9 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Typed option groups passed from CLI planning to compiler phases. +//! +//! These structures contain parsed values only. Cross-option contracts such as +//! target CPU, feature, ABI, and output compatibility are validated in the CLI +//! and target resolver before use. + #[derive(Default, Clone, Copy)] pub struct DebugFlags { pub tokens: bool, diff --git a/src/lib.rs b/src/lib.rs index f4131fff..61e65e57 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Compiler-driver services shared by the `wavec` binary and integration tools. +//! +//! This crate owns command-line planning, source preparation, diagnostics, and +//! link orchestration. Language parsing lives in the frontend crates, while +//! target-specific lowering lives in the `llvm` crate. + // CLI tables and compiler phase boundaries intentionally favor explicit data. #![allow( clippy::print_literal, diff --git a/src/link_validation/elf.rs b/src/link_validation/elf.rs index 97c8c521..f6bb74bf 100644 --- a/src/link_validation/elf.rs +++ b/src/link_validation/elf.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Minimal read-only ELF and Unix archive metadata inspection. +//! +//! Pre-link validation needs only machine and `e_flags`, so this module avoids a +//! full object-file parser while supporting direct ELF objects plus GNU and BSD +//! archive member naming. It never rewrites linker inputs. + use std::fmt; use std::fs; use std::path::{Path, PathBuf}; @@ -90,7 +96,8 @@ fn inspect_input( } else if bytes.starts_with(AR_MAGIC) { inspect_archive(path, bytes, metadata)?; } - // LLVM bitcode and linker scripts do not carry ELF e_flags. + // LLVM bitcode and linker scripts do not carry ELF e_flags. They remain + // valid linker inputs and are intentionally ignored by metadata validation. Ok(()) } diff --git a/src/link_validation/mod.rs b/src/link_validation/mod.rs index 97205d3f..31a6f3aa 100644 --- a/src/link_validation/mod.rs +++ b/src/link_validation/mod.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Target-specific validation performed before invoking the native linker. +//! +//! Metadata inspection is kept separate from linker command construction so the +//! checks can move to Whale without coupling them to the current external linker. + mod elf; mod riscv; diff --git a/src/link_validation/riscv.rs b/src/link_validation/riscv.rs index 34e7add1..b13f7c4e 100644 --- a/src/link_validation/riscv.rs +++ b/src/link_validation/riscv.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Pre-link RISC-V floating-point ABI compatibility checks. +//! +//! ELF `e_flags` distinguish LP64, LP64F, and LP64D objects. Every RISC-V member +//! discovered in direct objects or archives must agree with the effective Wave +//! target ABI; inputs for other architectures are left to the linker. + use super::elf::{inspect_link_inputs, LinkInputInspectionError}; use std::fmt; @@ -101,6 +107,8 @@ pub fn validate_riscv_link_inputs( target_abi: RiscvFloatAbi, inputs: &[String], ) -> Result<(), AbiValidationError> { + // Inspect every archive member rather than trusting the archive filename: + // one incompatible member is sufficient to make the final link invalid. for metadata in inspect_link_inputs(inputs).map_err(AbiValidationError::Inspection)? { if metadata.machine != EM_RISCV { continue; diff --git a/src/main.rs b/src/main.rs index a7bacbcf..ae53e8ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Process entry point for `wavec`. +//! +//! Argument handling lives in the library crate. This binary selects the error +//! renderer, prints usage for usage failures, and preserves the CLI error's +//! stable exit code. + use std::process; fn main() { diff --git a/src/runner.rs b/src/runner.rs index 8e41c88d..6be5e75b 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -10,6 +10,14 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Compiler-driver orchestration from source loading through native execution. +//! +//! This module owns user-facing phase boundaries and diagnostics. Frontend work +//! must finish in the order target preprocessing, parsing, import expansion, +//! semantic validation, monomorphization, and concrete-AST validation before an +//! AST reaches LLVM. Backend panics are caught here and translated into Wave +//! diagnostics; lower layers should not duplicate that presentation policy. + use crate::{DebugFlags, DepFlags, LinkFlags, LlvmFlags}; use ::error::*; use ::parser::ast::*; @@ -993,6 +1001,9 @@ fn frontend_prepare_wave_ast( println!("\n===== AST =====\n{:#?}", parsed_ast); } + // Imports are expanded before monomorphization so generic references may + // resolve across source files. The expanded AST retains source ownership + // long enough to report semantic errors against the originating file. let import_config = build_import_config(dep, target); let expanded = match expand_imports_for_codegen(file_path, &code, parsed_ast, &import_config) { Ok(a) => a, @@ -1001,6 +1012,8 @@ fn frontend_prepare_wave_ast( process::exit(1); } }; + // Validate both sides of monomorphization: templates must be semantically + // sound, and generated concrete nodes must satisfy the same language rules. validate_expanded_ast_or_exit(&expanded); let ast = match monomorphize_generics(expanded.ast) { Ok(a) => a, diff --git a/src/std.rs b/src/std.rs index ce4fb52b..d8262cf9 100644 --- a/src/std.rs +++ b/src/std.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Installation and update commands for the separately licensed Wave standard library. +//! +//! Only the repository's `std` subtree is fetched. Its manifest is validated +//! before files are copied into the per-user Wave library directory so an +//! unexpected repository layout is not installed as the standard library. + use crate::errors::CliError; use std::path::{Path, PathBuf}; use std::process::Command; diff --git a/src/version.rs b/src/version.rs index 1ae20e54..1f831d49 100644 --- a/src/version.rs +++ b/src/version.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Compiler version and host operating-system display information. +//! +//! The compiler version comes from Cargo package metadata. OS probing is used +//! only for human-readable diagnostics and falls back cleanly when platform +//! commands or release files are unavailable. + use std::process::Command; const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/utils/src/colorex.rs b/utils/src/colorex.rs index 166b7783..205acd06 100644 --- a/utils/src/colorex.rs +++ b/utils/src/colorex.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Minimal ANSI styling used by command-line diagnostics. +//! +//! All formatting honors the conventional `NO_COLOR`, `CLICOLOR`, and +//! `CLICOLOR_FORCE` environment variables. Styling methods therefore return +//! plain text when color is disabled and never make rendering a requirement. + pub struct Color(u8, u8, u8); fn colors_enabled() -> bool { diff --git a/utils/src/formatx.rs b/utils/src/formatx.rs index 90ec42c6..51eb0c83 100644 --- a/utils/src/formatx.rs +++ b/utils/src/formatx.rs @@ -10,18 +10,17 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. -// utils/formatx.rs -// -// Wave internal format utilities. -// This module replaces regex usage for placeholder detection. -// Supported pattern: `{ ... }` (non-nested, no escape) +//! Lightweight Wave format-placeholder scanning without regular expressions. +//! +//! The supported form is a non-nested `{...}` pair with no escape processing. +//! Unterminated opening braces are ignored rather than counted as placeholders. #[derive(Debug, Clone)] pub struct Placeholder { pub spec: String, } -// "{c}" -> spec="c", "{}" -> spec="" +/// Returns placeholders in source order, trimming the text inside each pair. pub fn parse_placeholders(input: &str) -> Vec { let bytes = input.as_bytes(); let mut i = 0; diff --git a/utils/src/json.rs b/utils/src/json.rs index bd7164bf..ee6b804e 100644 --- a/utils/src/json.rs +++ b/utils/src/json.rs @@ -10,6 +10,12 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Small JSON parser and writer used where a full serialization dependency is unnecessary. +//! +//! Objects preserve insertion order and duplicate keys in their representation; +//! lookup returns the first matching key. Callers that require schema guarantees +//! must validate the parsed tree explicitly. + use std::io; use std::io::Write; diff --git a/utils/src/lib.rs b/utils/src/lib.rs index 43b1cb9a..53519f5c 100644 --- a/utils/src/lib.rs +++ b/utils/src/lib.rs @@ -10,6 +10,11 @@ // SPDX-License-Identifier: MPL-2.0 // AI TRAINING NOTICE: Prohibited without prior written permission. No use for machine learning or generative AI training, fine-tuning, distillation, embedding, or dataset creation. +//! Small dependency-free utilities shared across Wave compiler crates. +//! +//! Keep this crate independent of frontend and backend types so formatting, +//! terminal color, and JSON helpers remain reusable at every compiler layer. + pub mod colorex; pub mod formatx; pub mod json;