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
48 changes: 48 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Shared editor settings. Language formatters remain authoritative for syntax.
# Modern K&R:
# - Opening braces stay on the same line.
# - Block bodies stay expanded and readable.
# - Keep exactly one blank line between function and method definitions.

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
tab_width = 4
trim_trailing_whitespace = true

# Soft guide only. Language formatters remain responsible for wrapping.
max_line_length = 100

[*.rs]
# Rust source layout.
indent_style = space
indent_size = 4
tab_width = 4

# Keep function/method definitions visually separated by one blank line.
blank_lines_around_function = 1
blank_lines_around_method = 1

[*.{yml,yaml,json}]
indent_size = 2

[*.md]
# Preserve Markdown's two-space hard line breaks.
trim_trailing_whitespace = false

[{Makefile,makefile,GNUmakefile,*.mk}]
indent_style = tab
indent_size = tab

[tests/fixtures/**]
# Fixture bytes may deliberately exercise whitespace and missing final newlines.
trim_trailing_whitespace = false
insert_final_newline = false
charset = unset
end_of_line = unset
max_line_length = off
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
*.wave linguist-language=Wave
tests/** linguist-detectable=false
# Match rustfmt's Unix newline style even with core.autocrlf enabled on Windows.
*.rs text eol=lf
# AST snapshots assert UTF-8 byte offsets, independently of checkout defaults.
tests/fixtures/ast/* text eol=lf
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,30 @@ cmake-build-debug/
cmake-build-release/

.DS_Store

# AI assistant instructions, configuration, and local state (at any depth)
AGENTS.md
AGENTS.override.md
CLAUDE.md
CLAUDE.local.md
GEMINI.md
.codex
.agents
.claude
.cursor
.cursorrules
.cursorignore
.windsurf
.windsurfrules
.continue
.clinerules
.roo
.roomodes
.aider.conf.yml
.aiderignore
.aider.chat.history.md
.aider.input.history
.github/copilot-instructions.md
.github/instructions/
.github/prompts/
.github/agents/
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<div align="center">
<a href="https://wave-lang.dev/">
<img src="https://wave-lang.dev/img/wave-logo.ico" width="128" alt="Wave programming language logo">
<img src="https://wave-lang.dev/img/wave.svg" width="128" alt="Wave programming language logo">
</a>

<h1>Wave</h1>
---

<p><strong>A general-purpose programming language built as a modern evolution of C.</strong></p>
<p>Native compilation and direct control, rebuilt for modern software and tooling.</p>
Expand Down Expand Up @@ -97,14 +97,13 @@ which controls the C ABI boundary. `main` is always a private entry point, so
Linux and macOS:

```shell
curl -fsSL https://wave-lang.dev/install.sh | bash -s -- latest
curl -fsSL https://wave-lang.dev/install.sh | bash
```

Windows PowerShell:

```powershell
irm https://wave-lang.dev/install.ps1 -OutFile install.ps1
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Latest
irm https://wave-lang.dev/install.ps1 -OutFile install.ps1; powershell -ExecutionPolicy Bypass -File .\install.ps1
```

See the [installation guide](https://wave-lang.dev/docs/getting-started/install) for platform requirements and release selection.
Expand Down
10 changes: 3 additions & 7 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ use std::{env, path::Path, process::Command};

fn git(args: &[&str]) -> Option<String> {
let result = Command::new("git").args(args).output().ok()?;
result
.status
.success()
.then(|| String::from_utf8_lossy(&result.stdout).trim().to_owned())
result.status.success().then(|| String::from_utf8_lossy(&result.stdout).trim().to_owned())
}

fn main() {
println!("cargo:rerun-if-env-changed=WAVE_STD_REVISION");
// Track both detached HEAD and branch ref changes, including worktrees.
Expand All @@ -32,9 +30,7 @@ fn main() {
// Do not accidentally record an enclosing, unrelated repository.
let root = git(&["rev-parse", "--show-toplevel"])?;
if Path::new(&root).canonicalize().ok()?
!= Path::new(&env::var("CARGO_MANIFEST_DIR").ok()?)
.canonicalize()
.ok()?
!= Path::new(&env::var("CARGO_MANIFEST_DIR").ok()?).canonicalize().ok()?
{
return None;
}
Expand Down
70 changes: 17 additions & 53 deletions front/error/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,8 @@ impl WaveError {
("help", Value::optional_string(self.help.as_deref())),
("suggestions", Value::strings(&self.suggestions)),
]);
wson::dumps(
&Value::object([("error", error)]),
wson::Format::Json,
false,
)
.expect("diagnostic schema contains only shallow JSON values")
wson::dumps(&Value::object([("error", error)]), wson::Format::Json, false)
.expect("diagnostic schema contains only shallow JSON values")
}

pub fn display_auto(&self) {
Expand All @@ -305,10 +301,7 @@ impl WaveError {
pub fn stdlib_requires_vex(module: &str, file: &str, line: usize, column: usize) -> Self {
Self::new(
WaveErrorKind::VexIntegrationRequired(module.to_string()),
format!(
"standard library module 'std::{}' requires Vex package manager",
module
),
format!("standard library module 'std::{}' requires Vex package manager", module),
file,
line,
column,
Expand All @@ -334,10 +327,7 @@ impl WaveError {
expected: expected.to_string(),
found: found.to_string(),
},
format!(
"mismatched types: expected `{}`, found `{}`",
expected, found
),
format!("mismatched types: expected `{}`, found `{}`", expected, found),
file,
line,
column,
Expand Down Expand Up @@ -380,10 +370,8 @@ impl WaveError {

if let Some(source_code) = &self.source_code {
// `lines()` drops the empty line containing EOF after a final newline.
let lines: Vec<&str> = crate::span::source_lines(source_code)
.into_iter()
.map(|(_, line)| line)
.collect();
let lines: Vec<&str> =
crate::span::source_lines(source_code).into_iter().map(|(_, line)| line).collect();
if line <= lines.len() {
let idx = line - 1;
let start = idx.saturating_sub(1);
Expand All @@ -395,23 +383,16 @@ impl WaveError {
utils::display_width::diagnostic_line(source_line, col, self.span_len);
let ln = i + 1;
let ln_str = format!("{:>width$}", ln, width = width);
eprintln!(
" {} {} {}",
ln_str.color("38,139,235").bold(),
pipe,
rendered.text
);
eprintln!(" {} {} {}", ln_str.color("38,139,235").bold(), pipe, rendered.text);
if ln == line {
let pad = " ".repeat(width);
let spaces = " ".repeat(rendered.caret_offset);
let marks = "^"
.repeat(rendered.caret_width)
.color(self.severity_color())
.bold();
let marks =
"^".repeat(rendered.caret_width).color(self.severity_color()).bold();
match &self.label {
Some(label) => {
eprintln!(" {} {} {}{} {}", pad, pipe, spaces, marks, label.dim())
}
},
None => eprintln!(" {} {} {}{}", pad, pipe, spaces, marks),
}
}
Expand All @@ -424,19 +405,11 @@ impl WaveError {
let rendered = utils::display_width::diagnostic_line(source_line, col, self.span_len);
let width = line.to_string().len().max(2);
let ln_str = format!("{:>width$}", line, width = width);
eprintln!(
" {} {} {}",
ln_str.color("38,139,235").bold(),
pipe,
rendered.text
);
eprintln!(" {} {} {}", ln_str.color("38,139,235").bold(), pipe, rendered.text);

let pad = " ".repeat(width);
let spaces = " ".repeat(rendered.caret_offset);
let marks = "^"
.repeat(rendered.caret_width)
.color(self.severity_color())
.bold();
let marks = "^".repeat(rendered.caret_width).color(self.severity_color()).bold();
match &self.label {
Some(label) => eprintln!(" {} {} {}{} {}", pad, pipe, spaces, marks, label.dim()),
None => eprintln!(" {} {} {}{}", pad, pipe, spaces, marks),
Expand All @@ -458,12 +431,7 @@ impl WaveError {
let code = self
.code
.as_ref()
.map(|c| {
format!("[{}]", c)
.color(self.severity_color())
.bold()
.to_string()
})
.map(|c| format!("[{}]", c).color(self.severity_color()).bold().to_string())
.unwrap_or_default();

if code.is_empty() {
Expand Down Expand Up @@ -585,14 +553,10 @@ impl WaveError {
}

if errors.len() > 1 {
let error_count = errors
.iter()
.filter(|e| matches!(e.severity, ErrorSeverity::Error))
.count();
let warning_count = errors
.iter()
.filter(|e| matches!(e.severity, ErrorSeverity::Warning))
.count();
let error_count =
errors.iter().filter(|e| matches!(e.severity, ErrorSeverity::Error)).count();
let warning_count =
errors.iter().filter(|e| matches!(e.severity, ErrorSeverity::Warning)).count();

eprintln!();
if error_count > 0 {
Expand Down
7 changes: 1 addition & 6 deletions front/error/src/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,7 @@ impl SourceSpan {
if self.file != last.file {
return self.clone();
}
Self {
end: last.end,
end_line: last.end_line,
end_column: last.end_column,
..self.clone()
}
Self { end: last.end, end_line: last.end_line, end_column: last.end_column, ..self.clone() }
}

pub fn generated(mut self, reason: impl Into<String>) -> Self {
Expand Down
Loading
Loading