brett-compiler 1.0.20 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ "use strict";require("antlr4");const e=require("./generated/BrettLexer.js");module.exports=e.BrettLexer;
@@ -0,0 +1 @@
1
+ "use strict";require("antlr4");const e=require("./generated/BrettListener.js");module.exports=e.BrettListener;
@@ -0,0 +1 @@
1
+ "use strict";require("antlr4");require("./generated/BrettListener.js");require("./generated/BrettVisitor.js");const e=require("./generated/BrettParser.js");module.exports=e.BrettParser;
@@ -0,0 +1 @@
1
+ "use strict";require("antlr4");const e=require("./generated/BrettVisitor.js");module.exports=e.BrettVisitor;
@@ -1,191 +1 @@
1
- const BrettVisitor = require('./generated/BrettVisitor').default;
2
- const { SymbolKind } = require('./model.js');
3
- const { SymbolTable } = require('./SymbolTable.js');
4
-
5
- const parserModule = require('./generated/BrettParser');
6
- const BrettParser = parserModule.BrettParser || parserModule.default || parserModule;
7
-
8
- class SemanticAnalyzerVisitor extends BrettVisitor {
9
- constructor() {
10
- super();
11
- this.errors = [];
12
- this.currentScope = new SymbolTable();
13
- this.allScopes = [];
14
- }
15
-
16
- addError(message, token, severity = 'error') {
17
- const line = token ? token.line : 0;
18
- const column = token ? token.column + 1 : 0;
19
- const length = token ? token.text.length : 1;
20
-
21
- this.errors.push({
22
- message,
23
- line,
24
- column,
25
- type: severity === 'error' ? 'Semantic Error' : 'Warning',
26
- length
27
- });
28
- }
29
-
30
- checkAssignment(declaredType, actualType, token) {
31
- // If either side is 'any', we assume it's valid (or already an error)
32
- if (declaredType === 'any' || actualType === 'any') {
33
- return true;
34
- }
35
-
36
- // Strict string comparison
37
- if (String(declaredType) !== String(actualType)) {
38
- this.addError(
39
- `Type '${actualType}' kan niet worden toegewezen aan type '${declaredType}'`,
40
- token
41
- );
42
- return false;
43
- }
44
- return true;
45
- }
46
-
47
- getSymbols() {
48
- const allSymbols = new Map();
49
- this.allScopes.forEach(scope => {
50
- if (scope.symbols) {
51
- for (const [name, symbol] of scope.symbols.entries()) {
52
- if (!allSymbols.has(name)) allSymbols.set(name, symbol);
53
- }
54
- }
55
- });
56
- ['string', 'number', 'bool', 'any'].forEach(t =>
57
- allSymbols.set(t, { name: t, kind: 'Type', type: 'type' })
58
- );
59
- return Array.from(allSymbols.values());
60
- }
61
-
62
- visitProgram(ctx) { this.visitChildren(ctx); }
63
-
64
- visitBlock(ctx) {
65
- this.currentScope = new SymbolTable(this.currentScope);
66
- this.visitChildren(ctx);
67
- this.allScopes.push(this.currentScope);
68
- this.currentScope = this.currentScope.parent;
69
- }
70
-
71
- visitFunctionDeclaration(ctx) {
72
- const identifierNode = ctx.IDENTIFIER();
73
- if (!identifierNode) return;
74
-
75
- const name = identifierNode.getText();
76
- const returnType = ctx.type()?.getText() ?? 'any';
77
-
78
- if (!this.currentScope.define({ name, kind: SymbolKind.Function, type: returnType })) {
79
- this.addError(`Functie '${name}' is al gedefinieerd.`, identifierNode.getSymbol());
80
- }
81
-
82
- this.currentScope = new SymbolTable(this.currentScope);
83
- if (ctx.parameterList()) this.visit(ctx.parameterList());
84
- if (ctx.block()) this.visit(ctx.block());
85
- this.currentScope = this.currentScope.parent;
86
- }
87
-
88
- visitParameter(ctx) {
89
- const identifierNode = ctx.IDENTIFIER();
90
- if (!identifierNode) return;
91
- const name = identifierNode.getText();
92
- const type = ctx.type()?.getText() ?? 'any';
93
- this.currentScope.define({ name, kind: SymbolKind.Parameter, type });
94
- }
95
-
96
- visitVariableDeclaration(ctx) {
97
- const identifierNode = ctx.IDENTIFIER();
98
- if (!identifierNode) return;
99
-
100
- const name = identifierNode.getText();
101
- const declaredType = ctx.type()?.getText() ?? 'any';
102
- const identifierToken = identifierNode.getSymbol();
103
-
104
- if (!/^[a-z]/.test(name)) {
105
- this.addError(`Variabele '${name}' moet met kleine letter beginnen.`, identifierToken, 'warning');
106
- }
107
-
108
- if (!this.currentScope.define({ name, kind: SymbolKind.Variable, type: declaredType })) {
109
- this.addError(`Variabele '${name}' is al gedefinieerd.`, identifierToken);
110
- }
111
-
112
- if (ctx.expression()) {
113
- const exprType = this.visit(ctx.expression());
114
- this.checkAssignment(declaredType, exprType, ctx.expression().start);
115
- }
116
- }
117
-
118
- // ================= EXPRESSION VISITORS =================
119
-
120
- visitAssignmentExpression(ctx) {
121
- const name = ctx.IDENTIFIER().getText();
122
- const symbol = this.currentScope.resolve(name);
123
- const token = ctx.IDENTIFIER().getSymbol();
124
-
125
- if (!symbol) {
126
- this.addError(`Variabele '${name}' is niet gevonden in deze scope.`, token);
127
- } else if (symbol.kind !== SymbolKind.Variable && symbol.kind !== SymbolKind.Parameter) {
128
- this.addError(`'${name}' is geen variabele.`, token);
129
- }
130
-
131
- const valType = this.visit(ctx.expression());
132
-
133
- if (symbol) {
134
- this.checkAssignment(symbol.type, valType, ctx.expression().start);
135
- }
136
- return valType;
137
- }
138
-
139
- visitBinaryExpression(ctx) {
140
- const leftType = this.visit(ctx.expression(0));
141
- const rightType = this.visit(ctx.expression(1));
142
- const operator = ctx.op.text;
143
-
144
- if (leftType === 'number' && rightType === 'number') {
145
- if (['<', '>', '<=', '>=', '==', '!='].includes(operator)) return 'bool';
146
- return 'number';
147
- }
148
-
149
- if (operator === '+' && (leftType === 'string' || rightType === 'string')) {
150
- return 'string';
151
- }
152
- return 'any';
153
- }
154
-
155
- visitIdentifierExpression(ctx) {
156
- const name = ctx.IDENTIFIER().getText();
157
- const symbol = this.currentScope.resolve(name);
158
-
159
- if (!symbol) {
160
- this.addError(`Variabele '${name}' is niet gevonden in deze scope.`, ctx.IDENTIFIER().getSymbol());
161
- // Important: Return 'any' so checkAssignment logic above ignores it
162
- return 'any';
163
- }
164
- return symbol.type;
165
- }
166
-
167
- visitFunctionCallExpression(ctx) {
168
- const name = ctx.IDENTIFIER().getText();
169
- const symbol = this.currentScope.resolve(name);
170
-
171
- if (!symbol || symbol.kind !== SymbolKind.Function) {
172
- this.addError(`Functie '${name}' is niet gedefinieerd.`, ctx.IDENTIFIER().getSymbol());
173
- return 'any';
174
- }
175
- if (ctx.argList()) this.visit(ctx.argList());
176
- return symbol.type;
177
- }
178
-
179
- visitLiteralExpression(ctx) {
180
- if (ctx.NUMBER()) return 'number';
181
- if (ctx.STRING()) return 'string';
182
- if (ctx.getText() === 'true' || ctx.getText() === 'false') return 'bool';
183
- return 'any';
184
- }
185
-
186
- visitParenthesizedExpression(ctx) {
187
- return this.visit(ctx.expression());
188
- }
189
- }
190
-
191
- module.exports = { SemanticAnalyzerVisitor };
1
+ "use strict";const l=require("./generated/BrettVisitor").default,{SymbolKind:s}=require("./model.js"),{SymbolTable:a}=require("./SymbolTable.js"),c=require("./generated/BrettParser");c.BrettParser||c.default;class u extends l{constructor(){super(),this.errors=[],this.currentScope=new a,this.allScopes=[]}addError(e,r,t="error"){const i=r?r.line:0,n=r?r.column+1:0,o=r?r.text.length:1;this.errors.push({message:e,line:i,column:n,type:t==="error"?"Semantic Error":"Warning",length:o})}checkAssignment(e,r,t){return e==="any"||r==="any"?!0:String(e)!==String(r)?(this.addError(`Type '${r}' kan niet worden toegewezen aan type '${e}'`,t),!1):!0}getSymbols(){const e=new Map;return this.allScopes.forEach(r=>{if(r.symbols)for(const[t,i]of r.symbols.entries())e.has(t)||e.set(t,i)}),["string","number","bool","any"].forEach(r=>e.set(r,{name:r,kind:"Type",type:"type"})),Array.from(e.values())}visitProgram(e){this.visitChildren(e)}visitBlock(e){this.currentScope=new a(this.currentScope),this.visitChildren(e),this.allScopes.push(this.currentScope),this.currentScope=this.currentScope.parent}visitFunctionDeclaration(e){const r=e.IDENTIFIER();if(!r)return;const t=r.getText(),i=e.type()?.getText()??"any";this.currentScope.define({name:t,kind:s.Function,type:i})||this.addError(`Functie '${t}' is al gedefinieerd.`,r.getSymbol()),this.currentScope=new a(this.currentScope),e.parameterList()&&this.visit(e.parameterList()),e.block()&&this.visit(e.block()),this.currentScope=this.currentScope.parent}visitParameter(e){const r=e.IDENTIFIER();if(!r)return;const t=r.getText(),i=e.type()?.getText()??"any";this.currentScope.define({name:t,kind:s.Parameter,type:i})}visitVariableDeclaration(e){const r=e.IDENTIFIER();if(!r)return;const t=r.getText(),i=e.type()?.getText()??"any",n=r.getSymbol();if(/^[a-z]/.test(t)||this.addError(`Variabele '${t}' moet met kleine letter beginnen.`,n,"warning"),this.currentScope.define({name:t,kind:s.Variable,type:i})||this.addError(`Variabele '${t}' is al gedefinieerd.`,n),e.expression()){const o=this.visit(e.expression());this.checkAssignment(i,o,e.expression().start)}}visitAssignmentExpression(e){const r=e.IDENTIFIER().getText(),t=this.currentScope.resolve(r),i=e.IDENTIFIER().getSymbol();t?t.kind!==s.Variable&&t.kind!==s.Parameter&&this.addError(`'${r}' is geen variabele.`,i):this.addError(`Variabele '${r}' is niet gevonden in deze scope.`,i);const n=this.visit(e.expression());return t&&this.checkAssignment(t.type,n,e.expression().start),n}visitBinaryExpression(e){const r=this.visit(e.expression(0)),t=this.visit(e.expression(1)),i=e.op.text;return r==="number"&&t==="number"?["<",">","<=",">=","==","!="].includes(i)?"bool":"number":i==="+"&&(r==="string"||t==="string")?"string":"any"}visitIdentifierExpression(e){const r=e.IDENTIFIER().getText(),t=this.currentScope.resolve(r);return t?t.type:(this.addError(`Variabele '${r}' is niet gevonden in deze scope.`,e.IDENTIFIER().getSymbol()),"any")}visitFunctionCallExpression(e){const r=e.IDENTIFIER().getText(),t=this.currentScope.resolve(r);return!t||t.kind!==s.Function?(this.addError(`Functie '${r}' is niet gedefinieerd.`,e.IDENTIFIER().getSymbol()),"any"):(e.argList()&&this.visit(e.argList()),t.type)}visitLiteralExpression(e){return e.NUMBER()?"number":e.STRING()?"string":e.getText()==="true"||e.getText()==="false"?"bool":"any"}visitParenthesizedExpression(e){return this.visit(e.expression())}}module.exports={SemanticAnalyzerVisitor:u};
@@ -1,28 +1 @@
1
- const { SymbolKind } = require('./model.js');
2
-
3
- class SymbolTable {
4
- constructor(parent = null) {
5
- this.symbols = new Map();
6
- this.parent = parent;
7
- }
8
-
9
- define(symbol) {
10
- if (this.symbols.has(symbol.name)) return false;
11
- this.symbols.set(symbol.name, symbol);
12
- return true;
13
- }
14
-
15
- resolve(name) {
16
- const s = this.symbols.get(name);
17
- if (s) return s;
18
- // Cruciaal: De recursieve lookup in ouderlijke scopes
19
- if (this.parent) return this.parent.resolve(name);
20
- return null; // Triggert Fout 8 en 9 in de Visitor
21
- }
22
- }
23
-
24
- module.exports = { SymbolTable };
25
-
26
- /*
27
- Another configuration change
28
- */
1
+ "use strict";const{SymbolKind:n}=require("./model.js");class t{constructor(s=null){this.symbols=new Map,this.parent=s}define(s){return this.symbols.has(s.name)?!1:(this.symbols.set(s.name,s),!0)}resolve(s){const e=this.symbols.get(s);return e||(this.parent?this.parent.resolve(s):null)}}module.exports={SymbolTable:t};
@@ -1,24 +1 @@
1
- class SyntaxErrorListener {
2
- constructor(errorsList) {
3
- this.errors = errorsList;
4
- }
5
-
6
- syntaxError(recognizer, offendingSymbol, line, column, msg, e) {
7
- const length = offendingSymbol ? offendingSymbol.text.length : 1;
8
-
9
- this.errors.push({
10
- type: 'Syntax Error',
11
- message: msg,
12
- line: line,
13
- column: column + 1, // 1-based for the user
14
- length: length // NEW: Store the token length
15
- });
16
- }
17
-
18
- // Deze lege methodes zijn nodig om als listener te werken
19
- reportAmbiguity() {}
20
- reportAttemptingFullContext() {}
21
- reportContextSensitivity() {}
22
- }
23
-
24
- module.exports = { SyntaxErrorListener };
1
+ "use strict";class i{constructor(t){this.errors=t}syntaxError(t,r,e,s,n,l){const o=r?r.text.length:1;this.errors.push({type:"Syntax Error",message:n,line:e,column:s+1,length:o})}reportAmbiguity(){}reportAttemptingFullContext(){}reportContextSensitivity(){}}module.exports={SyntaxErrorListener:i};
package/dist/index.js CHANGED
@@ -1,58 +1 @@
1
- const antlr4 = require('antlr4');
2
-
3
- const lexerModule = require('./generated/BrettLexer');
4
- const parserModule = require('./generated/BrettParser');
5
-
6
- const BrettLexer = lexerModule.BrettLexer || lexerModule.default || lexerModule;
7
- const BrettParser = parserModule.BrettParser || parserModule.default || parserModule;
8
-
9
- const { SemanticAnalyzerVisitor } = require('./SemanticAnalyserVisitor');
10
- const { SyntaxErrorListener } = require('./SyntaxErrorListener');
11
-
12
- function compile(input) {
13
- const chars = new antlr4.InputStream(input);
14
- const lexer = new BrettLexer(chars);
15
- const tokens = new antlr4.CommonTokenStream(lexer);
16
- const parser = new BrettParser(tokens);
17
-
18
- const errors = [];
19
- parser.removeErrorListeners();
20
- parser.addErrorListener(new SyntaxErrorListener(errors));
21
-
22
- const tree = parser.program();
23
-
24
- const visitor = new SemanticAnalyzerVisitor();
25
-
26
- try {
27
- visitor.visit(tree);
28
- } catch (e) {
29
- }
30
-
31
- const allErrors = errors.concat(visitor.errors);
32
-
33
- return allErrors;
34
- }
35
-
36
- function analyzeAndGetSymbols(input) {
37
- const chars = new antlr4.InputStream(input);
38
- const lexer = new BrettLexer(chars);
39
- const tokens = new antlr4.CommonTokenStream(lexer);
40
- const parser = new BrettParser(tokens);
41
-
42
- parser.removeErrorListeners();
43
-
44
- const tree = parser.program();
45
- const visitor = new SemanticAnalyzerVisitor();
46
-
47
- try {
48
- visitor.visit(tree);
49
- } catch (e) {
50
- console.error("Symbol analysis failed due to syntax error");
51
- }
52
-
53
- return visitor.getSymbols();
54
- }
55
-
56
- module.exports = { compile, analyzeAndGetSymbols };
57
-
58
- // Experiment to see if the new version is released in the right way.
1
+ "use strict";const n=require("antlr4"),l=require("./generated/BrettLexer"),m=require("./generated/BrettParser"),u=l.BrettLexer||l.default||l,w=m.BrettParser||m.default||m,{SemanticAnalyzerVisitor:y}=require("./SemanticAnalyserVisitor"),{SyntaxErrorListener:d}=require("./SyntaxErrorListener");function p(o){const s=new n.InputStream(o),c=new u(s),a=new n.CommonTokenStream(c),r=new w(a),e=[];r.removeErrorListeners(),r.addErrorListener(new d(e));const t=r.program(),i=new y;try{i.visit(t)}catch{}return e.concat(i.errors)}function S(o){const s=new n.InputStream(o),c=new u(s),a=new n.CommonTokenStream(c),r=new w(a);r.removeErrorListeners();const e=r.program(),t=new y;try{t.visit(e)}catch{console.error("Symbol analysis failed due to syntax error")}return t.getSymbols()}module.exports={compile:p,analyzeAndGetSymbols:S};
package/dist/model.js CHANGED
@@ -1,7 +1 @@
1
- const SymbolKind = Object.freeze({
2
- Variable: 5,
3
- Parameter: 6,
4
- Function: 3
5
- });
6
-
7
- module.exports = { SymbolKind };
1
+ "use strict";const e=Object.freeze({Variable:5,Parameter:6,Function:3});module.exports={SymbolKind:e};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brett-compiler",
3
- "version": "1.0.20",
3
+ "version": "1.0.23",
4
4
  "description": "Een compiler voor de .Brett taal",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,19 +8,27 @@
8
8
  "dist"
9
9
  ],
10
10
  "dependencies": {
11
- "antlr4": "^4.13.1"
11
+ "antlr4": "^4.13.1",
12
+ "vite": "^7.3.0"
12
13
  },
13
14
  "scripts": {
14
15
  "antlr": "powershell -ExecutionPolicy Bypass -File generate-compiler.ps1",
15
16
  "antlrci": "node generate-compiler.js",
16
17
  "start": "node dist/index.js",
17
18
  "test": "vitest",
18
- "build": "npm run antlrci && node build.js",
19
+ "build": "npm run antlrci && vite build",
19
20
  "prepublishOnly": "npm run build",
20
- "release": "semantic-release"
21
+ "release": "semantic-release",
22
+ "lint": "eslint . --ext .js,.ts,.d.ts"
21
23
  },
22
24
  "devDependencies": {
23
- "vitest": "^4.0.10",
24
- "standard-version": "^9.5.0"
25
+ "@eslint/js": "^9.39.2",
26
+ "@typescript-eslint/parser": "^8.50.0",
27
+ "eslint": "^9.39.2",
28
+ "javascript-obfuscator": "^5.1.0",
29
+ "rollup-plugin-copy": "^3.5.0",
30
+ "rollup-plugin-javascript-obfuscator": "^1.0.4",
31
+ "standard-version": "^9.5.0",
32
+ "vitest": "^4.0.10"
25
33
  }
26
34
  }
package/dist/index.d.ts DELETED
@@ -1,18 +0,0 @@
1
- 
2
- interface BrettSymbol {
3
- name: string;
4
- kind: 'Variable' | 'Function' | 'Type' | 'Parameter';
5
- type: string;
6
- }
7
-
8
- declare function compile(input: string): {
9
- type: string;
10
- message: string;
11
- line: number;
12
- column: number;
13
- length: number;
14
- }[];
15
-
16
- declare function analyzeAndGetSymbols(input: string): BrettSymbol[];
17
-
18
- export { compile, analyzeAndGetSymbols, BrettSymbol };