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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions front/error/src/error.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
5 changes: 5 additions & 0 deletions front/error/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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::*;
6 changes: 6 additions & 0 deletions front/lexer/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
5 changes: 5 additions & 0 deletions front/lexer/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
6 changes: 6 additions & 0 deletions front/lexer/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
6 changes: 6 additions & 0 deletions front/lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]

Expand Down
5 changes: 5 additions & 0 deletions front/lexer/src/literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
7 changes: 7 additions & 0 deletions front/lexer/src/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Token, WaveError> {
loop {
self.skip_trivia()?;
Expand Down
6 changes: 6 additions & 0 deletions front/lexer/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
6 changes: 6 additions & 0 deletions front/lexer/src/trivia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions front/parser/src/arch/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions front/parser/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions front/parser/src/arch/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions front/parser/src/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 7 additions & 0 deletions front/parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
5 changes: 5 additions & 0 deletions front/parser/src/expr/assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions front/parser/src/expr/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions front/parser/src/expr/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions front/parser/src/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions front/parser/src/expr/postfix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions front/parser/src/expr/primary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions front/parser/src/expr/unary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions front/parser/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<FormatPart> {
Expand Down
25 changes: 25 additions & 0 deletions front/parser/src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<String, FunctionNode>,
function_parameters: HashMap<String, Vec<ParameterNode>>,
struct_templates: HashMap<String, StructNode>,
Expand All @@ -31,9 +39,17 @@ struct GenericEnv {
struct_in_progress: HashSet<String>,
}

/// 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<ASTNode>) -> Result<Vec<ASTNode>, 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) => {
Expand Down Expand Up @@ -74,6 +90,8 @@ pub fn monomorphize_generics(ast: Vec<ASTNode>) -> Result<Vec<ASTNode>, String>
let mut out: Vec<ASTNode> = Vec::new();
let empty_subst: HashMap<String, WaveType> = 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) => {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -827,6 +849,9 @@ fn parse_wave_type_from_str(raw: &str) -> Result<WaveType, String> {
}

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");
Expand Down
7 changes: 7 additions & 0 deletions front/parser/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
6 changes: 6 additions & 0 deletions front/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
6 changes: 6 additions & 0 deletions front/parser/src/parser/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading
Loading