Een compiler voor de .Brett taal
npm install brett-compilerNaam student: Brett Deswert
Vak: Programmeren 3 – 2025–2026
Dit project bevat een compiler en een VS Code Language Server Extension voor de zelf ontworpen programmeertaal Brett.
De focus ligt op:
- Diagnostics (syntax & semantiek)
- Code completion
- Een duidelijke grammatica (EBNF)
- Integratie met VS Code via LSP
---
```
Compiler/
├─ .idea/
├─ dist/
├─ node_modules/
├─ pictures/
├─ src/
├─ test/
├─ .gitignore
├─ antlr-4.13.2-complete.jar
├─ generate-compiler.js
├─ generate-compiler.ps1
├─ package.json
├─ package-lock.json
├─ README.md
└─ vite.config.js
``
EXTENSION/
├─ .vscode/
├─ client/
│ ├─ node_modules/
│ ├─ out/
│ ├─ src/
│ │ └─ test/
│ │ └─ extension.ts
│ ├─ testFixture/
│ ├─ package-lock.json
│ ├─ package.json
│ ├─ tsconfig.json
│ └─ tsconfig.tsbuildinfo
├─ scripts/
│ └─ e2e.sh
├─ server/
│ ├─ node_modules/
│ ├─ out/
│ └─ src/
│ └─ server.ts
├─ .gitignore
├─ eslint.config.mjs
├─ package-lock.json
├─ package.json
├─ tsconfig.json
├─ tsconfig.tsbuildinfo
├─ README.md
└─ tsconfig.json
---
bash
cd Compiler
npm ci --include=dev
npm run build
`Dit voert automatisch uit:
- generatie van de parser via ANTLR (
antlrci)
- build van de compiler naar Compiler/dist/De gegenereerde code wordt gebruikt door de
SemanticAnalyserVisitor.---
$3
`bash
cd Compiler
npm ci --include=dev
npm run antlrci
npm test
`---
$3
`bash
cd extension
npm install
npm run compile
`
De package.json haalt de package op via npm, en gebruikt de geuploade package.De package wordt bij elke build automatisch naar npm geupload.
Dit is een link naar de npm package: https://www.npmjs.com/package/brett-compiler
Start daarna de extension via Run Extension in VS Code.
---
Voorbeeldbroncode (alle ondersteunde syntax)
`brett
let count: number = 10;
const isActive: bool = true;
let message: string = "Hallo Brett";def add(a: number, b: number): number {
return a + b;
}
let result = add(5, 7);
if (result > 10) {
message = "Groter dan tien";
} else {
message = "Tien of kleiner";
}
while (count > 0) {
count--;
}
for (let i: number = 0; i < 5; i = i + 1) {
result = result + i;
}
do {
count++;
} while (count < 3);
switch {
case result == 0 => {
message = "Nul";
}
default => {
message = "Niet nul";
}
}
let numbers = [1, 2, 3];
let person = {
name: "Alice",
age: 30
};
try {
let value = numbers[10];
} catch (err: any) {
message = "Fout opgetreden";
} finally {
message = "Klaar";
}
`---
Diagnostics
$3
- Ontbrekende ;
- Foutieve blokstructuur
- Ongeldige expressiesWorden weergegeven als Error diagnostics.
---
$3
- Typefouten
`brett
let x: number = "tekst";
`
- Dubbele declaraties in dezelfde scope
- Ongekende functies of variabelen---
$3
- Naamgevingsconventies
`brett
let MyAge: number = 30;
`Errors en warnings werken rond verschillende semantiek (types, scope, naamgeving).
---
Code Completion
$3
- Variabelen
- Functies
- Parameters
- Types
- Keywords (let, const, def, return, if, while, …)$3
- if...else
- def-funcFuncties worden automatisch aangevuld met
().---
Grammatica (EBNF)
`ebnf
program = { statement } ;
block = "{" { statement } "}" ;statement = variableDeclaration
| functionDeclaration
| ifStatement
| whileStatement
| forStatement
| switchStatement
| returnStatement
| expressionStatement
| block
| breakStatement
| continueStatement
| doWhileStatement
| tryCatchStatement ;
variableDeclaration
= "let" IDENTIFIER [ ":" type ] [ "=" expression ] ";"
| "const" IDENTIFIER ":" type "=" expression ";" ;
functionDeclaration
= "def" IDENTIFIER "(" [ parameterList ] ")" [ ":" type ] block ;
parameterList = parameter { "," parameter } ;
parameter = IDENTIFIER [ ":" type ] ;
ifStatement = "if" "(" expression ")" block [ "else" block ] ;
whileStatement = "while" "(" expression ")" block ;
doWhileStatement = "do" block "while" "(" expression ")" ";" ;
forStatement = "for" "(" [ variableDeclaration | expressionStatement ]
[ expression ] ";" [ expression ] ")" block ;
switchStatement = "switch" "{" { switchCase } [ defaultCase ] "}" ;
switchCase = "case" expression "=>" block ;
defaultCase = "default" "=>" block ;
tryCatchStatement = "try" block "catch" "(" IDENTIFIER [ ":" type ] ")" block
[ "finally" block ] ;
returnStatement = "return" [ expression ] ";" ;
breakStatement = "break" ";" ;
continueStatement = "continue" ";" ;
expressionStatement = expression ";" ;
type = baseType { "[]" } ;
baseType = "string" | "number" | "bool" | "any" | "void" | IDENTIFIER ;
expression = assignment ;
assignment = [ IDENTIFIER "=" ] comparison ;
comparison = term { ( "==" | "!=" | "<" | "<=" | ">" | ">=" ) term } ;
term = factor { ( "+" | "-" ) factor } ;
factor = unary { ( "*" | "/" ) unary } ;
unary = ( "++" | "--" ) unary | postfix ;
postfix = primary { "++" | "--" | "[" expression "]" | "." IDENTIFIER } ;
primary = NUMBER
| STRING
| "true"
| "false"
| "nil"
| IDENTIFIER
| "(" expression ")"
| IDENTIFIER "(" [ argList ] ")"
| arrayLiteral
| objectLiteral
| "new" IDENTIFIER "(" [ argList ] ")" ;
arrayLiteral = "[" [ expression { "," expression } ] "]" ;
objectLiteral = "{" [ property { "," property } ] "}" ;
property = ( IDENTIFIER | STRING ) ":" expression ;
argList = expression { "," expression } ;
`(Volledige grammatica wordt geïmplementeerd via ANTLR.)
---
Compiler-architectuur
- Lexer + Parser: ANTLR
- Opbouw van CST
- Semantische analyse:
- symbol tables
- scope-analyse
- type checking
- Gestructureerde foutafhandeling met locatie-informatie
---
VS Code Language Server
- Zet compiler-resultaten om naar:
- Diagnostics in de editor
- Completion items
- Gebruikt
vscode-languageserver---
Testing
- Unit tests voor parser (CST)
- Tests voor syntax errors
- End-to-end tests voor semantische analyse
- End-to-end tests voor code completion data
---
Code om warnings en errors mee te testen
De volgende code moet geschreven worden in een bestand genaamd index.brett om de verschillende warnings, errors en code completions te testen.
`brett
// ===================================
// SECTION 1: SYNTAX ERRORS
// ===================================let x: number = 10;
const MyVariable: any = 5;
def calculate(a: number, b: number) {
return a + b;
}
if (true) {
let z = 5;
}
// ===================================
// SECTION 2: SEMANTIC ERRORS
// ===================================
let MyAge: number = 30; // (Warning)
let myValue: number = "hello"; // ERROR 6
def testScope() {
let localVar: number = 1;
let localVar: string = "oops"; // ERROR 7
}
def anotherFunction() {
let result = calculate(10, 20);
// 👇 FOUTEN DIE MOETEN VERSCHIJNEN
let total = sum(1, 2); // Function 'sum' is not found.
total = unknown + 1; // Variable 'unknown' is niet gevonden in deze scope.
}
``---
- error diagnostics
!error diagnostics
- warning diagnostics
!warning diagnostics
- completion popup in VS Code
!code completion popup 2
!code completion popup 1
!code completion popup 3
---