Raven is a modern programming language and experimental compiler inspired by the .NET Roslyn architecture.
✨ Key traits:
- Familiar yet fresh syntax — looks like Swift, with ideas borrowed from Rust, F#, and C#
- Targets the .NET runtime — compiles directly to IL and integrates with the .NET ecosystem
- Immutable, service-oriented design — a compiler built as an API, following the "Compiler-as-a-Service" philosophy
Raven is primarily a learning and exploration project, aimed at:
- Understanding modern compiler construction
- Experimenting with language design
- Providing a clean API for syntax manipulation and analysis
Raven is a general-purpose, expression-oriented language with an expression-first design that blends functional and imperative paradigms. Its type system supports union and literal types with flow-sensitive typing similar to TypeScript, and it uses unit instead of void. As a .NET language, Raven interops seamlessly with C#, even shipping a C# analyzer for type unions. The compiler follows the Roslyn "compiler-as-a-service" architecture.
import System.Console.*
import System.Collections.Generic.List<int>
import System.Linq.*
alias LedgerEntry = (label: string, value: int)
func shape(values: List<int>) -> List<LedgerEntry> {
val result = List<LedgerEntry>()
for each value in values {
val label = if value < 0 "debit" else "credit"
result.Add((label: label, value: value))
}
return result
}
func summarize(readings: List<int>) -> string {
val shaped = shape(readings)
val total = shaped.Aggregate(0, (acc, entry) => acc + entry.value)
val verdict = if total > 0
"net positive"
else if total < 0
"net negative"
else
"balanced"
return $"processed ${shaped.Count()} items -> ${verdict} (${total})"
}
var ledger = List<int>()
ledger.Add(25)
ledger.Add(-10)
ledger.Add(5)
ledger.Add(0)
WriteLine(summarize(ledger))
Highlights:
- Expression-first control flow and file-scope functions
valvsvar(immutable vs mutable) with tuple-shaped data- Lambdas and LINQ interop against .NET collection types
- String interpolation with tuple element access
- Direct interop with .NET libraries
Read the full Introduction for a more detailed overview.
Ravens are remarkable birds, known for their intelligence and adaptability.
In Old Norse mythology, ravens held significant importance as messengers of Odin. His two ravens, Huginn ("thought") and Muninn ("memory/mind"), symbolized intellect and reflection—qualities that align with the goals of this language.
The name reflects both the mythological roots and the clever traits of these birds.
Alternative names considered: Old Norse "Hrafn" or Danish "Ravn."
- Create a Programming Language — build a language from the ground up, covering design and implementation.
- Focus on Parsing & Semantics — implement parsing, binding, and analysis as the backbone of compilation.
- Serve as a Reference — provide a well-documented example for compiler enthusiasts.
- Pragmatic Scope — aim for a practical subset of Roslyn-like features, not full parity.
See the pseudo-specification here.
More samples.
- Compiler API reference: docs/compiler/api
- Example usage: Raven.Compiler project
- .NET SDK 9.0
- Optional: DocFX for docs
# Restore packages
dotnet restore
# Generate syntax nodes (run from the Syntax directory)
cd src/Raven.CodeAnalysis/Syntax
dotnet run --project ../../../tools/NodeGenerator # add `-- -f` to force regeneration
cd ../../..
# Build the compiler, tests, and Raven.Core (the Option/Result standard library built with ravc)
dotnet build Raven.sln
dotnet testCommand:
dotnet run --project src/Raven.Compiler -- <path-to-file> -o <output-file-path>Options:
--framework <tfm>– target framework--refs <path>– additional metadata reference (repeatable)--raven-core <path>– reference a specificRaven.Core.dll--emit-core-types-only– embed Raven core shims instead of usingRaven.Core.dll-o <path>– output assembly path-s– display the syntax tree (single file only)-d [plain|pretty[:no-diagnostics]]– dump syntax (plainfor raw text,prettyfor highlighted syntax; append:no-diagnosticsto skip underlines, single file only)--highlight– display diagnostics with highlighted source snippets and severity-coloured underlines (covers compiler, analyzer, and emit diagnostics)-r– print the raw source (single file only)-b– print the binder tree (single file only)-bt– print the binder and bound tree (single file only)--symbols [list|hierarchy]– inspect source symbols (listdumps properties,hierarchyprints the tree)-h,--help– show help
ravc now ships with and references Raven.Core.dll by default. The library is copied next to ravc during build, and any compilation also copies it to the output directory of the produced assembly. Use --raven-core to point to a different build of Raven.Core, or --emit-core-types-only to embed the shimmed core types instead of referencing the DLL.
Creating a .debug/ directory in the current or parent folder causes the
compiler to emit per-file dumps (syntax tree, highlighted syntax, raw source,
bound tree, and binder tree) into that directory. The debug options above will additionally
write to the console when compiling a single file.
⚠️ When the arguments are omitted, there is a hardcoded input file, and a hardcoded output file path (test.dll).
dotnet run --project src/Raven.Editor -- <path-to-file>When a file path is supplied, the editor opens the file and displays its name in the window title.
src/
Raven.CodeAnalysis/ # Compiler core: syntax, binder, semantic model, code gen
Raven.Compiler/ # Command-line compiler
Raven.CodeAnalysis.Testing/ # Diagnostic test helpers
TypeUnionAnalyzer/ # Analyzer for C# type unions
TestDep/ # Auxiliary test project
test/ # Unit tests
samples/ # Example Raven programs and CLI demos
tools/
NodeGenerator/ # Generates syntax node code from Model.xml
Generator/ # Shared Roslyn generator framework
docs/ # Language spec & design docs
- The
RunNodeGeneratortarget inRaven.CodeAnalysis.csprojruns automatically, but if generated files are missing, run the command manually. - Generated files reside in
Syntax/generated/andSyntax/InternalSyntax/generated/— do not edit by hand. - Always run
dotnet buildanddotnet testbefore committing.
Contributions are welcome! See CONTRIBUTING.md for coding standards, git conventions, and workflow.
- Full documentation: docs/
- Unit tests for the language: Raven.CodeAnalysis.Tests
💡 Raven is a playground for exploring compilers and language design — your ideas and contributions can directly shape its evolution!